// 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_LEDGER_CLIENT_H_
#define PERIDOT_LIB_LEDGER_CLIENT_LEDGER_CLIENT_H_

#include <functional>
#include <memory>
#include <vector>

#include <fuchsia/ledger/cpp/fidl.h>
#include <fuchsia/ledger/internal/cpp/fidl.h>
#include <lib/async/cpp/operation.h>
#include <lib/fidl/cpp/binding_set.h>
#include <lib/fidl/cpp/interface_ptr.h>
#include <lib/fxl/logging.h>
#include <lib/fxl/macros.h>

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

namespace modular {

class PageClient;

// The primary purpose of the ledger client is to act as conflict resolver
// factory which is able to dispatch conflicts to the page clients based on
// their page and key prefix.
class LedgerClient : fuchsia::ledger::ConflictResolverFactory {
 public:
  LedgerClient(fuchsia::ledger::internal::LedgerRepository* ledger_repository,
               const std::string& name, std::function<void()> error);
  LedgerClient(fuchsia::ledger::LedgerPtr ledger);
  ~LedgerClient() override;

  fuchsia::ledger::Ledger* ledger() const { return ledger_.get(); }

  // A callback that is invoked every time one conflict resolution completes.
  // Used only for testing so far.
  void add_watcher(std::function<void()> watcher) {
    watchers_.emplace_back(std::move(watcher));
  }

 private:
  friend class PageClient;
  class ConflictResolverImpl;
  struct PageEntry;

  // Used by PageClient to access a new page on creation. Two page clients of
  // the same page share the same ledger::Page connection.
  fuchsia::ledger::Page* GetPage(PageClient* page_client,
                                 const std::string& context,
                                 const fuchsia::ledger::PageId& page_id);

  // PageClient deregisters itself on destrution.
  void DropPageClient(PageClient* page_client);

  // |ConflictResolverFactory|
  void GetPolicy(LedgerPageId page_id, GetPolicyCallback callback) override;

  // |ConflictResolverFactory|
  void NewConflictResolver(
      LedgerPageId page_id,
      fidl::InterfaceRequest<fuchsia::ledger::ConflictResolver> request)
      override;

  void ClearConflictResolver(const LedgerPageId& page_id);

  // The ledger this is a client of.
  fuchsia::ledger::LedgerPtr ledger_;

  fidl::BindingSet<fuchsia::ledger::ConflictResolverFactory> bindings_;
  std::vector<std::unique_ptr<ConflictResolverImpl>> resolvers_;

  // ledger::Page connections are owned by LedgerClient, and only handed to
  // PageClient as naked pointers. This allows multiple clients of the same page
  // to share a page connection.
  std::vector<std::unique_ptr<PageEntry>> pages_;

  // Notified whenever a conflict resolution cycle finishes.
  std::vector<std::function<void()>> watchers_;

  FXL_DISALLOW_COPY_AND_ASSIGN(LedgerClient);
};

// A conflict resolver for one page that delegates the diff for a key to the
// appropriate page client that handles that key.
class LedgerClient::ConflictResolverImpl : fuchsia::ledger::ConflictResolver {
 public:
  ConflictResolverImpl(LedgerClient* ledger_client,
                       const LedgerPageId& page_id);
  ~ConflictResolverImpl() override;

  void Connect(
      fidl::InterfaceRequest<fuchsia::ledger::ConflictResolver> request);

  const LedgerPageId& page_id() const { return page_id_; }

 private:
  // |ConflictResolver|
  void Resolve(
      fidl::InterfaceHandle<fuchsia::ledger::PageSnapshot> left_version,
      fidl::InterfaceHandle<fuchsia::ledger::PageSnapshot> right_version,
      fidl::InterfaceHandle<fuchsia::ledger::PageSnapshot> common_version,
      fidl::InterfaceHandle<fuchsia::ledger::MergeResultProvider>
          result_provider) override;

  void GetPageClients(std::vector<PageClient*>* page_clients);

  void NotifyWatchers() const;

  LedgerClient* const ledger_client_;
  LedgerPageId page_id_;

  fidl::BindingSet<fuchsia::ledger::ConflictResolver> bindings_;

  OperationQueue operation_queue_;
  class ResolveCall;

  FXL_DISALLOW_COPY_AND_ASSIGN(ConflictResolverImpl);
};

}  // namespace modular

#endif  // PERIDOT_LIB_LEDGER_CLIENT_LEDGER_CLIENT_H_
