// Copyright 2018 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/p2p_sync/impl/commit_batch.h"

#include <lib/callback/scoped_callback.h>

namespace p2p_sync {

CommitBatch::CommitBatch(std::string device, Delegate* delegate,
                         storage::PageStorage* storage)
    : device_(std::move(device)),
      delegate_(delegate),
      storage_(storage),
      weak_factory_(this) {}

void CommitBatch::set_on_empty(fit::closure on_empty) {
  on_empty_ = std::move(on_empty);
}

void CommitBatch::AddToBatch(
    std::vector<storage::PageStorage::CommitIdAndBytes> new_commits) {
  // New commits are supposed to be the parents of the already inserted ones. We
  // insert them before to ensure parents are processed before children.
  //
  // This insertion may be suboptimal in some cases, for instance when a merge
  // commit's parents are related to each other. In that case, we may request
  // (and insert) multiple times the same commit. A better way would be to sort
  // these commits by generation before inserting, but we don't have access to
  // this information here.
  commits_.insert(commits_.begin(),
                  std::make_move_iterator(new_commits.begin()),
                  std::make_move_iterator(new_commits.end()));

  std::vector<storage::PageStorage::CommitIdAndBytes> out;
  out.reserve(commits_.size());
  for (const auto& commit : commits_) {
    out.emplace_back(commit.id, commit.bytes);
  }

  storage_->AddCommitsFromSync(
      std::move(out), storage::ChangeSource::P2P,
      callback::MakeScoped(
          weak_factory_.GetWeakPtr(),
          [this](storage::Status status,
                 std::vector<storage::CommitId> missing_ids) {
            if (status == storage::Status::OK) {
              if (on_empty_) {
                on_empty_();
              }
              return;
            }
            if (status == storage::Status::NOT_FOUND && !missing_ids.empty()) {
              delegate_->RequestCommits(device_, std::move(missing_ids));
              return;
            }
            FXL_LOG(ERROR) << "Error while adding commits, aborting batch: "
                           << status;
            if (on_empty_) {
              on_empty_();
            }
          }));
}

}  // namespace p2p_sync
