// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef PERIDOT_BIN_SESSIONMGR_STORAGE_STORY_STORAGE_H_
#define PERIDOT_BIN_SESSIONMGR_STORAGE_STORY_STORAGE_H_

#include <map>

#include <fuchsia/modular/cpp/fidl.h>
#include <lib/async/cpp/future.h>
#include <lib/fidl/cpp/interface_ptr_set.h>
#include <lib/fit/defer.h>

#include "peridot/lib/ledger_client/ledger_client.h"
#include "peridot/lib/ledger_client/page_client.h"
#include "peridot/lib/ledger_client/page_id.h"

using fuchsia::modular::LinkPath;
using fuchsia::modular::LinkPathPtr;
using fuchsia::modular::ModuleData;
using fuchsia::modular::ModuleDataPtr;

namespace modular {

// This class has the following responsibilities:
//
// * Manage the persistence of metadata about what mods are part of a single
//   story.
// * Manage the persistence of link values in a single story.
// * Observe the metadata and call clients back when changes initiated by other
//   Ledger clients appear.
//
// All calls operate directly on the Ledger itself: no local caching is
// performed.
class StoryStorage : public PageClient {
 public:
  // Constructs a new StoryStorage with storage on |page_id| in the ledger
  // given by |ledger_client|.
  //
  // |ledger_client| must outlive *this.
  StoryStorage(LedgerClient* ledger_client, fuchsia::ledger::PageId page_id);

  enum class Status {
    OK = 0,
    LEDGER_ERROR = 1,
    VMO_COPY_ERROR = 2,
    // Indicates the storage operation detected either an invalid or conflicting
    // entity type (e.g. an empty type string or a write with a mismatched
    // type).
    INVALID_ENTITY_TYPE = 3,
    // Indicates the storage operation detected an invalid entity cookie (e.g.
    // an empty cookie).
    INVALID_ENTITY_COOKIE = 4,
  };

  // =========================================================================
  // ModuleData

  // Sets the callback that is called whenever ModuleData is added or updated
  // in underlying storage. Excludes notifications for changes (such as with
  // WriteModuleData() or UpdateModuleData()) made on this instance of
  // StoryStorage.
  void set_on_module_data_updated(fit::function<void(ModuleData)> callback) {
    on_module_data_updated_ = std::move(callback);
  }

  // Returns the current ModuleData for |module_path|. If not found, the
  // returned value is null.
  FuturePtr<ModuleDataPtr> ReadModuleData(
      const std::vector<std::string>& module_path);

  // Writes |module_data| to storage. The returned future is completed
  // once |module_data| has been written and a notification confirming the
  // write has been received.
  FuturePtr<> WriteModuleData(ModuleData module_data);

  // Reads the ModuleData for |module_path|, calls |mutate_fn| which may modify
  // the contents, and writes the resulting ModuleData back to storage.
  // Completes the returned future once a notification confirming the write has
  // been received.
  //
  // If there is no ModuleData for |module_path|, |mutate_fn| will be called
  // with a null ModuleDataPtr. |mutate_fn| may initialize the ModuleDataPtr,
  // in which case a new ModuleData record will be written.
  //
  // It is illegal to change ModuleDataPtr->module_path in |mutate_fn| or to
  // reset to null an otherwise initialized ModuleDataPtr.
  FuturePtr<> UpdateModuleData(const std::vector<std::string>& module_path,
                               fit::function<void(ModuleDataPtr*)> mutate_fn);

  // Returns all ModuleData entries for all mods.
  FuturePtr<std::vector<ModuleData>> ReadAllModuleData();

  // =========================================================================
  // Link data

  // Use with WatchLink below.
  //
  // Called whenever a change occurs to the link specified in
  // WatchLink(). The receiver gets the LinkPath, the current
  // |value| and whatever |context| was passed into the mutation call. If
  // the new value did not originate from a call on *this, |context| will be
  // given the special value of nullptr.
  using LinkUpdatedCallback =
      fit::function<void(const fidl::StringPtr& value, const void* context)>;
  using LinkWatcherAutoCancel = fit::deferred_action<fit::function<void()>>;

  // Registers |callback| to be invoked whenever a change to the link value at
  // |link_path| occurs. See documentation for LinkUpdatedCallback above. The
  // returned LinkWatcherAutoCancel must be kept alive as long as the callee
  // wishes to receive link updates on |callback|.
  LinkWatcherAutoCancel WatchLink(const LinkPath& link_path,
                                  LinkUpdatedCallback callback);

  // Returns the value for |link_path|.
  //
  // The returned value will be stringified JSON. If no value is found, returns
  // "null", the JSON string for a null value.
  FuturePtr<Status, std::string> GetLinkValue(const LinkPath& link_path);

