// Copyright (c) 2012 The Chromium 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 "components/sync/driver/about_sync_util.h"

#include <string>
#include <utility>
#include <vector>

#include "base/i18n/time_formatting.h"
#include "base/logging.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "base/values.h"
#include "components/sync/driver/sync_service.h"
#include "components/sync/driver/sync_token_status.h"
#include "components/sync/driver/sync_user_settings.h"
#include "components/sync/engine/cycle/sync_cycle_snapshot.h"
#include "components/sync/engine/sync_status.h"
#include "components/sync/engine/sync_string_conversions.h"
#include "components/sync/model/time.h"
#include "components/sync/protocol/proto_enum_conversions.h"
#include "url/gurl.h"

namespace syncer {

namespace sync_ui_util {

const char kIdentityTitle[] = "Identity";
const char kDetailsKey[] = "details";

// Resource paths.
const char kAboutJS[] = "about.js";
const char kChromeSyncJS[] = "chrome_sync.js";
const char kDataJS[] = "data.js";
const char kEventsJS[] = "events.js";
const char kSearchJS[] = "search.js";
const char kSyncIndexJS[] = "sync_index.js";
const char kSyncLogJS[] = "sync_log.js";
const char kSyncNodeBrowserJS[] = "sync_node_browser.js";
const char kSyncSearchJS[] = "sync_search.js";
const char kTypesJS[] = "types.js";
const char kUserEventsJS[] = "user_events.js";
const char kTrafficLogJS[] = "traffic_log.js";

// Message handlers.
const char kDispatchEvent[] = "chrome.sync.dispatchEvent";
const char kGetAllNodes[] = "getAllNodes";
const char kGetAllNodesCallback[] = "chrome.sync.getAllNodesCallback";
const char kRegisterForEvents[] = "registerForEvents";
const char kRegisterForPerTypeCounters[] = "registerForPerTypeCounters";
const char kRequestIncludeSpecificsInitialState[] =
    "requestIncludeSpecificsInitialState";
const char kRequestListOfTypes[] = "requestListOfTypes";
const char kRequestStart[] = "requestStart";
const char kRequestStopKeepData[] = "requestStopKeepData";
const char kRequestStopClearData[] = "requestStopClearData";
const char kRequestUpdatedAboutInfo[] = "requestUpdatedAboutInfo";
const char kRequestUserEventsVisibility[] = "requestUserEventsVisibility";
const char kSetIncludeSpecifics[] = "setIncludeSpecifics";
const char kTriggerRefresh[] = "triggerRefresh";
const char kUserEventsVisibilityCallback[] =
    "chrome.sync.userEventsVisibilityCallback";
const char kWriteUserEvent[] = "writeUserEvent";

// Other strings.
const char kCommit[] = "commit";
const char kCounters[] = "counters";
const char kCounterType[] = "counterType";
const char kIncludeSpecifics[] = "includeSpecifics";
const char kModelType[] = "modelType";
const char kOnAboutInfoUpdated[] = "onAboutInfoUpdated";
const char kOnCountersUpdated[] = "onCountersUpdated";
const char kOnProtocolEvent[] = "onProtocolEvent";
const char kOnReceivedIncludeSpecificsInitialState[] =
    "onReceivedIncludeSpecificsInitialState";
const char kOnReceivedListOfTypes[] = "onReceivedListOfTypes";
const char kStatus[] = "status";
const char kTypes[] = "types";
const char kUpdate[] = "update";

namespace {

const char kUninitialized[] = "Uninitialized";

// This class represents one field in about:sync. It gets serialized into a
// dictionary with entries for 'stat_name', 'stat_value' and 'is_valid'.
class StatBase {
 public:
  base::Value ToValue() const {
    base::Value result(base::Value::Type::DICTIONARY);
    result.SetKey("stat_name", base::Value(key_));
    result.SetKey("stat_value", value_.Clone());
    result.SetKey("is_valid", base::Value(is_valid_));
    return result;
  }

 protected:
  StatBase(const std::string& key, base::Value default_value)
      : key_(key), value_(std::move(default_value)) {}

  void SetFromValue(base::Value value) {
    value_ = std::move(value);
    is_valid_ = true;
  }

 private:
  std::string key_;
  base::Value value_;
  bool is_valid_ = false;
};

template <typename T>
class Stat : public StatBase {
 public:
  Stat(const std::string& key, const T& default_value)
      : StatBase(key, base::Value(default_value)) {}

