// Copyright 2015 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#ifndef COBALT_STORAGE_STORAGE_MANAGER_H_
#define COBALT_STORAGE_STORAGE_MANAGER_H_

#include <vector>

#include "base/callback.h"
#include "base/memory/scoped_ptr.h"
#include "base/message_loop.h"
#include "base/synchronization/waitable_event.h"
#include "base/threading/thread.h"
#include "base/threading/thread_checker.h"
#include "base/timer.h"
#include "cobalt/storage/savegame_thread.h"
#include "cobalt/storage/sql_vfs.h"
#include "cobalt/storage/upgrade/upgrade_reader.h"
#include "cobalt/storage/virtual_file_system.h"
#include "sql/connection.h"

namespace cobalt {
namespace storage {
class SqlContext;

// StorageManager manages a SQLite database containing cookies and local
// storage data. On most platforms, this is written to disk as a savegame
// using platform APIs. On Linux/Windows, it's a regular file.
// Internally this runs two threads: one thread to perform blocking I/O,
// and one where SQL operations occur.  Users are expected to access the
// database via an SqlContext, which can be obtained with GetSqlContext().
// The callback to GetSqlCallback will run on the SQL thread.
// Operations on SqlContext will block the SQL thread until the savegame
// is loaded.
class StorageManager {
 public:
  // Support for "upgrade" of legacy save data that may have been generated by
  // a platform other than Steel/Cobalt. If save data in the upgrade format is
  // detected, the |OnUpgrade| method will be called on |upgrade_handler_|.
  class UpgradeHandler {
   public:
    virtual ~UpgradeHandler() {}
    virtual void OnUpgrade(StorageManager* storage, const char* data,
                           int size) = 0;
  };

  struct Options {
    Savegame::Options savegame_options;
  };

  typedef base::Callback<void(SqlContext*)> SqlCallback;

  // Database version "2" indicates that this was created by Steel v1.x.
  // Database version "0" indicates that this was created by v2.x beta,
  //   patches 0-3.  Version "0" is a default from sqlite3 because these
  //   versions of the application did not set this value at all.
  // Database version "3" indicates that the schema versions of individual
  //   tables should be tracked in SchemaTable.
  static const int kDatabaseUserVersion = 3;

  // Schema-related error codes.  See GetSchemaVersion().
  enum {
    kSchemaTableIsNew = -1,
    kSchemaVersionLost = -2,
  };

  StorageManager(scoped_ptr<UpgradeHandler> upgrade_handler,
                 const Options& options);
  virtual ~StorageManager();

  // Obtain the SqlContext for our database.
  // |callback| will be called with an SqlContext that can be used to operate on
  // the database. The callback will run on the storage manager's message loop.
  void GetSqlContext(const SqlCallback& callback);

  // Schedule a write of our database to disk to happen at some point in the
  // future after a change occurs. Multiple calls to Flush() do not necessarily
  // result in multiple writes to disk.
  // This call returns immediately.
  void FlushOnChange();

  // Triggers a write to disk to happen immediately.  Each call to FlushNow()
  // will result in a write to disk.
  // |callback|, if provided, will be called when the I/O has completed,
  // and will be run on the storage manager's IO thread.
  // This call returns immediately.
  void FlushNow(const base::Closure& callback);

  const Options& options() const { return options_; }

  UpgradeHandler* upgrade_handler() const { return upgrade_handler_.get(); }

 protected:
  // Queues a flush to be executed as soon as possible.  As soon as possible
  // will be as soon as any existing flush completes, or right away if no
  // existing flush is happening.  Note that it is protected and virtual for
  // white box testing purposes.
  virtual void QueueFlush(const base::Closure& callback);

 private:
  // SqlContext needs access to our internal APIs.
  friend class SqlContext;
  // Give StorageManagerTest access, so we can more easily test some internals.
  friend class StorageManagerTest;

  // Flushes all queued flushes to the savegame thread.
  void FlushInternal();

  // Initialize the SQLite database. This blocks until the savegame load is
  // complete.
  void FinishInit();

  // Stops any timers that are currently running.
  void StopFlushOnChangeTimers();

  // Callback when flush timer has elapsed.
  void OnFlushOnChangeTimerFired();

  // Logic to be executed on the SQL thread when a flush completes.  Will
  // dispatch |flush_processing_callbacks_| callbacks and execute a new flush
  // if |flush_requested_| is true.
  void OnFlushIOCompletedSQLCallback();

  // This function will not return until all queued I/O is completed.  Since
  // it will require the SQL message loop to process, it must be called from
  // outside the SQL message loop (such as from StorageManager's destructor).
  void FinishIO();

  // This function will immediately the on change timers if they are running.
  void FireRunningOnChangeTimers();

  // Called by the destructor, to ensure we destroy certain objects on the
  // sql thread.
  void OnDestroy();