  // Fetches the link value at |link_path| and passes it to |mutate_fn|.
  // |mutate_fn| must synchronously update the StringPtr with the desired new
  // value for the link and return. The new value will be written to storage
  // and the returned future completed with the status.
  //
  // |mutate_fn|'s |value| points to the current value for the link and may be
  // modified. If the link is new and has no value, value->is_null() will be
  // true. Otherwise, *value will be valid JSON and must remain valid JSON
  // after |mutate_fn| is done.
  //
  // |context| is carried with the mutation operation and passed to any
  // notifications about this change on this instance of StoryStorage. A value
  // of nullptr for |context| is illegal.
  FuturePtr<Status> UpdateLinkValue(
      const LinkPath& link_path,
      fit::function<void(fidl::StringPtr* value)> mutate_fn,
      const void* context);

  // Sets the type and data for the Entity stored under |cookie|.
  //
  // |type| If Entity data has already been written, this type is expected to
  //        match the type which was previously written.
  // |data| The data to write to the Entity.
  FuturePtr<Status> SetEntityData(const std::string& cookie,
                                  const std::string& type,
                                  fuchsia::mem::Buffer data);

  // Returns the type for the Entity stored under the provided |cookie|.
  //
  // If an error occurred the Status will indicate the error, and returned
  // string will be empty.
  FuturePtr<Status, std::string> GetEntityType(const std::string& cookie);

  // Returns the data for the Entity stored under the provided |cookie|.
  //
  // |type| The expected type of the data.
  //
  // If an error occurred the Status will indicate the error, and returned
  // fuchsia::mem::BufferPtr will be nullptr.
  FuturePtr<Status, fuchsia::mem::BufferPtr> GetEntityData(
      const std::string& cookie, const std::string& type);

  // Registers a watcher for an Entity. The EntityWatcher is notified of data
  // changes until it is closed.
  //
  // |cookie| The Entity cookie.
  // |type| The type of the observed entity data.
  // |watcher| The entity watcher which will get notified of updates to the
  // entity stored under |cookie|.
  void WatchEntity(const std::string& cookie, const std::string& type,
                   fuchsia::modular::EntityWatcherPtr watcher);

  // Sets the |entity_name| of the Entity associated with |cookie|.
  //
  // Once an entity has been named, the associated |cookie| can be retrieved by
  // calling |GetEntityCookieForName|.
  FuturePtr<Status> SetEntityName(const std::string& cookie,
                                  const std::string& entity_name);

  // Gets the Entity cookie associated with the specified name.
  FuturePtr<Status, std::string> GetEntityCookieForName(
      const std::string& entity_name);

  // Completes the returned future after all prior methods have completed.
  FuturePtr<> Sync();

 private:
  // |PageClient|
  void OnPageChange(const std::string& key,
                    fuchsia::mem::BufferPtr value) override;

  // |PageClient|
  void OnPageDelete(const std::string& key) override;

  // |PageClient|
  void OnPageConflict(Conflict* conflict) override;

  // Notifies any watchers in |link_watchers_|.
  //
  // |value| will never be a null StringPtr. |value| is always a JSON-encoded
  // string, so a null value will be presented as the string "null".
  void NotifyLinkWatchers(const std::string& link_key, fidl::StringPtr value,
                          const void* context);

  // Notifies any watchers in |entity_watchers_[cookie]|.
  //
  // |value| is a valid fuchsia::mem::Buffer.
  void NotifyEntityWatchers(const std::string& cookie,
                            fuchsia::mem::Buffer value);

  // Completes the returned Future when the ledger notifies us (through
  // OnPageChange()) of a write for |key| with |value|.
  FuturePtr<> WaitForWrite(const std::string& key, const std::string& value);

  fxl::WeakPtr<StoryStorage> GetWeakPtr();

  LedgerClient* const ledger_client_;
  const fuchsia::ledger::PageId page_id_;
  // NOTE: This operation queue serializes all link operations, even though
  // operations on different links do not have an impact on each other. Consider
  // adding an OperationQueue per link if we want to increase concurrency.
  OperationQueue operation_queue_;

  // Called when new ModuleData is encountered from the Ledger.
  fit::function<void(ModuleData)> on_module_data_updated_;

  // A map of link ledger key -> watcher callback. Multiple clients can watch
  // the same Link.
  std::multimap<std::string, LinkUpdatedCallback> link_watchers_;

  // A map of Entity cookie (i.e. Ledger key) -> set of watchers. Multiple
  // watchers can watch the same entity.
  std::map<std::string, fidl::InterfacePtrSet<fuchsia::modular::EntityWatcher>>
      entity_watchers_;

  // A map of ledger (key, value) to (vec of future). When we see a
  // notification in OnPageChange() for a matching (key, value), we complete
  // all the respective futures.
  //
  // NOTE: we use a map<> of vector<> here instead of a multimap<> because we
  // complete all the Futures for a given key/value pair at once.
  std::map<std::pair<std::string, std::string>, std::vector<FuturePtr<>>>
      pending_writes_;

  fxl::WeakPtrFactory<StoryStorage> weak_ptr_factory_;

  FXL_DISALLOW_COPY_AND_ASSIGN(StoryStorage);
};

}  // namespace modular

#endif  // PERIDOT_BIN_SESSIONMGR_STORAGE_STORY_STORAGE_H_