  void Set(const T& value) { SetFromValue(base::Value(value)); }
};

// A section for display on about:sync, consisting of a title and a list of
// fields.
class Section {
 public:
  explicit Section(const std::string& title) : title_(title) {}

  void MarkSensitive() { is_sensitive_ = true; }

  Stat<bool>* AddBoolStat(const std::string& key) {
    return AddStat(key, false);
  }
  Stat<int>* AddIntStat(const std::string& key) { return AddStat(key, 0); }
  Stat<std::string>* AddStringStat(const std::string& key) {
    return AddStat(key, std::string(kUninitialized));
  }

  base::Value ToValue() const {
    base::Value result(base::Value::Type::DICTIONARY);
    result.SetKey("title", base::Value(title_));
    base::Value stats(base::Value::Type::LIST);
    for (const std::unique_ptr<StatBase>& stat : stats_)
      stats.GetList().push_back(stat->ToValue());
    result.SetKey("data", std::move(stats));
    result.SetKey("is_sensitive", base::Value(is_sensitive_));
    return result;
  }

 private:
  template <typename T>
  Stat<T>* AddStat(const std::string& key, const T& default_value) {
    auto stat = std::make_unique<Stat<T>>(key, default_value);
    Stat<T>* result = stat.get();
    stats_.push_back(std::move(stat));
    return result;
  }

  std::string title_;
  std::vector<std::unique_ptr<StatBase>> stats_;
  bool is_sensitive_ = false;
};

class SectionList {
 public:
  SectionList() = default;

  Section* AddSection(const std::string& title) {
    sections_.push_back(std::make_unique<Section>(title));
    return sections_.back().get();
  }

  base::Value ToValue() const {
    base::Value result(base::Value::Type::LIST);
    for (const std::unique_ptr<Section>& section : sections_)
      result.GetList().push_back(section->ToValue());
    return result;
  }

