// Copyright 2015 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 "chrome/browser/ui/webui/settings/settings_manage_profile_handler.h"

#include <utility>

#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "base/value_conversions.h"
#include "base/values.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/chrome_notification_types.h"
#include "chrome/browser/profiles/gaia_info_update_service.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/profiles/profile_attributes_entry.h"
#include "chrome/browser/profiles/profile_avatar_icon_util.h"
#include "chrome/browser/profiles/profile_manager.h"
#include "chrome/browser/profiles/profile_metrics.h"
#include "chrome/browser/profiles/profile_shortcut_manager.h"
#include "chrome/browser/profiles/profile_window.h"
#include "chrome/browser/profiles/profiles_state.h"
#include "chrome/browser/ui/browser_finder.h"
#include "chrome/common/pref_names.h"
#include "chrome/common/url_constants.h"
#include "chrome/grit/generated_resources.h"
#include "components/prefs/pref_service.h"
#include "components/prefs/scoped_user_pref_update.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/notification_service.h"
#include "content/public/browser/web_ui.h"
#include "google_apis/gaia/gaia_auth_util.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/webui/web_ui_util.h"

namespace settings {

namespace {

const char kProfileShortcutSettingHidden[] = "profileShortcutSettingHidden";
const char kProfileShortcutFound[] = "profileShortcutFound";
const char kProfileShortcutNotFound[] = "profileShortcutNotFound";

}  // namespace

ManageProfileHandler::ManageProfileHandler(Profile* profile)
    : profile_(profile), observer_(this), weak_factory_(this) {}

ManageProfileHandler::~ManageProfileHandler() {}

void ManageProfileHandler::RegisterMessages() {
  web_ui()->RegisterMessageCallback(
      "getAvailableIcons",
      base::BindRepeating(&ManageProfileHandler::HandleGetAvailableIcons,
                          base::Unretained(this)));
  web_ui()->RegisterMessageCallback(
      "setProfileIconToGaiaAvatar",
      base::BindRepeating(
          &ManageProfileHandler::HandleSetProfileIconToGaiaAvatar,
          base::Unretained(this)));
  web_ui()->RegisterMessageCallback(
      "setProfileIconToDefaultAvatar",
      base::BindRepeating(
          &ManageProfileHandler::HandleSetProfileIconToDefaultAvatar,
          base::Unretained(this)));
  web_ui()->RegisterMessageCallback(
      "setProfileName",
      base::BindRepeating(&ManageProfileHandler::HandleSetProfileName,
                          base::Unretained(this)));
  web_ui()->RegisterMessageCallback(
      "requestProfileShortcutStatus",
      base::BindRepeating(
          &ManageProfileHandler::HandleRequestProfileShortcutStatus,
          base::Unretained(this)));
  web_ui()->RegisterMessageCallback(
      "addProfileShortcut",
      base::BindRepeating(&ManageProfileHandler::HandleAddProfileShortcut,
                          base::Unretained(this)));
  web_ui()->RegisterMessageCallback(
      "removeProfileShortcut",
      base::BindRepeating(&ManageProfileHandler::HandleRemoveProfileShortcut,
                          base::Unretained(this)));
}

void ManageProfileHandler::OnJavascriptAllowed() {
  observer_.Add(
      &g_browser_process->profile_manager()->GetProfileAttributesStorage());
}

void ManageProfileHandler::OnJavascriptDisallowed() {
  observer_.RemoveAll();
}

void ManageProfileHandler::OnProfileHighResAvatarLoaded(
    const base::FilePath& profile_path) {
  // GAIA image is loaded asynchronously.
  FireWebUIListener("available-icons-changed", *GetAvailableIcons());
}

void ManageProfileHandler::OnProfileAvatarChanged(
    const base::FilePath& profile_path) {
  // This is necessary to send the potentially updated GAIA photo.
  FireWebUIListener("available-icons-changed", *GetAvailableIcons());
}

void ManageProfileHandler::HandleGetAvailableIcons(
    const base::ListValue* args) {
  AllowJavascript();

  profiles::UpdateGaiaProfileInfoIfNeeded(profile_);

  CHECK_EQ(1U, args->GetSize());
  const base::Value* callback_id;
  CHECK(args->Get(0, &callback_id));
  ResolveJavascriptCallback(*callback_id, *GetAvailableIcons());
}

std::unique_ptr<base::ListValue> ManageProfileHandler::GetAvailableIcons() {
  PrefService* pref_service = profile_->GetPrefs();
  bool using_gaia = pref_service->GetBoolean(prefs::kProfileUsingGAIAAvatar);
  size_t selected_avatar_idx =
      using_gaia ? SIZE_MAX
                 : pref_service->GetInteger(prefs::kProfileAvatarIndex);

  // Obtain a list of the default avatar icons.
  std::unique_ptr<base::ListValue> avatars(
      profiles::GetDefaultProfileAvatarIconsAndLabels(selected_avatar_idx));

  // Add the GAIA picture to the beginning of the list if it is available.
  ProfileAttributesEntry* entry;
  if (g_browser_process->profile_manager()->GetProfileAttributesStorage().
          GetProfileAttributesWithPath(profile_->GetPath(), &entry)) {
    const gfx::Image* icon = entry->GetGAIAPicture();
    if (icon) {
      auto gaia_picture_info = std::make_unique<base::DictionaryValue>();
      gfx::Image avatar_icon = profiles::GetAvatarIconForWebUI(*icon, true);
      gaia_picture_info->SetString(
          "url", webui::GetBitmapDataUrl(avatar_icon.AsBitmap()));
      gaia_picture_info->SetString(
          "label",
          l10n_util::GetStringUTF16(IDS_SETTINGS_CHANGE_PICTURE_PROFILE_PHOTO));
      gaia_picture_info->SetBoolean("isGaiaAvatar", true);
      if (using_gaia)
        gaia_picture_info->SetBoolean("selected", true);
      avatars->Insert(0, std::move(gaia_picture_info));
    }
  }

  return avatars;
}

void ManageProfileHandler::HandleSetProfileIconToGaiaAvatar(
    const base::ListValue* /* args */) {
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);

