// Copyright 2012 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.h"

#include <utility>

#include "base/logging.h"
#include "base/metrics/histogram_macros.h"
#include "base/notreached.h"
#include "base/rand_util.h"
#include "base/trace_event/trace_event.h"
#include "components/sync/base/data_type_histogram.h"
#include "components/sync/engine/active_devices_invalidation_info.h"
#include "components/sync/engine/commit_processor.h"
#include "components/sync/engine/commit_util.h"
#include "components/sync/engine/cycle/sync_cycle.h"
#include "components/sync/engine/events/commit_request_event.h"
#include "components/sync/engine/events/commit_response_event.h"
#include "components/sync/engine/syncer.h"
#include "components/sync/engine/syncer_proto_util.h"

namespace syncer {

namespace {

// The number of random ASCII bytes we'll add to CommitMessage. We choose 256
// because it is not too large (to hurt performance and compression ratio), but
// it is not too small to easily be canceled out using statistical analysis.
const size_t kPaddingSize = 256;

std::string RandASCIIString(size_t length) {
  std::string result;
  const int kMin = static_cast<int>(' ');
  const int kMax = static_cast<int>('~');
  result.reserve(length);
  for (size_t i = 0; i < length; ++i)
    result.push_back(static_cast<char>(base::RandInt(kMin, kMax)));
  return result;
}

SyncCommitError GetSyncCommitError(SyncerError syncer_error) {
  switch (syncer_error.value()) {
    case SyncerError::UNSET:
    case SyncerError::SYNCER_OK:
      NOTREACHED();
      break;
    case SyncerError::NETWORK_CONNECTION_UNAVAILABLE:
    case SyncerError::NETWORK_IO_ERROR:
      return SyncCommitError::kNetworkError;
    case SyncerError::SYNC_AUTH_ERROR:
      return SyncCommitError::kAuthError;
    case SyncerError::SYNC_SERVER_ERROR:
    case SyncerError::SERVER_RETURN_UNKNOWN_ERROR:
    case SyncerError::SERVER_RETURN_THROTTLED:
    case SyncerError::SERVER_RETURN_TRANSIENT_ERROR:
    case SyncerError::SERVER_RETURN_MIGRATION_DONE:
    case SyncerError::SERVER_RETURN_CLEAR_PENDING:
    case SyncerError::SERVER_RETURN_NOT_MY_BIRTHDAY:
    case SyncerError::SERVER_RETURN_CONFLICT:
    case SyncerError::SERVER_RETURN_CLIENT_DATA_OBSOLETE:
    case SyncerError::SERVER_RETURN_ENCRYPTION_OBSOLETE:
    case SyncerError::SERVER_RETURN_DISABLED_BY_ADMIN:
      return SyncCommitError::kServerError;
    case SyncerError::SERVER_RESPONSE_VALIDATION_FAILED:
      return SyncCommitError::kBadServerResponse;
  }

  NOTREACHED();
  return SyncCommitError::kServerError;
}

}  // namespace

Commit::Commit(ContributionMap contributions,
               const sync_pb::ClientToServerMessage& message,
               ExtensionsActivity::Records extensions_activity_buffer)
    : contributions_(std::move(contributions)),
      message_(message),
      extensions_activity_buffer_(extensions_activity_buffer) {}

Commit::~Commit() = default;

// static
std::unique_ptr<Commit> Commit::Init(
    ModelTypeSet enabled_types,
    bool proxy_tabs_datatype_enabled,
    size_t max_entries,
    const std::string& account_name,
    const std::string& cache_guid,
    bool cookie_jar_mismatch,
    const ActiveDevicesInvalidationInfo& active_devices_invalidation_info,
    CommitProcessor* commit_processor,
    ExtensionsActivity* extensions_activity) {
  // Gather per-type contributions.
  ContributionMap contributions =
      commit_processor->GatherCommitContributions(max_entries);

  // Give up if no one had anything to commit.
  if (contributions.empty())
    return nullptr;

  sync_pb::ClientToServerMessage message;
  message.set_message_contents(sync_pb::ClientToServerMessage::COMMIT);
  message.set_share(account_name);

  sync_pb::CommitMessage* commit_message = message.mutable_commit();
  commit_message->set_cache_guid(cache_guid);

  // Set padding to mitigate CRIME attack.
  commit_message->set_padding(RandASCIIString(kPaddingSize));

  // Set extensions activity if bookmark commits are present.
  ExtensionsActivity::Records extensions_activity_buffer;
  if (extensions_activity != nullptr) {
    ContributionMap::const_iterator it = contributions.find(BOOKMARKS);
    if (it != contributions.end() && it->second->GetNumEntries() != 0) {
      commit_util::AddExtensionsActivityToMessage(
          extensions_activity, &extensions_activity_buffer, commit_message);
    }
  }

  ModelTypeSet contributed_data_types;
  for (const auto& [type, contribution] : contributions) {
    contributed_data_types.Put(type);
  }

  // Set the client config params.
  commit_util::AddClientConfigParamsToMessage(
      enabled_types, proxy_tabs_datatype_enabled, cookie_jar_mismatch,
      active_devices_invalidation_info.IsSingleClientForTypes(
          contributed_data_types),
      active_devices_invalidation_info
          .IsSingleClientWithStandaloneInvalidationsForTypes(
              contributed_data_types),
      active_devices_invalidation_info
          .IsSingleClientWithOldInvalidationsForTypes(contributed_data_types),
      active_devices_invalidation_info.all_fcm_registration_tokens(),
      active_devices_invalidation_info
          .GetFcmRegistrationTokensForInterestedClients(contributed_data_types),
      commit_message);

  // Finally, serialize all our contributions.
  for (const auto& contribution : contributions) {
    contribution.second->AddToCommitMessage(&message);
  }

  // If we made it this far, then we've successfully prepared a commit message.
  return std::make_unique<Commit>(std::move(contributions), message,
                                  extensions_activity_buffer);
}

SyncerError Commit::PostAndProcessResponse(
    NudgeTracker* nudge_tracker,
    SyncCycle* cycle,
    StatusController* status,
    ExtensionsActivity* extensions_activity) {
  ModelTypeSet request_types;
  for (const auto& [request_type, contribution] : contributions_) {
    request_types.Put(request_type);
    UMA_HISTOGRAM_ENUMERATION("Sync.PostedDataTypeCommitRequest",
                              ModelTypeHistogramValue(request_type));
  }

  if (cycle->context()->debug_info_getter()) {
    *message_.mutable_debug_info() =
        cycle->context()->debug_info_getter()->GetDebugInfo();
  }

  DVLOG(1) << "Sending commit message.";
  SyncerProtoUtil::AddRequiredFieldsToClientToServerMessage(cycle, &message_);

  CommitRequestEvent request_event(base::Time::Now(),
                                   message_.commit().entries_size(),
                                   request_types, message_);
  cycle->SendProtocolEvent(request_event);

  TRACE_EVENT_BEGIN0("sync", "PostCommit");
  sync_pb::ClientToServerResponse response;
  const SyncerError post_result = SyncerProtoUtil::PostClientToServerMessage(
      message_, &response, cycle, nullptr);
  TRACE_EVENT_END0("sync", "PostCommit");

  // TODO(rlarocque): Use result that includes errors captured later?
  CommitResponseEvent response_event(base::Time::Now(), post_result, response);
  cycle->SendProtocolEvent(response_event);

  if (post_result.value() != SyncerError::SYNCER_OK) {
    LOG(WARNING) << "Post commit failed";
    ReportFullCommitFailure(post_result);
    return post_result;
  }

  if (!response.has_commit()) {
    LOG(WARNING) << "Commit response has no commit body!";
    const SyncerError syncer_error(
        SyncerError::SERVER_RESPONSE_VALIDATION_FAILED);
    ReportFullCommitFailure(syncer_error);
    return syncer_error;
  }

  size_t message_entries = message_.commit().entries_size();
  size_t response_entries = response.commit().entryresponse_size();
  if (message_entries != response_entries) {
    LOG(ERROR) << "Commit response has wrong number of entries! "
               << "Expected: " << message_entries << ", "
               << "Got: " << response_entries;
    const SyncerError syncer_error(
        SyncerError::SERVER_RESPONSE_VALIDATION_FAILED);
    ReportFullCommitFailure(syncer_error);
    return syncer_error;
  }

  if (cycle->context()->debug_info_getter()) {
    // Clear debug info now that we have successfully sent it to the server.
    DVLOG(1) << "Clearing client debug info.";
    cycle->context()->debug_info_getter()->ClearDebugInfo();
  }

  // Let the contributors process the responses to each of their requests.
  SyncerError processing_result = SyncerError(SyncerError::SYNCER_OK);
  for (const auto& [type, contributions] : contributions_) {
    const char* model_type_str = ModelTypeToDebugString(type);
    TRACE_EVENT1("sync", "ProcessCommitResponse", "type", model_type_str);
    SyncerError type_result =
        contributions->ProcessCommitResponse(response, status);
    if (type_result.value() == SyncerError::SERVER_RETURN_CONFLICT) {
      nudge_tracker->RecordCommitConflict(type);
    }
    if (processing_result.value() == SyncerError::SYNCER_OK &&
        type_result.value() != SyncerError::SYNCER_OK) {
      processing_result = type_result;
    }
  }

  // Handle bookmarks' special extensions activity stats.
  if (extensions_activity != nullptr &&
      cycle->status_controller()
              .model_neutral_state()
              .num_successful_bookmark_commits == 0) {
    extensions_activity->PutRecords(extensions_activity_buffer_);
  }

  return processing_result;
}

ModelTypeSet Commit::GetContributingDataTypes() const {
  ModelTypeSet contributed_data_types;
  for (const auto& [model_type, contribution] : contributions_) {
    contributed_data_types.Put(model_type);
  }
  return contributed_data_types;
}

void Commit::ReportFullCommitFailure(SyncerError syncer_error) {
  const SyncCommitError commit_error = GetSyncCommitError(syncer_error);
  for (auto& [model_type, contribution] : contributions_) {
    contribution->ProcessCommitFailure(commit_error);
  }
}

}  // namespace syncer
