// Copyright 2016 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_BRANCH_TRACKER_H_
#define PERIDOT_BIN_LEDGER_APP_BRANCH_TRACKER_H_

#include <memory>

#include <lib/callback/auto_cleanable.h>
#include <lib/fit/function.h>
#include <lib/fxl/memory/weak_ptr.h>

#include "peridot/bin/ledger/app/page_snapshot_impl.h"
#include "peridot/bin/ledger/coroutine/coroutine.h"
#include "peridot/bin/ledger/storage/public/commit_watcher.h"
#include "peridot/bin/ledger/storage/public/page_storage.h"
#include "peridot/bin/ledger/storage/public/types.h"

namespace ledger {
class PageManager;

// Tracks the head of a commit "branch". A commit is chosen arbitrarily from the
// page's head commits at construction. Subsequently, this object will track the
// head of this commit branch, unless reset by |SetBranchHead|. If two commits
// have the same parent, the first one to be received will be tracked.
class BranchTracker : public storage::CommitWatcher {
 public:
  BranchTracker(coroutine::CoroutineService* coroutine_service,
                PageManager* manager, storage::PageStorage* storage);
  ~BranchTracker() override;

  void Init(fit::function<void(Status)> on_done);

  void set_on_empty(fit::closure on_empty_callback);

  // Returns the head commit of the currently tracked branch.
  const storage::CommitId& GetBranchHeadId();

  // Registers a new PageWatcher interface.
  void RegisterPageWatcher(PageWatcherPtr page_watcher_ptr,
                           std::unique_ptr<const storage::Commit> base_commit,
                           std::string key_prefix);

  // Informs the BranchTracker that a transaction is in progress. It first
  // drains all pending Watcher updates, then stops sending them until
  // |StopTransaction| is called. |watchers_drained_callback| is called when all
  // watcher updates have been processed by the clients. This should be used by
  // |PageDelegate| when a transaction is in progress.
  void StartTransaction(fit::closure watchers_drained_callback);

  // Informs the BranchTracker that a transaction is no longer in progress.
  // Resumes sending updates to registered watchers. This should be used by
  // |PageDelegate| when a transaction is committed or rolled back.
  // |commit| must be the one created by the transaction if it was committed, or
  // nullptr otherwise.
  void StopTransaction(std::unique_ptr<const storage::Commit> commit);

  // Returns true if there are no watchers registered.
  bool IsEmpty();

 private:
  class PageWatcherContainer;

  // storage::CommitWatcher:
  void OnNewCommits(
      const std::vector<std::unique_ptr<const storage::Commit>>& commits,
      storage::ChangeSource source) override;

  void InitCommitAndSetWatcher(storage::CommitId commit_id);

  void CheckEmpty();

  coroutine::CoroutineService* coroutine_service_;
  PageManager* manager_;
  storage::PageStorage* storage_;
  callback::AutoCleanableSet<PageWatcherContainer> watchers_;
  fit::closure on_empty_callback_;

  bool transaction_in_progress_;
  // The following two variables hold the commit object and id correspondingly
  // of the commit tracked by this BranchTracker. |current_commit_| is used
  // for notifying the watchers. On initialization, |current_commit_id_| is set
  // to track the first head as returned from PageStorage. |current_commit_| at
  // that point equals nullptr and is only updated with a valid Commit,
  // corresponding to the tracked id, after the first call to OnNewCommits or
  // StopTransaction. Since the notifications are sent to the watchers only
  // after updating the tracked commit, the value of the |current_commit_| at
  // initialization (which is set to nullptr) is not necessary.
  std::unique_ptr<const storage::Commit> current_commit_;
  storage::CommitId current_commit_id_;

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

  FXL_DISALLOW_COPY_AND_ASSIGN(BranchTracker);
};

}  // namespace ledger

#endif  // PERIDOT_BIN_LEDGER_APP_BRANCH_TRACKER_H_
