// 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_BIN_LEDGER_APP_MERGING_CONFLICT_RESOLVER_CLIENT_H_
#define PERIDOT_BIN_LEDGER_APP_MERGING_CONFLICT_RESOLVER_CLIENT_H_

#include <memory>
#include <vector>

#include <lib/callback/operation_serializer.h>
#include <lib/callback/waiter.h>
#include <lib/fit/function.h>
#include <lib/fxl/macros.h>
#include <lib/fxl/memory/weak_ptr.h>

#include "peridot/bin/ledger/app/diff_utils.h"
#include "peridot/bin/ledger/app/page_manager.h"
#include "peridot/bin/ledger/fidl/error_notifier.h"
#include "peridot/bin/ledger/fidl/include/types.h"
#include "peridot/bin/ledger/storage/public/commit.h"
#include "peridot/bin/ledger/storage/public/page_storage.h"

namespace ledger {
// Client handling communication with a ConflictResolver interface in order to
// merge conflicting commit branches. It is used both by AutoMergeStrategy and
// CustomMergeStrategy.
class ConflictResolverClient
    : public fuchsia::ledger::MergeResultProviderErrorNotifierDelegate {
 public:
  explicit ConflictResolverClient(
      storage::PageStorage* storage, PageManager* page_manager,
      ConflictResolver* conflict_resolver,
      std::unique_ptr<const storage::Commit> left,
      std::unique_ptr<const storage::Commit> right,
      std::unique_ptr<const storage::Commit> ancestor,
      fit::function<void(Status)> callback);
  ~ConflictResolverClient() override;

  void Start();
  void Cancel();

 private:
  void OnNextMergeResult(
      const MergedValue& merged_value,
      const fxl::RefPtr<callback::Waiter<storage::Status,
                                         storage::ObjectIdentifier>>& waiter);

  // Rolls back journal, closes merge result provider and invokes callback_ with
  // |status|. This method must be called at most once.
  void Finalize(Status status);

  // Performs a diff of the given type on the conflict. Return a |Status|
  // different than OK if an error occured. If no error, return an
  // |IterationStatus|.
  void GetDiff(
      diff_utils::DiffType type, std::unique_ptr<Token> token,
      fit::function<void(Status, IterationStatus, fidl::VectorPtr<DiffEntry>,
                         std::unique_ptr<Token>)>
          callback);

  // MergeResultProviderNotifierDelegate:
  void GetFullDiff(
      std::unique_ptr<Token> token,
      fit::function<void(Status, Status, fidl::VectorPtr<DiffEntry>,
                         std::unique_ptr<Token>)>
          callback) override;
  void GetFullDiffNew(
      std::unique_ptr<Token> token,
      fit::function<void(Status, IterationStatus, fidl::VectorPtr<DiffEntry>,
                         std::unique_ptr<Token>)>
          callback) override;
  void GetConflictingDiff(
      std::unique_ptr<Token> token,
      fit::function<void(Status, Status, fidl::VectorPtr<DiffEntry>,
                         std::unique_ptr<Token>)>
          callback) override;
  void GetConflictingDiffNew(
      std::unique_ptr<Token> token,
      fit::function<void(Status, IterationStatus, fidl::VectorPtr<DiffEntry>,
                         std::unique_ptr<Token>)>
          callback) override;
  void Merge(fidl::VectorPtr<MergedValue> merged_values,
             fit::function<void(Status, Status)> callback) override;
  void MergeNew(fidl::VectorPtr<MergedValue> merged_values,
                fit::function<void(Status)> callback) override;
  void MergeNonConflictingEntries(
      fit::function<void(Status, Status)> callback) override;
  void MergeNonConflictingEntriesNew(
      fit::function<void(Status)> callback) override;
  void Done(fit::function<void(Status, Status)> callback) override;
  void DoneNew(fit::function<void(Status)> callback) override;

  // Checks whether this ConflictResolverClient is still valid (not deleted nor
  // cancelled) and the status is OK. Returns |true| in that case. Otherwise,
  // calls |callback| with the given |status| and calls |Finalize| if this
  // object is not deleted, then return |false|.
  static bool IsInValidStateAndNotify(
      const fxl::WeakPtr<ConflictResolverClient>& weak_this,
      const fit::function<void(Status)>& callback,
      storage::Status status = storage::Status::OK);

  storage::PageStorage* const storage_;
  PageManager* const manager_;
  ConflictResolver* const conflict_resolver_;

  std::unique_ptr<const storage::Commit> const left_;
  std::unique_ptr<const storage::Commit> const right_;
  std::unique_ptr<const storage::Commit> const ancestor_;

  // Called when the merge process is finished.
  fit::function<void(Status)> callback_;

  // |has_merged_values_| is true when |Merge| has been called to set some
  // values. It is used as an optimization in |MergeNonConflictingEntries|.
  bool has_merged_values_ = false;
  std::unique_ptr<storage::Journal> journal_;
  // |in_client_request_| is true when waiting for the callback of the
  // ConflictResolver.Resolve call. When this merge is cancelled, we check this
  // boolean to know if we should abort immediately (when in a client request,
  // as the client may have disconnected) and when we should wait for the
  // operation to finish (the other cases, such as committing the merge).
  bool in_client_request_ = false;
  bool cancelled_ = false;

  // Operations are operating on the state of the merge commit. They must be
  // serialized.
  callback::OperationSerializer operation_serializer_;

  ledger::ErrorNotifierBinding<
      fuchsia::ledger::MergeResultProviderErrorNotifierDelegate>
      merge_result_provider_binding_;

  // This must be the last member of the class.
  fxl::WeakPtrFactory<ConflictResolverClient> weak_factory_;

  FXL_DISALLOW_COPY_AND_ASSIGN(ConflictResolverClient);
};

}  // namespace ledger

#endif  // PERIDOT_BIN_LEDGER_APP_MERGING_CONFLICT_RESOLVER_CLIENT_H_
