// Copyright 2014 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "components/sync/engine/commit_processor.h"

#include <map>
#include <memory>
#include <utility>

#include "base/logging.h"
#include "base/notreached.h"
#include "components/sync/engine/commit_contribution.h"
#include "components/sync/engine/commit_contributor.h"

namespace syncer {

using TypeToIndexMap = std::map<ModelType, size_t>;

CommitProcessor::CommitProcessor(ModelTypeSet commit_types,
                                 CommitContributorMap* commit_contributor_map)
    : commit_types_(commit_types),
      commit_contributor_map_(commit_contributor_map),
      phase_(GatheringPhase::kHighPriority) {
  // NIGORI contributions must be collected in every commit cycle.
  DCHECK(commit_types_.Has(NIGORI));
  DCHECK(commit_contributor_map);
}

CommitProcessor::~CommitProcessor() = default;

Commit::ContributionMap CommitProcessor::GatherCommitContributions(
    size_t max_entries) {
  DCHECK_GT(max_entries, 0u);
  if (phase_ == GatheringPhase::kDone) {
    return Commit::ContributionMap();
  }

  Commit::ContributionMap contributions;

  // NIGORI contributions are always gathered to make sure that no encrypted
  // data gets committed before the corresponding NIGORI commit, which can
  // otherwise lead to data loss if the commit fails partially.
  if (GatherCommitContributionsForType(NIGORI, max_entries, &contributions) >
      0) {
    // Encryptable entities cannot get combined in the same commit with NIGORI.
    // NIGORI commits are rare so to keep it simple and to play it safe, the
    // processor does not combine any other entities with NIGORI.
    return contributions;
  }

  size_t num_entries = 0;
  do {
    num_entries += GatherCommitContributionsForTypes(
        GetUserTypesForCurrentCommitPhase(), max_entries - num_entries,
        &contributions);
    DCHECK_LE(num_entries, max_entries);
    if (num_entries < max_entries) {
      // Move to the next phase because there are no further commit
      // contributions for this phase at this moment (as there's still capacity
      // left). Even if new contributions for this phase appear while this
      // commit is in flight, they will get ignored until the next nudge. This
      // prevents infinite commit cycles.
      phase_ = IncrementGatheringPhase(phase_);
    }
  } while (phase_ != GatheringPhase::kDone && num_entries < max_entries);

  return contributions;
}

// static
CommitProcessor::GatheringPhase CommitProcessor::IncrementGatheringPhase(
    GatheringPhase phase) {
  switch (phase) {
    case GatheringPhase::kHighPriority:
      return GatheringPhase::kRegular;
    case GatheringPhase::kRegular:
      return GatheringPhase::kLowPriority;
    case GatheringPhase::kLowPriority:
      return GatheringPhase::kDone;
    case GatheringPhase::kDone:
      NOTREACHED();
      return GatheringPhase::kDone;
  }
}

ModelTypeSet CommitProcessor::GetUserTypesForCurrentCommitPhase() const {
  switch (phase_) {
    case GatheringPhase::kHighPriority:
      return Intersection(commit_types_, HighPriorityUserTypes());
    case GatheringPhase::kRegular:
      return Difference(commit_types_, Union(Union(HighPriorityUserTypes(),
                                                   LowPriorityUserTypes()),
                                             ModelTypeSet(NIGORI)));
    case GatheringPhase::kLowPriority:
      return Intersection(commit_types_, LowPriorityUserTypes());
    case GatheringPhase::kDone:
      NOTREACHED();
      return ModelTypeSet();
  }
}

size_t CommitProcessor::GatherCommitContributionsForType(
    ModelType type,
    size_t max_entries,
    Commit::ContributionMap* contributions) {
  if (max_entries == 0) {
    return 0;
  }
  auto cm_it = commit_contributor_map_->find(type);
  if (cm_it == commit_contributor_map_->end()) {
    DLOG(ERROR) << "Could not find requested type "
                << ModelTypeToDebugString(type) << " in contributor map.";
    return 0;
  }

  std::unique_ptr<CommitContribution> contribution =
      cm_it->second->GetContribution(max_entries);
  if (!contribution) {
    return 0;
  }

  size_t num_entries = contribution->GetNumEntries();
  DCHECK_LE(num_entries, max_entries);
  contributions->emplace(type, std::move(contribution));

  return num_entries;
}

size_t CommitProcessor::GatherCommitContributionsForTypes(
    ModelTypeSet types,
    size_t max_entries,
    Commit::ContributionMap* contributions) {
  size_t num_entries = 0;
  for (ModelType type : types) {
    num_entries += GatherCommitContributionsForType(
        type, max_entries - num_entries, contributions);
    if (num_entries >= max_entries) {
      DCHECK_EQ(num_entries, max_entries)
          << "Number of commit entries exceeds maximum";
      break;
    }
  }
  return num_entries;
}

}  // namespace syncer
