// 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.

#include "peridot/bin/ledger/app/merging/common_ancestor.h"

#include <utility>

#include <lib/callback/waiter.h>
#include <lib/fit/function.h>
#include <lib/fxl/memory/ref_ptr.h>

#include "peridot/bin/ledger/app/page_utils.h"
#include "peridot/bin/ledger/coroutine/coroutine.h"
#include "peridot/bin/ledger/coroutine/coroutine_waiter.h"

namespace ledger {

namespace {

// Comparator for commits that order commits based on their generation, then on
// their id.
struct GenerationComparator {
  bool operator()(const std::unique_ptr<const storage::Commit>& lhs,
                  const std::unique_ptr<const storage::Commit>& rhs) const {
    uint64_t lhs_generation = lhs->GetGeneration();
    uint64_t rhs_generation = rhs->GetGeneration();
    return lhs_generation == rhs_generation ? lhs->GetId() < rhs->GetId()
                                            : lhs_generation < rhs_generation;
  }
};

// Find the common ancestor the 2 given commits.
//
// The algorithm goes as follows: we keep a set of "active" commits, ordered
// by generation order. Until this set has only one element, we take the
// commit with the greater generation (the one deepest in the commit graph)
// and replace it by its parent. If we seed the initial set with two commits,
// we get their unique lowest common ancestor.
// At each step of the iteration we request the parent commits of all commits
// with the same generation.
storage::Status FindCommonAncestorSync(
    coroutine::CoroutineHandler* handler, storage::PageStorage* storage,
    std::unique_ptr<const storage::Commit> head1,
    std::unique_ptr<const storage::Commit> head2,
    std::unique_ptr<const storage::Commit>* result) {
  std::set<std::unique_ptr<const storage::Commit>, GenerationComparator>
      commits;
  commits.emplace(std::move(head1));
  commits.emplace(std::move(head2));

  while (commits.size() > 1) {
    // Pop the newest commits and retrieve their parents.
    uint64_t expected_generation = (*commits.rbegin())->GetGeneration();
    auto waiter = fxl::MakeRefCounted<callback::Waiter<
        storage::Status, std::unique_ptr<const storage::Commit>>>(
        storage::Status::OK);
    while (commits.size() > 1 &&
           expected_generation == (*commits.rbegin())->GetGeneration()) {
      // Pop the newest commit.
      std::unique_ptr<const storage::Commit> commit =
          std::move(commits.extract(std::prev(commits.end())).value());
      // Request its parents.
      for (const auto& parent_id : commit->GetParentIds()) {
        storage->GetCommit(parent_id, waiter->NewCallback());
      }
    }
    storage::Status status;
    std::vector<std::unique_ptr<const storage::Commit>> parents;
    if (coroutine::Wait(handler, std::move(waiter), &status, &parents) ==
        coroutine::ContinuationStatus::INTERRUPTED) {
      return storage::Status::INTERRUPTED;
    }
    if (status != storage::Status::OK) {
      return status;
    }
    // Once the parents have been retrieved, add these in the set.
    // ancestor in that generation.
    for (auto& parent : parents) {
      commits.insert(std::move(parent));
    }
  }
  FXL_DCHECK(commits.size() == 1);
  *result = std::move(commits.extract(commits.begin()).value());
  return storage::Status::OK;
}

}  // namespace

void FindCommonAncestor(
    coroutine::CoroutineService* coroutine_service,
    storage::PageStorage* const storage,
    std::unique_ptr<const storage::Commit> head1,
    std::unique_ptr<const storage::Commit> head2,
    fit::function<void(Status, std::unique_ptr<const storage::Commit>)>
        callback) {
  coroutine_service->StartCoroutine(
      [storage, head1 = std::move(head1), head2 = std::move(head2),
       callback =
           std::move(callback)](coroutine::CoroutineHandler* handler) mutable {
        std::unique_ptr<const storage::Commit> result;
        storage::Status status = FindCommonAncestorSync(
            handler, storage, std::move(head1), std::move(head2), &result);
        callback(PageUtils::ConvertStatus(status), std::move(result));
      });
}

}  // namespace ledger