  PrefService* pref_service = profile_->GetPrefs();
  bool previously_using_gaia_icon =
      pref_service->GetBoolean(prefs::kProfileUsingGAIAAvatar);

  pref_service->SetBoolean(prefs::kProfileUsingDefaultAvatar, false);
  pref_service->SetBoolean(prefs::kProfileUsingGAIAAvatar, true);
  if (!previously_using_gaia_icon) {
    // Only log if they changed to the GAIA photo.
    // Selection of GAIA photo as avatar is logged as part of the function
    // below.
    ProfileMetrics::LogProfileSwitchGaia(ProfileMetrics::GAIA_OPT_IN);
  }

  ProfileMetrics::LogProfileUpdate(profile_->GetPath());
}

void ManageProfileHandler::HandleSetProfileIconToDefaultAvatar(
    const base::ListValue* args) {
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
  DCHECK(args);
  DCHECK_EQ(1u, args->GetSize());

  std::string icon_url;
  CHECK(args->GetString(0, &icon_url));

  size_t new_icon_index = 0;
  CHECK(profiles::IsDefaultAvatarIconUrl(icon_url, &new_icon_index));

  PrefService* pref_service = profile_->GetPrefs();
  pref_service->SetInteger(prefs::kProfileAvatarIndex, new_icon_index);
  pref_service->SetBoolean(prefs::kProfileUsingDefaultAvatar, false);
  pref_service->SetBoolean(prefs::kProfileUsingGAIAAvatar, false);

  ProfileMetrics::LogProfileAvatarSelection(new_icon_index);
  ProfileMetrics::LogProfileUpdate(profile_->GetPath());
}

void ManageProfileHandler::HandleSetProfileName(const base::ListValue* args) {
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
  DCHECK(args);
  DCHECK_EQ(1u, args->GetSize());

  if (profile_->IsLegacySupervised())
    return;

  base::string16 new_profile_name;
  CHECK(args->GetString(0, &new_profile_name));

  base::TrimWhitespace(new_profile_name, base::TRIM_ALL, &new_profile_name);
  CHECK(!new_profile_name.empty());
  profiles::UpdateProfileName(profile_, new_profile_name);

  ProfileMetrics::LogProfileUpdate(profile_->GetPath());
}

void ManageProfileHandler::HandleRequestProfileShortcutStatus(
    const base::ListValue* args) {
  AllowJavascript();
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
  DCHECK(ProfileShortcutManager::IsFeatureEnabled());

  CHECK_EQ(1U, args->GetSize());
  std::string callback_id;
  CHECK(args->GetString(0, &callback_id));

  // Don't show the add/remove desktop shortcut button in the single user case.
  ProfileAttributesStorage& storage =
      g_browser_process->profile_manager()->GetProfileAttributesStorage();
  if (storage.GetNumberOfProfiles() <= 1u) {
    ResolveJavascriptCallback(base::Value(callback_id),
                              base::Value(kProfileShortcutSettingHidden));
    return;
  }

  ProfileShortcutManager* shortcut_manager =
      g_browser_process->profile_manager()->profile_shortcut_manager();
  DCHECK(shortcut_manager);
  shortcut_manager->HasProfileShortcuts(
      profile_->GetPath(),
      base::Bind(&ManageProfileHandler::OnHasProfileShortcuts,
                 weak_factory_.GetWeakPtr(), callback_id));
}

void ManageProfileHandler::OnHasProfileShortcuts(
    const std::string& callback_id, bool has_shortcuts) {
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
  ResolveJavascriptCallback(
      base::Value(callback_id),
      base::Value(has_shortcuts ? kProfileShortcutFound
                                : kProfileShortcutNotFound));
}

void ManageProfileHandler::HandleAddProfileShortcut(
    const base::ListValue* args) {
  DCHECK(ProfileShortcutManager::IsFeatureEnabled());
  ProfileShortcutManager* shortcut_manager =
      g_browser_process->profile_manager()->profile_shortcut_manager();
  DCHECK(shortcut_manager);

  shortcut_manager->CreateProfileShortcut(profile_->GetPath());
}

void ManageProfileHandler::HandleRemoveProfileShortcut(
    const base::ListValue* args) {
  DCHECK(ProfileShortcutManager::IsFeatureEnabled());
  ProfileShortcutManager* shortcut_manager =
    g_browser_process->profile_manager()->profile_shortcut_manager();
  DCHECK(shortcut_manager);

  shortcut_manager->RemoveProfileShortcuts(profile_->GetPath());
}

}  // namespace settings
