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

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

#include "base/bind.h"
#include "base/logging.h"
#include "base/metrics/histogram_macros.h"
#include "base/metrics/user_metrics.h"
#include "base/strings/utf_string_conversions.h"
#include "base/values.h"
#include "base/win/registry.h"
#include "chrome/browser/conflicts/incompatible_applications_updater_win.h"
#include "chrome/browser/conflicts/registry_key_watcher_win.h"
#include "chrome/browser/conflicts/uninstall_application_win.h"
#include "chrome/grit/generated_resources.h"
#include "ui/base/l10n/l10n_util.h"

namespace settings {

IncompatibleApplicationsHandler::IncompatibleApplicationsHandler() = default;

IncompatibleApplicationsHandler::~IncompatibleApplicationsHandler() = default;

void IncompatibleApplicationsHandler::RegisterMessages() {
  web_ui()->RegisterMessageCallback(
      "requestIncompatibleApplicationsList",
      base::BindRepeating(&IncompatibleApplicationsHandler::
                              HandleRequestIncompatibleApplicationsList,
                          base::Unretained(this)));
  web_ui()->RegisterMessageCallback(
      "startApplicationUninstallation",
      base::BindRepeating(&IncompatibleApplicationsHandler::
                              HandleStartApplicationUninstallation,
                          base::Unretained(this)));
  web_ui()->RegisterMessageCallback(
      "getSubtitlePluralString",
      base::BindRepeating(
          &IncompatibleApplicationsHandler::HandleGetSubtitlePluralString,
          base::Unretained(this)));
  web_ui()->RegisterMessageCallback(
      "getSubtitleNoAdminRightsPluralString",
      base::BindRepeating(&IncompatibleApplicationsHandler::
                              HandleGetSubtitleNoAdminRightsPluralString,
                          base::Unretained(this)));
  web_ui()->RegisterMessageCallback(
      "getListTitlePluralString",
      base::BindRepeating(
          &IncompatibleApplicationsHandler::HandleGetListTitlePluralString,
          base::Unretained(this)));
}

void IncompatibleApplicationsHandler::OnJavascriptAllowed() {}

void IncompatibleApplicationsHandler::OnJavascriptDisallowed() {
  registry_key_watchers_.clear();
}

void IncompatibleApplicationsHandler::HandleRequestIncompatibleApplicationsList(
    const base::ListValue* args) {
  CHECK_EQ(1u, args->GetList().size());

  AllowJavascript();

  // Reset the registry watchers, to correctly handle repeated calls to
  // requestIncompatibleApplicationsList().
  registry_key_watchers_.clear();

  std::vector<IncompatibleApplicationsUpdater::IncompatibleApplication>
      incompatible_applications =
          IncompatibleApplicationsUpdater::GetCachedApplications();

  base::Value application_list(base::Value::Type::LIST);
  application_list.GetList().reserve(incompatible_applications.size());

  for (const auto& application : incompatible_applications) {
    // Set up a registry watcher for each problem application.
    // Since this instance owns the watcher, it is safe to use
    // base::Unretained() because the callback won't be invoked when the watcher
    // gets deleted.
    auto registry_key_watcher = RegistryKeyWatcher::Create(
        application.info.registry_root,
        application.info.registry_key_path.c_str(),
        application.info.registry_wow64_access,
        base::BindOnce(&IncompatibleApplicationsHandler::OnApplicationRemoved,
                       base::Unretained(this), application.info));

    // Only keep the watcher if it was successfully initialized. A failure here
    // is unlikely, but the worst that can happen is that the |application| will
    // not get removed from the list automatically in the Incompatible
    // Applications subpage.
    if (registry_key_watcher) {
      registry_key_watchers_.insert(
          {application.info, std::move(registry_key_watcher)});
    }

    // Also add the application to the list that is passed to the javascript.
    base::Value dict(base::Value::Type::DICTIONARY);
    dict.SetKey("name", base::Value(application.info.name));
    dict.SetKey("type",
                base::Value(application.blacklist_action->message_type()));
    dict.SetKey("url",
                base::Value(application.blacklist_action->message_url()));
    application_list.GetList().push_back(std::move(dict));
  }

  UMA_HISTOGRAM_COUNTS_100("IncompatibleApplicationsPage.NumApplications",
                           incompatible_applications.size());

  const base::Value& callback_id = args->GetList().front();
  ResolveJavascriptCallback(callback_id, application_list);
}

void IncompatibleApplicationsHandler::HandleStartApplicationUninstallation(
    const base::ListValue* args) {
  CHECK_EQ(1u, args->GetList().size());
  base::RecordAction(base::UserMetricsAction(
      "IncompatibleApplicationsPage.UninstallationStarted"));

  // Open the Apps & Settings page with the application name highlighted.
  uninstall_application::LaunchUninstallFlow(
      base::UTF8ToUTF16(args->GetList()[0].GetString()));
}

void IncompatibleApplicationsHandler::HandleGetSubtitlePluralString(
    const base::ListValue* args) {
  GetPluralString(IDS_SETTINGS_INCOMPATIBLE_APPLICATIONS_SUBPAGE_SUBTITLE,
                  args);
}

void IncompatibleApplicationsHandler::
    HandleGetSubtitleNoAdminRightsPluralString(const base::ListValue* args) {
  GetPluralString(
      IDS_SETTINGS_INCOMPATIBLE_APPLICATIONS_SUBPAGE_SUBTITLE_NO_ADMIN_RIGHTS,
      args);
}

void IncompatibleApplicationsHandler::HandleGetListTitlePluralString(
    const base::ListValue* args) {
  GetPluralString(IDS_SETTINGS_INCOMPATIBLE_APPLICATIONS_LIST_TITLE, args);
}

void IncompatibleApplicationsHandler::GetPluralString(
    int id,
    const base::ListValue* args) {
  CHECK_EQ(2U, args->GetList().size());

  const base::Value& callback_id = args->GetList()[0];
  int num_applications = args->GetList()[1].GetInt();
  DCHECK_GT(num_applications, 0);

  ResolveJavascriptCallback(
      callback_id,
      base::Value(l10n_util::GetPluralStringFUTF16(id, num_applications)));
}

void IncompatibleApplicationsHandler::OnApplicationRemoved(
    const InstalledApplications::ApplicationInfo& application) {
  base::RecordAction(base::UserMetricsAction(
      "IncompatibleApplicationsPage.ApplicationRemoved"));

  registry_key_watchers_.erase(application);
  FireWebUIListener("incompatible-application-removed",
                    base::Value(application.name));
}

}  // namespace settings
