// Copyright 2017 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_LIB_LEDGER_CLIENT_PAGE_CLIENT_H_
#define PERIDOT_LIB_LEDGER_CLIENT_PAGE_CLIENT_H_

#include <array>
#include <string>

#include <fuchsia/ledger/cpp/fidl.h>
#include <lib/fidl/cpp/binding.h>
#include <lib/fidl/cpp/interface_request.h>
#include <lib/fxl/macros.h>

#include "peridot/lib/ledger_client/types.h"

namespace modular {

class LedgerClient;

// A helper class that holds on to a page snapshot through a shared
// pointer, hands out shared pointers to it, can replace the snapshot
// by a new one, and registers a connection error handler on it. It
// essentially wraps fuchsia::ledger::PageSnapshot.
//
// This is used by classes that hold onto a PageSnapshot and update it
// in return calls from PageWatcher notifications, and use Operation
// containers to access the snapshot.
//
// Every time we receive an OnChange notification, we update the page
// snapshot so we see the current state. Just in case, we also install
// a connection error handler on the snapshot connection, so we can
// log when the connection unexpectedly closes, although we cannot do
// anything else about it.
//
// An instance of this class always holds the current snapshot of the
// page we read from, as obtained from the watcher on the page. It is
// held by a shared pointer, because the update may occur while
// Operation instances that read from it are still in progress, and
// they need to hold on to the same snapshot they started with, lest
// the methods called on that snapshot never return.
//
// The same behavior as with a shared_ptr could be accomplished with
// a duplicate PageSnapshotPtr for each Operation instance that needs
// one, but PageSnapshot doesn't have a duplicate method.
class PageClient : fuchsia::ledger::PageWatcher {
 public:
  // |context| is used as a string prefix on log messages.  |ledger_client| is
  // used to retrieve a handle to the page specified in |page_id|, and to
  // listen for conflicts from the ledger. If |prefix| is provided, the
  // resulting page snapshot and change notifications are limited to only keys
  // with that prefix. However, OnPageChange()'s |key| will include the full
  // key, including the prefix.
  //
  // |ledger_client| must outlive *this.
  PageClient(std::string context, LedgerClient* ledger_client,
             LedgerPageId page_id, std::string prefix = "");
  ~PageClient() override;

  // Returns a snapshot of the Ledger page under |prefix| at the most recent
  // timepoint.
  //
  // If |on_error| is provided, it will be called if there was a Ledger error
  // trying to get the snapshot.
  //
  // NOTE: There is no guaranteed timing for writes made to the returned
  // PageSnapshot and notifications of changes through OnPageChange(). The
  // ordering is guaranteed to be the same, ignoring changes to the writes
  // caused by conflict resolution which can cause some writes to disappear.
  fuchsia::ledger::PageSnapshotPtr NewSnapshot(
      std::function<void()> on_error = nullptr);

  const fuchsia::ledger::PageId& page_id() const { return page_id_; }
  const std::string& prefix() const { return prefix_; }
  fuchsia::ledger::Page* page() { return page_; }

  // Computed by implementations of OnPageConflict() in derived classes.
  enum ConflictResolution { LEFT, RIGHT, MERGE };

  // The argument to OnPageConflict(). It's mutated in place so it's easier to
  // extend without having to alter clients.
  struct Conflict {
    fidl::VectorPtr<uint8_t> key;

    bool has_left{};
    std::string left;
    bool left_is_deleted{};

    bool has_right{};
    std::string right;
    bool right_is_deleted{};

    ConflictResolution resolution{LEFT};
    std::string merged;
    bool merged_is_deleted{};
  };

 protected:
  // Derived classes implement this method as needed. The default implementation
  // copies the VMO to a string and forwards to |OnPageChange(const
  // std::string&, const std::string&)|.
  virtual void OnPageChange(const std::string& key,
                            fuchsia::mem::BufferPtr value);

 private:
  // Derived classes implement this method as needed. The default implementation
  // does nothing. This method is only called if forwarded from
  // |OnPageChange(const std::string&, fuchsia::mem::BufferPtr)|.
  virtual void OnPageChange(const std::string& key, const std::string& value);
  // Derived classes implement this method as needed. The default implementation
  // does nothing.
  virtual void OnPageDelete(const std::string& key);

  // Derived classes implement this method as needed. The default implementation
  // selects left and logs an INFO about the unresolved conflict.
  //
  // For now, only per-key conflict resolution is supported by page client. If
  // we need more coherency for conflict resolution, this can be changed.
  //
  // For now, conflict resolution is synchronous. Can be changed too, for
  // example to go on an OperationQueue to wait for ongoing changes to reconcile
  // with.
  //
  // If ConflictResolution is MERGE, the result is returned in merged*. It is
  // possible that the merge of two undeleted values is to the delete the key.
  //
  // This is invoked from the conflict resolver in LedgerClient.
  friend class LedgerClient;
  virtual void OnPageConflict(Conflict* conflict);

  // |PageWatcher|
  void OnChange(fuchsia::ledger::PageChange page,
                fuchsia::ledger::ResultState result_state,
                OnChangeCallback callback) override;

  fidl::Binding<fuchsia::ledger::PageWatcher> binding_;
  const std::string context_;

  LedgerClient* const ledger_client_;
  const fuchsia::ledger::PageId page_id_;
  fuchsia::ledger::Page* const page_;
  const std::string prefix_;

  FXL_DISALLOW_COPY_AND_ASSIGN(PageClient);
};

// Retrieves all entries from the given snapshot and calls the given callback
// with the final status.
//
// The FIDL pointer backing |snapshot| must have the same life time as
// |entries|, so that callbacks are cancelled when |entries| are deleted before
// |callback| is invoked.
void GetEntries(fuchsia::ledger::PageSnapshot* snapshot,
                std::vector<fuchsia::ledger::Entry>* entries,
                std::function<void(fuchsia::ledger::Status)> done);

}  // namespace modular

#endif  // PERIDOT_LIB_LEDGER_CLIENT_PAGE_CLIENT_H_
