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

#include "chrome/browser/devtools/devtools_settings.h"

#include "base/strings/to_string.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/common/pref_names.h"
#include "components/prefs/scoped_user_pref_update.h"

const char DevToolsSettings::kSyncDevToolsPreferencesFrontendName[] =
    "sync-preferences";
const bool DevToolsSettings::kSyncDevToolsPreferencesDefault = false;

DevToolsSettings::DevToolsSettings(Profile* profile) : profile_(profile) {
  pref_change_registrar_.Init(profile_->GetPrefs());
  pref_change_registrar_.Add(
      prefs::kDevToolsSyncPreferences,
      base::BindRepeating(&DevToolsSettings::DevToolsSyncPreferencesChanged,
                          base::Unretained(this)));
}

DevToolsSettings::~DevToolsSettings() = default;

void DevToolsSettings::Register(const std::string& name,
                                const RegisterOptions& options) {
  // kSyncDevToolsPreferenceFrontendName is not stored in any of the relevant
  // dictionaries. Skip registration.
  if (name == kSyncDevToolsPreferencesFrontendName)
    return;

  if (options.sync_mode == RegisterOptions::SyncMode::kSync) {
    synced_setting_names_.insert(name);
  }

  // Setting might have had a different sync status in the past. Move the
  // setting to the correct dictionary.
  PrefService* prefs = profile_->GetPrefs();
  const char* dictionary_to_remove_from =
      options.sync_mode == RegisterOptions::SyncMode::kSync
          ? prefs::kDevToolsPreferences
          : GetDictionaryNameForSyncedPrefs();
  const std::string* settings_value =
      prefs->GetDict(dictionary_to_remove_from).FindString(name);
  if (!settings_value) {
    return;
  }

  const char* dictionary_to_insert_into =
      GetDictionaryNameForSettingsName(name);
  // Settings already moved to the synced dictionary on a different device have
  // precedence.
  const std::string* already_synced_value =
      prefs->GetDict(dictionary_to_insert_into).FindString(name);
  if (dictionary_to_insert_into == prefs::kDevToolsPreferences ||
      !already_synced_value) {
    ScopedDictPrefUpdate insert_update(profile_->GetPrefs(),
                                       dictionary_to_insert_into);
    insert_update->Set(name, *settings_value);
  }

  ScopedDictPrefUpdate remove_update(profile_->GetPrefs(),
                                     dictionary_to_remove_from);
  remove_update->Remove(name);
}

base::Value::Dict DevToolsSettings::Get() {
  base::Value::Dict settings;

  PrefService* prefs = profile_->GetPrefs();
  // DevTools expects any kind of preference to be a string. Parsing is
  // happening on the frontend.
  settings.Set(
      kSyncDevToolsPreferencesFrontendName,
      base::ToString(prefs->GetBoolean(prefs::kDevToolsSyncPreferences)));
  settings.Merge(prefs->GetDict(prefs::kDevToolsPreferences).Clone());
  settings.Merge(prefs->GetDict(GetDictionaryNameForSyncedPrefs()).Clone());

  return settings;
}

std::optional<base::Value> DevToolsSettings::Get(const std::string& name) {
  PrefService* prefs = profile_->GetPrefs();
  if (name == kSyncDevToolsPreferencesFrontendName) {
    // DevTools expects any kind of preference to be a string. Parsing is
    // happening on the frontend.
    bool result = prefs->GetBoolean(prefs::kDevToolsSyncPreferences);
    return base::Value(base::ToString(result));
  }
  const char* dict_name = GetDictionaryNameForSettingsName(name);
  const base::Value::Dict& dict = prefs->GetDict(dict_name);
  const base::Value* value = dict.Find(name);
  return value ? std::optional<base::Value>(value->Clone()) : std::nullopt;
}

void DevToolsSettings::Set(const std::string& name, const std::string& value) {
  if (name == kSyncDevToolsPreferencesFrontendName) {
    profile_->GetPrefs()->SetBoolean(prefs::kDevToolsSyncPreferences,
                                     value == "true");
    return;
  }

  ScopedDictPrefUpdate update(profile_->GetPrefs(),
                              GetDictionaryNameForSettingsName(name));
  update->Set(name, value);
}

void DevToolsSettings::Remove(const std::string& name) {
  if (name == kSyncDevToolsPreferencesFrontendName) {
    profile_->GetPrefs()->SetBoolean(prefs::kDevToolsSyncPreferences,
                                     kSyncDevToolsPreferencesDefault);
    return;
  }

  PrefService* prefs = profile_->GetPrefs();
  for (auto* dict_name :
       {GetDictionaryNameForSyncedPrefs(), prefs::kDevToolsPreferences}) {
    const base::Value::Dict& dict = prefs->GetDict(dict_name);
    if (dict.Find(name)) {
      ScopedDictPrefUpdate update(profile_->GetPrefs(), dict_name);
      update->Remove(name);
    }
  }
}

void DevToolsSettings::Clear() {
  profile_->GetPrefs()->SetBoolean(prefs::kDevToolsSyncPreferences,
                                   kSyncDevToolsPreferencesDefault);
  profile_->GetPrefs()->SetDict(prefs::kDevToolsPreferences,
                                base::Value::Dict());
  profile_->GetPrefs()->SetDict(prefs::kDevToolsSyncedPreferencesSyncEnabled,
                                base::Value::Dict());
  profile_->GetPrefs()->SetDict(prefs::kDevToolsSyncedPreferencesSyncDisabled,
                                base::Value::Dict());
}

const char* DevToolsSettings::GetDictionaryNameForSettingsName(
    const std::string& name) const {
  return synced_setting_names_.contains(name)
             ? GetDictionaryNameForSyncedPrefs()
             : prefs::kDevToolsPreferences;
}

const char* DevToolsSettings::GetDictionaryNameForSyncedPrefs() const {
  const bool isDevToolsSyncEnabled =
      profile_->GetPrefs()->GetBoolean(prefs::kDevToolsSyncPreferences);
  return isDevToolsSyncEnabled ? prefs::kDevToolsSyncedPreferencesSyncEnabled
                               : prefs::kDevToolsSyncedPreferencesSyncDisabled;
}

void DevToolsSettings::DevToolsSyncPreferencesChanged() {
  // There are two cases to handle:
  //
  // Sync was enabled: We assume this was triggered by the user in the local
  // DevTools session as opposed to synced from a different device. As such, the
  // local settings have precedence when merging. The unsynced dictonary is
  // cleared.
  //
  // Sync was disabled: As kDevToolsSyncPreferences is synced itself we can
  // clear the synced dictionary after copying to the unsynced one. The unsynced
  // dictionary is empty.
  //
  // Considering the points above, the implementation between both cases can be
  // shared modulo the source/target dictionary.
  const bool sync_enabled =
      profile_->GetPrefs()->GetBoolean(prefs::kDevToolsSyncPreferences);
  const char* target_dictionary =
      sync_enabled ? prefs::kDevToolsSyncedPreferencesSyncEnabled
                   : prefs::kDevToolsSyncedPreferencesSyncDisabled;
  const char* source_dictionary =
      sync_enabled ? prefs::kDevToolsSyncedPreferencesSyncDisabled
                   : prefs::kDevToolsSyncedPreferencesSyncEnabled;

  ScopedDictPrefUpdate source_update(profile_->GetPrefs(), source_dictionary);
  ScopedDictPrefUpdate target_update(profile_->GetPrefs(), target_dictionary);
  base::Value::Dict source_dict;
  std::swap(source_dict, *source_update);
  target_update->Merge(std::move(source_dict));
}
