// 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/store/memory_store.h"
#include "cobalt/storage/upgrade/upgrade_reader.h"

namespace cobalt {
namespace storage {

// StorageManager manages a store 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 store operations occur.  Users are expected to access the
// store via an MemoryStore, which can be obtained with GetReadOnlyMemoryStore()
// or WithMemoryStore(). The callback to will run on the store thread.
// Operations on MemoryStore will block the store 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(const MemoryStore&)> ReadOnlyMemoryStoreCallback;
  typedef base::Callback<void(MemoryStore*)> MemoryStoreCallback;

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

  void WithReadOnlyMemoryStore(const ReadOnlyMemoryStoreCallback& callback);
  void WithMemoryStore(const MemoryStoreCallback& callback);

  // Schedule a write of our memory store 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:
  // 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 store. 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 store thread when a flush completes.  Will
  // dispatch |flush_processing_callbacks_| callbacks and execute a new flush
  // if |flush_requested_| is true.
  void OnFlushIOCompletedCallback();

  // This function will not return until all queued I/O is completed.  Since
  // it will require the store message loop to process, it must be called from
  // outside the store 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
  // store thread
  void OnDestroy();

  // 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 store
  // operations are done.
  scoped_ptr<base::Thread> storage_thread_;
  scoped_refptr<base::MessageLoopProxy> storage_message_loop_;

  scoped_ptr<MemoryStore> memory_store_;

  // When the savegame is loaded at startup, we keep the raw data around
  // until we can initialize the store 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 store 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);
};

}  // namespace storage
}  // namespace cobalt

#endif  // COBALT_STORAGE_STORAGE_MANAGER_H_