  // Internal API for use by SqlContext.
  sql::Connection* sql_connection();
  bool GetSchemaVersion(const char* table_name, int* schema_version);
  void UpdateSchemaVersion(const char* table_name, int version);

  // Upgrade handler used if upgrade save data is detected.
  scoped_ptr<UpgradeHandler> upgrade_handler_;

  // Configuration options for the Storage Manager.
  Options options_;

  // Storage manager runs on its own thread. This is where SQL database
  // operations are done.
  scoped_ptr<base::Thread> sql_thread_;
  scoped_refptr<base::MessageLoopProxy> sql_message_loop_;

  // An interface to the storage manager's SQL database that will run on
  // the correct thread.
  scoped_ptr<SqlContext> sql_context_;

  // The in-memory database connection.
  scoped_ptr<sql::Connection> connection_;

  // Virtual file system that contains our in-memory SQLite database.
  scoped_ptr<VirtualFileSystem> vfs_;

  // An interface between Sqlite and VirtualFileSystem.
  scoped_ptr<SqlVfs> sql_vfs_;

  // When the savegame is loaded at startup, we keep the raw data around
  // until we can initialize the database on the correct thread.
  scoped_ptr<Savegame::ByteVector> loaded_raw_bytes_;

  // Timers that start running when FlushOnChange() is called. When the time
  // elapses, we actually perform the write. This is a simple form of rate
  // limiting I/O writes.
  // |flush_on_last_change_timer_| is re-started on each change, enabling
  // changes to collect if several happen within a short period of time.
  // |flush_on_change_max_delay_timer_| starts on the first change and is never
  // re-started, ensuring that the flush always occurs within its delay and
  // cannot be pushed back indefinitely.
  scoped_ptr<base::OneShotTimer<StorageManager> > flush_on_last_change_timer_;
  scoped_ptr<base::OneShotTimer<StorageManager> >
      flush_on_change_max_delay_timer_;

  // See comments for for kDatabaseUserVersion.
  int loaded_database_version_;
  // false until the SQL database is fully configured.
  bool initialized_;

  // True if a flush is currently being processed on the storage message loop.
  // In this case, we should not issue more flushes, but instead set
  // |flush_requested_| to true to ensure that a new flush is submitted as
  // soon as we are done processing the current one.
  bool flush_processing_;

  // The queue of callbacks that are should be called when the current flush
  // completes.  If this is not empty, then |flush_processing_| must be true.
  std::vector<base::Closure> flush_processing_callbacks_;

  // True if |flush_processing_| is true, but we would like to perform a new
  // flush as soon as it completes.
  bool flush_pending_;

  // The queue of callbacks that will be called when the flush that follows
  // the current flush completes.  If this is non-empty, then |flush_pending_|
  // must be true.
  std::vector<base::Closure> flush_pending_callbacks_;

  base::WaitableEvent no_flushes_pending_;

  // An object that wraps Savegame inside of an I/O thread so that we can
  // flush data asynchronously.
  scoped_ptr<SavegameThread> savegame_thread_;

  DISALLOW_COPY_AND_ASSIGN(StorageManager);
};

// Proxy for accessing StorageManager's SQL database in a thread-safe way.
// All access to the StorageManager's database should be done via an SqlContext.
// Only the StorageManager can create this class.
class SqlContext {
 public:
  sql::Connection* sql_connection() const {
    return storage_manager_->sql_connection();
  }

  // Get the schema version for the given table.
  // Returns false if the table does not exist, otherwise returns true
  // and writes the version number to the schema_version pointer.
  // schema_version will be set to kSchemaTableIsNew if the table exists,
  // but the schema table was newly created in this session.
  // schema_version will be set to kSchemaVersionLost if the table exists,
  // and the schema table existed once before, but has since been lost.
  // In this case, the schema version cannot be known or directly inferred.
  bool GetSchemaVersion(const char* table_name, int* schema_version) {
    return storage_manager_->GetSchemaVersion(table_name, schema_version);
  }

  // Updates the schema version for the given table.
  // The version number must be greater than 0.
  void UpdateSchemaVersion(const char* table_name, int version) {
    return storage_manager_->UpdateSchemaVersion(table_name, version);
  }

  void FlushOnChange() { storage_manager_->FlushOnChange(); }

  void FlushNow(const base::Closure& callback) {
    storage_manager_->FlushNow(callback);
  }

 private:
  StorageManager* storage_manager_;

  explicit SqlContext(StorageManager* storage_manager)
      : storage_manager_(storage_manager) {}

  friend StorageManager::StorageManager(
      scoped_ptr<StorageManager::UpgradeHandler> upgrade_handler,
      const Options& options);
  DISALLOW_COPY_AND_ASSIGN(SqlContext);
};

}  // namespace storage
}  // namespace cobalt

#endif  // COBALT_STORAGE_STORAGE_MANAGER_H_
