// 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_SESSION_STORAGE_H_
#define PERIDOT_BIN_SESSIONMGR_STORAGE_SESSION_STORAGE_H_

#include <fuchsia/modular/cpp/fidl.h>
#include <fuchsia/modular/internal/cpp/fidl.h>
#include <lib/async/cpp/future.h>

#include "peridot/bin/sessionmgr/storage/story_storage.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"

namespace modular {

// This class has the following responsibilities:
//
// * Manage the persistence of metadata about what stories are part of a single
//   session.
// * Observe the metadata and call clients back when changes initiated by other
//   Ledger clients appear.
// * Manage the lifecycle of Ledger pages for storing individual story
//   metadata. The contents of these pages are governed by StoryStoage.
//
// All calls operate directly on the Ledger itself: no local caching is
// performed.
class SessionStorage : public PageClient {
 public:
  // Constructs a new SessionStorage with storage on |page_id| in the ledger
  // given by |ledger_client|.
  //
  // |ledger_client| must outlive *this.
  SessionStorage(LedgerClient* ledger_client, LedgerPageId page_id);

  // |callback| is notified whenever a story has been deleted. This
  // notification is either the result of:
  //
  // a) The story being deleted on another device.
  // b) The story having been deleted locally with DeleteStory().
  void set_on_story_deleted(
      std::function<void(fidl::StringPtr story_id)> callback) {
    on_story_deleted_ = std::move(callback);
  }

  // |callback| is notified whenever a story has been added or updated.
  // Currently we do not differentiate between the two, and it is up to the
  // client to make this distinction.
  //
  // The update could be the result of a local modification (ie, through
  // Update*()) or a modification on another device.
  void set_on_story_updated(
      std::function<void(fidl::StringPtr story_id,
                         fuchsia::modular::internal::StoryData story_data)>
          callback) {
    on_story_updated_ = std::move(callback);
  }

  // Creates a new story and returns a tuple of (story id, story ledger page
  // id) on completion. |story_name| and |extra_info| may be null.
  //
  // If |story_name| is not provided, a UUID will be generated as the name.
  //
  // If |extra_info| is set, populates StoryData.story_info.extra with the
  // entries given.
  //
  // TODO(thatguy): Allowing for null story names is left in for backwards
  // compatibility with existing code. The intention is that all clients
  // outside the FW (through FIDL interfaces) use story names exclusively.  It
  // is unclear if internal story IDs should be an implementation detail of
  // SessionStorage, or if they should be exposed to the story runtime
  // architecture.
  FuturePtr<fidl::StringPtr, fuchsia::ledger::PageId> CreateStory(
      fidl::StringPtr story_name,
      fidl::VectorPtr<fuchsia::modular::StoryInfoExtraEntry> extra_info,
      fuchsia::modular::StoryOptions story_options);

  // Same as above, but defaults |story_name| to nullptr.
  FuturePtr<fidl::StringPtr, fuchsia::ledger::PageId> CreateStory(
      fidl::VectorPtr<fuchsia::modular::StoryInfoExtraEntry> extra_info,
      fuchsia::modular::StoryOptions story_options);

  // Deletes the |story_id| from the list of known stories and completes the
  // returned Future when done.
  //
  // Does not currently delete the story's page, so it is left dangling.
  //
  // TODO(thatguy): Deleting stories is a two-step process:
  //   1) Remove the story from the list of active stories (so it doesn't show
  //      up on the timeline).
  //   2) Delete the underlying story storage page.
  //
  // We only do (1). Find a way to split (1) and (2): either have the client
  // pass in a Future that signals when it's OK to delete the story storage (ie,
  // once the story has shut down cleanly) or split the function into two calls.
  // MI4-1002
  FuturePtr<> DeleteStory(fidl::StringPtr story_id);

  // Sets the last focused timestamp for |story_id| to |ts|. Completes the
  // returned Future when done.
  FuturePtr<> UpdateLastFocusedTimestamp(fidl::StringPtr story_id, int64_t ts);

  // Returns a Future StoryDataPtr for |story_id|. If |story_id| is not a valid
  // story, the returned StoryDataPtr will be null.
  FuturePtr<fuchsia::modular::internal::StoryDataPtr> GetStoryData(
      fidl::StringPtr story_id);

  // Returns a Future vector of StoryData for all stories in this session.
  //
  // TODO(thatguy): If the return value grows large, an dispatcher stream would
  // be a more appropriate return value.
  FuturePtr<fidl::VectorPtr<fuchsia::modular::internal::StoryData>>
  GetAllStoryData();

  FuturePtr<> UpdateStoryOptions(fidl::StringPtr story_id,
                                 fuchsia::modular::StoryOptions story_options);

  // Gets the StoryStorage for the story with the given |story_id| to perform
  // operations on the story such as adding modules, updating links, etc.
  FuturePtr<std::unique_ptr<StoryStorage>> GetStoryStorage(
      fidl::StringPtr story_id);

  // Returns the snapshot for the story. If there is no snapshot for the story
  // or the read operation failed, the return value of |fuchsia::mem::BufferPtr|
  // will be nullptr.
  FuturePtr<fuchsia::mem::BufferPtr> ReadSnapshot(fidl::StringPtr story_id);

  // Writes the given |snapshot| to storage. The returned future will resolve
  // when the |snapshot| has been written to storage or when it has failed to
  // write to storage.
  FuturePtr<> WriteSnapshot(fidl::StringPtr story_id,
                            fuchsia::mem::Buffer snapshot);

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

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

  LedgerClient* const ledger_client_;
  OperationQueue operation_queue_;

  std::function<void(fidl::StringPtr story_id)> on_story_deleted_;
  std::function<void(fidl::StringPtr story_id,
                     fuchsia::modular::internal::StoryData story_data)>
      on_story_updated_;

  FXL_DISALLOW_COPY_AND_ASSIGN(SessionStorage);
};

}  // namespace modular

#endif  // PERIDOT_BIN_SESSIONMGR_STORAGE_SESSION_STORAGE_H_