 private:
  std::vector<std::unique_ptr<Section>> sections_;
};

std::string GetDisableReasonsString(int disable_reasons) {
  if (disable_reasons == syncer::SyncService::DISABLE_REASON_NONE) {
    return "None";
  }
  std::vector<std::string> reason_strings;
  if (disable_reasons & syncer::SyncService::DISABLE_REASON_PLATFORM_OVERRIDE)
    reason_strings.push_back("Platform override");
  if (disable_reasons & syncer::SyncService::DISABLE_REASON_ENTERPRISE_POLICY)
    reason_strings.push_back("Enterprise policy");
  if (disable_reasons & syncer::SyncService::DISABLE_REASON_NOT_SIGNED_IN)
    reason_strings.push_back("Not signed in");
  if (disable_reasons & syncer::SyncService::DISABLE_REASON_USER_CHOICE)
    reason_strings.push_back("User choice");
  if (disable_reasons & syncer::SyncService::DISABLE_REASON_UNRECOVERABLE_ERROR)
    reason_strings.push_back("Unrecoverable error");
  return base::JoinString(reason_strings, ", ");
}

std::string GetTransportStateString(syncer::SyncService::TransportState state) {
  switch (state) {
    case syncer::SyncService::TransportState::DISABLED:
      return "Disabled";
    case syncer::SyncService::TransportState::WAITING_FOR_START_REQUEST:
      return "Waiting for start request";
    case syncer::SyncService::TransportState::START_DEFERRED:
      return "Start deferred";
    case syncer::SyncService::TransportState::INITIALIZING:
      return "Initializing";
    case syncer::SyncService::TransportState::PENDING_DESIRED_CONFIGURATION:
      return "Pending desired configuration";
    case syncer::SyncService::TransportState::CONFIGURING:
      return "Configuring data types";
    case syncer::SyncService::TransportState::ACTIVE:
      return "Active";
  }
  NOTREACHED();
  return std::string();
}

// Returns a string describing the chrome version environment. Version format:
// <Build Info> <OS> <Version number> (<Last change>)<channel or "-devel">
// If version information is unavailable, returns "invalid."
// TODO(zea): this approximately matches syncer::MakeUserAgentForSync in
// sync_util.h. Unify the two if possible.
std::string GetVersionString(version_info::Channel channel) {
  // Build a version string that matches syncer::MakeUserAgentForSync with the
  // addition of channel info and proper OS names.
  // chrome::GetChannelName() returns empty string for stable channel or
  // unofficial builds, the channel string otherwise. We want to have "-devel"
  // for unofficial builds only.
  std::string version_modifier = version_info::GetChannelString(channel);
  if (version_modifier.empty()) {
    if (channel != version_info::Channel::STABLE) {
      version_modifier = "-devel";
    }
  } else {
    version_modifier = " " + version_modifier;
  }
  return version_info::GetProductName() + " " + version_info::GetOSType() +
         " " + version_info::GetVersionNumber() + " (" +
         version_info::GetLastChange() + ")" + version_modifier;
}

std::string GetTimeStr(base::Time time, const std::string& default_msg) {
  if (time.is_null())
    return default_msg;
  return GetTimeDebugString(time);
}

// Analogous to GetTimeDebugString from components/sync/base/time.h. Consider
// moving it there if more places need this.
std::string GetTimeDeltaDebugString(base::TimeDelta t) {
  base::string16 result;
  if (!base::TimeDurationFormat(t, base::DURATION_WIDTH_WIDE, &result)) {
    return "Invalid TimeDelta?!";
  }
  return base::UTF16ToUTF8(result);
}

std::string GetLastSyncedTimeString(base::Time last_synced_time) {
  if (last_synced_time.is_null())
    return "Never";

  base::TimeDelta time_since_last_sync = base::Time::Now() - last_synced_time;

  if (time_since_last_sync < base::TimeDelta::FromMinutes(1))
    return "Just now";

  return GetTimeDeltaDebugString(time_since_last_sync) + " ago";
}

std::string GetConnectionStatus(const SyncTokenStatus& status) {
  switch (status.connection_status) {
    case CONNECTION_NOT_ATTEMPTED:
      return "not attempted";
    case CONNECTION_OK:
      return base::StringPrintf(
          "OK since %s",
          GetTimeStr(status.connection_status_update_time, "n/a").c_str());
    case CONNECTION_AUTH_ERROR:
      return base::StringPrintf(
          "auth error since %s",
          GetTimeStr(status.connection_status_update_time, "n/a").c_str());
    case CONNECTION_SERVER_ERROR:
      return base::StringPrintf(
          "server error since %s",
          GetTimeStr(status.connection_status_update_time, "n/a").c_str());
  }
  NOTREACHED();
  return std::string();
}

}  // namespace

// This function both defines the structure of the message to be returned and
// its contents.  Most of the message consists of simple fields in about:sync
// which are grouped into sections and populated with the help of the SyncStat
// classes defined above.
std::unique_ptr<base::DictionaryValue> ConstructAboutInformation(
    SyncService* service,
    version_info::Channel channel) {
  auto about_info = std::make_unique<base::DictionaryValue>();

  SectionList section_list;

  Section* section_summary = section_list.AddSection("Summary");
  Stat<std::string>* transport_state =
      section_summary->AddStringStat("Transport State");
  Stat<std::string>* disable_reasons =
      section_summary->AddStringStat("Disable Reasons");
  Stat<bool>* feature_enabled =
      section_summary->AddBoolStat("Sync Feature Enabled");
  Stat<bool>* setup_in_progress =
      section_summary->AddBoolStat("Setup In Progress");

  Section* section_version = section_list.AddSection("Version Info");
  Stat<std::string>* client_version =
      section_version->AddStringStat("Client Version");
  Stat<std::string>* server_url = section_version->AddStringStat("Server URL");

  Section* section_identity = section_list.AddSection(kIdentityTitle);
  section_identity->MarkSensitive();
  Stat<std::string>* sync_client_id =
      section_identity->AddStringStat("Sync Client ID");
  Stat<std::string>* invalidator_id =
      section_identity->AddStringStat("Invalidator Client ID");
  Stat<std::string>* username = section_identity->AddStringStat("Username");
  Stat<bool>* user_is_primary = section_identity->AddBoolStat("Is Primary");
  Stat<std::string>* auth_error = section_identity->AddStringStat("Auth Error");
  // TODO(treib): Add the *time* of the auth error?

  Section* section_credentials = section_list.AddSection("Credentials");
  Stat<std::string>* request_token_time =
      section_credentials->AddStringStat("Requested Token");
  Stat<std::string>* receive_token_time =
      section_credentials->AddStringStat("Received Token");
  Stat<std::string>* last_token_request_result =
      section_credentials->AddStringStat("Last Token Request Result");
  Stat<bool>* has_token = section_credentials->AddBoolStat("Has Token");
  Stat<std::string>* next_token_request =
      section_credentials->AddStringStat("Next Token Request");

  Section* section_local = section_list.AddSection("Local State");
  Stat<std::string>* server_connection =
      section_local->AddStringStat("Server Connection");
  Stat<std::string>* last_synced = section_local->AddStringStat("Last Synced");
  Stat<bool>* is_setup_complete =
      section_local->AddBoolStat("Sync First-Time Setup Complete");
  Stat<bool>* is_syncing = section_local->AddBoolStat("Sync Cycle Ongoing");
  Stat<bool>* is_local_sync_enabled =
      section_local->AddBoolStat("Local Sync Backend Enabled");
  Stat<std::string>* local_backend_path =
      section_local->AddStringStat("Local Backend Path");

  Section* section_network = section_list.AddSection("Network");
  Stat<bool>* is_any_throttled_or_backoff =
      section_network->AddBoolStat("Throttled or Backoff");
  Stat<std::string>* retry_time = section_network->AddStringStat("Retry Time");
  Stat<bool>* are_notifications_enabled =
      section_network->AddBoolStat("Notifications Enabled");

  Section* section_encryption = section_list.AddSection("Encryption");
  Stat<bool>* is_using_explicit_passphrase =
      section_encryption->AddBoolStat("Explicit Passphrase");
  Stat<bool>* is_passphrase_required =
      section_encryption->AddBoolStat("Passphrase Required");
  Stat<bool>* is_cryptographer_ready =
      section_encryption->AddBoolStat("Cryptographer Ready");
  Stat<bool>* has_pending_keys =
      section_encryption->AddBoolStat("Cryptographer Has Pending Keys");
  Stat<std::string>* encrypted_types =
      section_encryption->AddStringStat("Encrypted Types");
  Stat<bool>* has_keystore_key =
      section_encryption->AddBoolStat("Has Keystore Key");
  Stat<std::string>* keystore_migration_time =
      section_encryption->AddStringStat("Keystore Migration Time");
  Stat<std::string>* passphrase_type =
      section_encryption->AddStringStat("Passphrase Type");
  Stat<std::string>* passphrase_time =
      section_encryption->AddStringStat("Passphrase Time");

  Section* section_last_session =
      section_list.AddSection("Status from Last Completed Session");
  Stat<std::string>* session_source =
      section_last_session->AddStringStat("Sync Source");
  Stat<std::string>* get_key_result =
      section_last_session->AddStringStat("GetKey Step Result");
  Stat<std::string>* download_result =
      section_last_session->AddStringStat("Download Step Result");
  Stat<std::string>* commit_result =
      section_last_session->AddStringStat("Commit Step Result");

  Section* section_counters = section_list.AddSection("Running Totals");
  Stat<int>* notifications_received =
      section_counters->AddIntStat("Notifications Received");
  Stat<int>* updates_received =
      section_counters->AddIntStat("Updates Downloaded");
  Stat<int>* tombstone_updates =
      section_counters->AddIntStat("Tombstone Updates");
  Stat<int>* reflected_updates =
      section_counters->AddIntStat("Reflected Updates");
  Stat<int>* successful_commits =
      section_counters->AddIntStat("Successful Commits");
  Stat<int>* conflicts_resolved_local_wins =
      section_counters->AddIntStat("Conflicts Resolved: Client Wins");
  Stat<int>* conflicts_resolved_server_wins =
      section_counters->AddIntStat("Conflicts Resolved: Server Wins");

  Section* section_this_cycle =
      section_list.AddSection("Transient Counters (this cycle)");
  Stat<int>* encryption_conflicts =
      section_this_cycle->AddIntStat("Encryption Conflicts");
  Stat<int>* hierarchy_conflicts =
      section_this_cycle->AddIntStat("Hierarchy Conflicts");
  Stat<int>* server_conflicts =
      section_this_cycle->AddIntStat("Server Conflicts");
  Stat<int>* committed_items =
      section_this_cycle->AddIntStat("Committed Items");

  Section* section_that_cycle = section_list.AddSection(
      "Transient Counters (last cycle of last completed session)");
  Stat<int>* updates_downloaded =
      section_that_cycle->AddIntStat("Updates Downloaded");
  Stat<int>* committed_count =
      section_that_cycle->AddIntStat("Committed Count");
  Stat<int>* entries = section_that_cycle->AddIntStat("Entries");

  Section* section_nudge_info =
      section_list.AddSection("Nudge Source Counters");
  Stat<int>* nudge_source_notification =
      section_nudge_info->AddIntStat("Server Invalidations");
  Stat<int>* nudge_source_local =
      section_nudge_info->AddIntStat("Local Changes");
  Stat<int>* nudge_source_local_refresh =
      section_nudge_info->AddIntStat("Local Refreshes");

  // Populate all the fields we declared above.
  client_version->Set(GetVersionString(channel));

  if (!service) {
    transport_state->Set("Sync service does not exist");
    about_info->SetKey(kDetailsKey, section_list.ToValue());
    return about_info;
  }

  // Summary.
  transport_state->Set(GetTransportStateString(service->GetTransportState()));
  disable_reasons->Set(GetDisableReasonsString(service->GetDisableReasons()));
  feature_enabled->Set(service->IsSyncFeatureEnabled());
  setup_in_progress->Set(service->IsSetupInProgress());

  SyncStatus full_status;
  bool is_status_valid = service->QueryDetailedSyncStatus(&full_status);
  const SyncCycleSnapshot& snapshot = service->GetLastCycleSnapshot();
  const SyncTokenStatus& token_status = service->GetSyncTokenStatus();

  // Version Info.
  // |client_version| was already set above.
  server_url->Set(service->sync_service_url().spec());

  // Identity.
  if (is_status_valid && !full_status.sync_id.empty())
    sync_client_id->Set(full_status.sync_id);
  if (is_status_valid && !full_status.invalidator_client_id.empty())
    invalidator_id->Set(full_status.invalidator_client_id);
  username->Set(service->GetAuthenticatedAccountInfo().email);
  user_is_primary->Set(service->IsAuthenticatedAccountPrimary());
  std::string auth_error_str = service->GetAuthError().ToString();
  auth_error->Set(auth_error_str.empty() ? "None" : auth_error_str);

  // Credentials.
  request_token_time->Set(GetTimeStr(token_status.token_request_time, "n/a"));
  receive_token_time->Set(GetTimeStr(token_status.token_receive_time, "n/a"));
  std::string err = token_status.last_get_token_error.error_message();
  last_token_request_result->Set(err.empty() ? "OK" : err);
  has_token->Set(token_status.has_token);
  next_token_request->Set(
      GetTimeStr(token_status.next_token_request_time, "not scheduled"));

  // Local State.
  server_connection->Set(GetConnectionStatus(token_status));
  last_synced->Set(GetLastSyncedTimeString(service->GetLastSyncedTime()));
  is_setup_complete->Set(service->GetUserSettings()->IsFirstSetupComplete());
  if (is_status_valid)
    is_syncing->Set(full_status.syncing);
  is_local_sync_enabled->Set(service->IsLocalSyncEnabled());
  if (service->IsLocalSyncEnabled() && is_status_valid)
    local_backend_path->Set(full_status.local_sync_folder);

  // Network.
  if (snapshot.is_initialized())
    is_any_throttled_or_backoff->Set(snapshot.is_silenced());
  if (is_status_valid) {
    retry_time->Set(GetTimeStr(full_status.retry_time,
                               "Scheduler is not in backoff or throttled"));
  }
  if (is_status_valid)
    are_notifications_enabled->Set(full_status.notifications_enabled);

  // Encryption.
  if (service->IsSyncFeatureActive()) {
    is_using_explicit_passphrase->Set(service->IsUsingSecondaryPassphrase());
    is_passphrase_required->Set(service->IsPassphraseRequired());
    passphrase_time->Set(
        GetTimeStr(service->GetUserSettings()->GetExplicitPassphraseTime(),
                   "No Passphrase Time"));
  }
  if (is_status_valid) {
    is_cryptographer_ready->Set(full_status.cryptographer_ready);
    has_pending_keys->Set(full_status.crypto_has_pending_keys);
    encrypted_types->Set(ModelTypeSetToString(full_status.encrypted_types));
    has_keystore_key->Set(full_status.has_keystore_key);
    keystore_migration_time->Set(
        GetTimeStr(full_status.keystore_migration_time, "Not Migrated"));
    passphrase_type->Set(PassphraseTypeToString(full_status.passphrase_type));
  }

  // Status from Last Completed Session.
  if (snapshot.is_initialized()) {
    if (snapshot.get_updates_origin() != sync_pb::SyncEnums::UNKNOWN_ORIGIN) {
      session_source->Set(ProtoEnumToString(snapshot.get_updates_origin()));
    }
    get_key_result->Set(
        snapshot.model_neutral_state().last_get_key_result.ToString());
    download_result->Set(
        snapshot.model_neutral_state().last_download_updates_result.ToString());
    commit_result->Set(snapshot.model_neutral_state().commit_result.ToString());
  }

  // Running Totals.
  if (is_status_valid) {
    notifications_received->Set(full_status.notifications_received);
    updates_received->Set(full_status.updates_received);
    tombstone_updates->Set(full_status.tombstone_updates_received);
    reflected_updates->Set(full_status.reflected_updates_received);
    successful_commits->Set(full_status.num_commits_total);
    conflicts_resolved_local_wins->Set(full_status.num_local_overwrites_total);
    conflicts_resolved_server_wins->Set(
        full_status.num_server_overwrites_total);
  }

  // Transient Counters (this cycle).
  if (is_status_valid) {
    encryption_conflicts->Set(full_status.encryption_conflicts);
    hierarchy_conflicts->Set(full_status.hierarchy_conflicts);
    server_conflicts->Set(full_status.server_conflicts);
    committed_items->Set(full_status.committed_count);
  }

  // Transient Counters (last cycle of last completed session).
  if (snapshot.is_initialized()) {
    updates_downloaded->Set(
        snapshot.model_neutral_state().num_updates_downloaded_total);
    committed_count->Set(snapshot.model_neutral_state().num_successful_commits);
    entries->Set(static_cast<int>(snapshot.num_entries()));
  }

  // Nudge Source Counters.
  if (is_status_valid) {
    nudge_source_notification->Set(full_status.nudge_source_notification);
    nudge_source_local->Set(full_status.nudge_source_local);
    nudge_source_local_refresh->Set(full_status.nudge_source_local_refresh);
  }

  // This list of sections belongs in the 'details' field of the returned
  // message.
  about_info->SetKey(kDetailsKey, section_list.ToValue());

  // The values set from this point onwards do not belong in the
  // details list.

  // We don't need to check is_status_valid here.
  // full_status.sync_protocol_error is exported directly from the
  // ProfileSyncService, even if the backend doesn't exist.
  const bool actionable_error_detected =
      full_status.sync_protocol_error.error_type != UNKNOWN_ERROR &&
      full_status.sync_protocol_error.error_type != SYNC_SUCCESS;

  about_info->SetKey("actionable_error_detected",
                     base::Value(actionable_error_detected));

  // NOTE: We won't bother showing any of the following values unless
  // actionable_error_detected is set.

  base::Value actionable_error(base::Value::Type::LIST);
  Stat<std::string> error_type("Error Type", kUninitialized);
  Stat<std::string> action("Action", kUninitialized);
  Stat<std::string> url("URL", kUninitialized);
  Stat<std::string> description("Error Description", kUninitialized);

  if (actionable_error_detected) {
    error_type.Set(
        GetSyncErrorTypeString(full_status.sync_protocol_error.error_type));
    action.Set(GetClientActionString(full_status.sync_protocol_error.action));
    url.Set(full_status.sync_protocol_error.url);
    description.Set(full_status.sync_protocol_error.error_description);
  }

  actionable_error.GetList().push_back(error_type.ToValue());
  actionable_error.GetList().push_back(action.ToValue());
  actionable_error.GetList().push_back(url.ToValue());
  actionable_error.GetList().push_back(description.ToValue());
  about_info->SetKey("actionable_error", std::move(actionable_error));

  about_info->SetKey("unrecoverable_error_detected",
                     base::Value(service->HasUnrecoverableError()));

  if (service->HasUnrecoverableError()) {
    std::string unrecoverable_error_message =
        "Unrecoverable error detected at " +
        service->unrecoverable_error_location().ToString() + ": " +
        service->unrecoverable_error_message();
    about_info->SetKey("unrecoverable_error_message",
                       base::Value(unrecoverable_error_message));
  }

  about_info->SetKey("type_status", base::Value::FromUniquePtrValue(
                                        service->GetTypeStatusMap()));

  return about_info;
}

}  // namespace sync_ui_util

}  // namespace syncer
