// 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 "chrome/browser/shell_integration.h"

#include <utility>

#include "base/command_line.h"
#include "base/files/file_util.h"
#include "base/functional/bind.h"
#include "base/i18n/file_util_icu.h"
#include "base/metrics/histogram_macros.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "base/task/lazy_thread_pool_task_runner.h"
#include "base/task/single_thread_task_runner_thread_mode.h"
#include "base/task/task_traits.h"
#include "base/threading/scoped_blocking_call.h"
#include "build/branding_buildflags.h"
#include "build/build_config.h"
#include "chrome/browser/policy/policy_path_parser.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/chrome_switches.h"
#include "components/prefs/pref_service.h"
#include "components/version_info/version_info.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/common/content_switches.h"

#if BUILDFLAG(IS_CHROMEOS)
#include "ash/constants/ash_switches.h"
#endif

#if BUILDFLAG(IS_WIN)
#include "base/win/windows_version.h"
#include "chrome/browser/shell_integration_win.h"
#include "chrome/installer/util/shell_util.h"
#endif

#if !BUILDFLAG(IS_WIN)
#include "chrome/common/channel_info.h"
#include "chrome/grit/branded_strings.h"
#include "ui/base/l10n/l10n_util.h"
#endif

using content::BrowserThread;

namespace shell_integration {

namespace {

// TODO(crbug.com/40544199): Remove |g_sequenced_task_runner| and use an
// instance field / singleton instead.
#if BUILDFLAG(IS_WIN)
base::LazyThreadPoolCOMSTATaskRunner g_sequenced_task_runner =
    LAZY_COM_STA_TASK_RUNNER_INITIALIZER(
        base::TaskTraits(base::MayBlock()),
        base::SingleThreadTaskRunnerThreadMode::SHARED);
#else
base::LazyThreadPoolSequencedTaskRunner g_sequenced_task_runner =
    LAZY_THREAD_POOL_SEQUENCED_TASK_RUNNER_INITIALIZER(
        base::TaskTraits(base::MayBlock()));
#endif

bool IsValidDefaultWebClientState(DefaultWebClientState state) {
  switch (state) {
    case NOT_DEFAULT:
    case IS_DEFAULT:
    case UNKNOWN_DEFAULT:
    case OTHER_MODE_IS_DEFAULT:
      return true;
    case NUM_DEFAULT_STATES:
      break;
  }
  NOTREACHED();
}

void RunCallback(DefaultWebClientWorkerCallback callback,
                 DefaultWebClientState state) {
  if (!callback.is_null() && IsValidDefaultWebClientState(state)) {
    std::move(callback).Run(state);
    return;
  }
}

DefaultWebClientSetPermission GetDefaultWebClientSetPermission(
    internal::WebClientSetMethod method) {
#if BUILDFLAG(CHROME_FOR_TESTING)
  return SET_DEFAULT_NOT_ALLOWED;
#else
  return internal::GetPlatformSpecificDefaultWebClientSetPermission(method);
#endif
}

}  // namespace

DefaultWebClientSetPermission GetDefaultBrowserSetPermission() {
  return GetDefaultWebClientSetPermission(
      internal::WebClientSetMethod::kDefaultBrowser);
}

DefaultWebClientSetPermission GetDefaultSchemeClientSetPermission() {
  return GetDefaultWebClientSetPermission(
      internal::WebClientSetMethod::kDefaultSchemeHandler);
}

bool CanSetAsDefaultBrowser() {
  return GetDefaultBrowserSetPermission() != SET_DEFAULT_NOT_ALLOWED;
}

base::CommandLine CommandLineArgsForLauncher(
    const GURL& url,
    const std::string& extension_app_id,
    const base::FilePath& profile_path,
    const std::string& run_on_os_login_mode) {
  base::ScopedBlockingCall scoped_blocking_call(FROM_HERE,
                                                base::BlockingType::MAY_BLOCK);
  base::CommandLine new_cmd_line(base::CommandLine::NO_PROGRAM);

  AppendProfileArgs(
      extension_app_id.empty() ? base::FilePath() : profile_path,
      &new_cmd_line);

  // If |extension_app_id| is present, we use the kAppId switch rather than
  // the kApp switch (the launch url will be read from the extension app
  // during launch.
  if (!extension_app_id.empty()) {
    new_cmd_line.AppendSwitchASCII(switches::kAppId, extension_app_id);
    // Add --enable-automation switch to support app launches against a browser
    // process already running with --enable-automation. If not present, app
    // launches will fail as process hand-off is prohibited in automation mode.
    if (base::CommandLine::ForCurrentProcess()->HasSwitch(
            switches::kEnableAutomation)) {
      new_cmd_line.AppendSwitch(switches::kEnableAutomation);
    }
  } else {
    // Use '--app=url' instead of just 'url' to launch the browser with minimal
    // chrome.
    // Note: Do not change this flag!  Old Gears shortcuts will break if you do!
    new_cmd_line.AppendSwitchASCII(switches::kApp, url.spec());
  }

  if (!run_on_os_login_mode.empty()) {
    new_cmd_line.AppendSwitchASCII(switches::kAppRunOnOsLoginMode,
                                   run_on_os_login_mode);
  }

  return new_cmd_line;
}

base::CommandLine CommandLineArgsForUrlShortcut(
    const base::FilePath& chrome_exe_program,
    const base::FilePath& profile_path,
    const GURL& url) {
  CHECK(!chrome_exe_program.empty());
  CHECK(!profile_path.empty());
  CHECK(url.is_valid());
  base::CommandLine new_cmd_line(chrome_exe_program);
  AppendProfileArgs(profile_path, &new_cmd_line);
  new_cmd_line.AppendSwitch(switches::kIgnoreProfileDirectoryIfNotExists);
  new_cmd_line.AppendArg(url.spec());

  return new_cmd_line;
}

void AppendProfileArgs(const base::FilePath& profile_path,
                       base::CommandLine* command_line) {
  DCHECK(command_line);
  const base::CommandLine& cmd_line = *base::CommandLine::ForCurrentProcess();

  // Use the same UserDataDir for new launches that we currently have set.
  base::FilePath user_data_dir =
      cmd_line.GetSwitchValuePath(switches::kUserDataDir);
#if BUILDFLAG(IS_MAC) || BUILDFLAG(IS_WIN)
  policy::path_parser::CheckUserDataDirPolicy(&user_data_dir);
#endif
  if (!user_data_dir.empty()) {
    // Make sure user_data_dir is an absolute path.
    user_data_dir = base::MakeAbsoluteFilePath(user_data_dir);
    if (!user_data_dir.empty() && base::PathExists(user_data_dir))
      command_line->AppendSwitchPath(switches::kUserDataDir, user_data_dir);
  }

#if BUILDFLAG(IS_CHROMEOS)
  base::FilePath profile =
      cmd_line.GetSwitchValuePath(ash::switches::kLoginProfile);
  if (!profile.empty())
    command_line->AppendSwitchPath(ash::switches::kLoginProfile, profile);
#else
  if (!profile_path.empty())
    command_line->AppendSwitchPath(switches::kProfileDirectory,
                                   profile_path.BaseName());
#endif
}

#if !BUILDFLAG(IS_WIN)
std::u16string GetAppShortcutsSubdirName() {
  if (chrome::GetChannel() == version_info::Channel::CANARY)
    return l10n_util::GetStringUTF16(IDS_APP_SHORTCUTS_SUBDIR_NAME_CANARY);
  return l10n_util::GetStringUTF16(IDS_APP_SHORTCUTS_SUBDIR_NAME);
}
#endif  // !BUILDFLAG(IS_WIN)

///////////////////////////////////////////////////////////////////////////////
// DefaultWebClientWorker
//

void DefaultWebClientWorker::StartCheckIsDefault(
    DefaultWebClientWorkerCallback callback) {
  g_sequenced_task_runner.Get()->PostTask(
      FROM_HERE, base::BindOnce(&DefaultWebClientWorker::CheckIsDefault, this,
                                false, std::move(callback)));
}

void DefaultWebClientWorker::StartSetAsDefault(
    DefaultWebClientWorkerCallback callback) {
  g_sequenced_task_runner.Get()->PostTask(
      FROM_HERE, base::BindOnce(&DefaultWebClientWorker::SetAsDefault, this,
                                std::move(callback)));
}

///////////////////////////////////////////////////////////////////////////////
// DefaultWebClientWorker, protected:

DefaultWebClientWorker::DefaultWebClientWorker(const char* worker_name)
    : worker_name_(worker_name) {}

DefaultWebClientWorker::~DefaultWebClientWorker() = default;

void DefaultWebClientWorker::OnCheckIsDefaultComplete(
    DefaultWebClientState state,
    bool is_following_set_as_default,
    DefaultWebClientWorkerCallback callback) {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);
  RunCallback(std::move(callback), state);

  if (is_following_set_as_default)
    ReportSetDefaultResult(state);
}

///////////////////////////////////////////////////////////////////////////////
// DefaultWebClientWorker, private:

void DefaultWebClientWorker::CheckIsDefault(
    bool is_following_set_as_default,
    DefaultWebClientWorkerCallback callback) {
  base::ScopedBlockingCall scoped_blocking_call(FROM_HERE,
                                                base::BlockingType::MAY_BLOCK);

  DefaultWebClientState state = CheckIsDefaultImpl();
  content::GetUIThreadTaskRunner({})->PostTask(
      FROM_HERE,
      base::BindOnce(&DefaultBrowserWorker::OnCheckIsDefaultComplete, this,
                     state, is_following_set_as_default, std::move(callback)));
}

void DefaultWebClientWorker::SetAsDefault(
    DefaultWebClientWorkerCallback callback) {
  base::ScopedBlockingCall scoped_blocking_call(FROM_HERE,
                                                base::BlockingType::MAY_BLOCK);

  // SetAsDefaultImpl will make sure the callback is executed exactly once.
  SetAsDefaultImpl(base::BindOnce(&DefaultWebClientWorker::CheckIsDefault, this,
                                  true, std::move(callback)));
}

void DefaultWebClientWorker::ReportSetDefaultResult(
    DefaultWebClientState state) {
  base::LinearHistogram::FactoryGet(
      base::StringPrintf("%s.SetDefaultResult2", worker_name_), 1,
      DefaultWebClientState::NUM_DEFAULT_STATES,
      DefaultWebClientState::NUM_DEFAULT_STATES + 1,
      base::HistogramBase::kUmaTargetedHistogramFlag)
      ->Add(state);
}

///////////////////////////////////////////////////////////////////////////////
// DefaultBrowserWorker
//

DefaultBrowserWorker::DefaultBrowserWorker()
    : DefaultWebClientWorker("DefaultBrowser") {}

///////////////////////////////////////////////////////////////////////////////
// DefaultBrowserWorker, private:

DefaultBrowserWorker::~DefaultBrowserWorker() = default;

// static
bool DefaultBrowserWorker::g_disable_set_as_default_for_testing = false;

// static
void DefaultBrowserWorker::DisableSetAsDefaultForTesting() {
  g_disable_set_as_default_for_testing = true;
}

DefaultWebClientState DefaultBrowserWorker::CheckIsDefaultImpl() {
  return GetDefaultBrowser();
}

void DefaultBrowserWorker::SetAsDefaultImpl(
    base::OnceClosure on_finished_callback) {
  if (!g_disable_set_as_default_for_testing) {
    switch (GetDefaultBrowserSetPermission()) {
      case SET_DEFAULT_NOT_ALLOWED:
        // This is a no-op on channels where set-default is not allowed, but not
        // an error.
        break;
      case SET_DEFAULT_UNATTENDED:
        SetAsDefaultBrowser();
        break;
      case SET_DEFAULT_INTERACTIVE:
#if BUILDFLAG(IS_WIN)
        if (interactive_permitted_) {
          win::SetAsDefaultBrowserUsingSystemSettings(
              std::move(on_finished_callback));
          // Early return because the function above takes care of calling
          // `on_finished_callback`.
          return;
        }
#endif  // BUILDFLAG(IS_WIN)
        break;
    }
  }
  std::move(on_finished_callback).Run();
}

///////////////////////////////////////////////////////////////////////////////
// DefaultSchemeClientWorker
//

DefaultSchemeClientWorker::DefaultSchemeClientWorker(const std::string& scheme)
    : DefaultWebClientWorker("DefaultSchemeClient"), scheme_(scheme) {}

DefaultSchemeClientWorker::DefaultSchemeClientWorker(const GURL& url)
    : DefaultWebClientWorker("DefaultSchemeClient"),
      scheme_(url.GetScheme()),
      url_(url) {}

void DefaultSchemeClientWorker::StartCheckIsDefaultAndGetDefaultClientName(
    DefaultSchemeHandlerWorkerCallback callback) {
  g_sequenced_task_runner.Get()->PostTask(
      FROM_HERE,
      base::BindOnce(
          &DefaultSchemeClientWorker::CheckIsDefaultAndGetDefaultClientName,
          this, std::move(callback)));
}

///////////////////////////////////////////////////////////////////////////////
// DefaultSchemeClientWorker, protected:

DefaultSchemeClientWorker::~DefaultSchemeClientWorker() = default;

void DefaultSchemeClientWorker::OnCheckIsDefaultAndGetDefaultClientNameComplete(
    DefaultWebClientState state,
    std::u16string program_name,
    DefaultSchemeHandlerWorkerCallback callback) {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);

  if (!callback.is_null() && IsValidDefaultWebClientState(state)) {
    std::move(callback).Run(state, program_name);
  }
}

///////////////////////////////////////////////////////////////////////////////
// DefaultSchemeClientWorker, private:

void DefaultSchemeClientWorker::CheckIsDefaultAndGetDefaultClientName(
    DefaultSchemeHandlerWorkerCallback callback) {
  DCHECK(!url_.is_empty());
  base::ScopedBlockingCall scoped_blocking_call(FROM_HERE,
                                                base::BlockingType::MAY_BLOCK);

  DefaultWebClientState state = CheckIsDefaultImpl();
  std::u16string program_name = GetDefaultClientNameImpl();
  content::GetUIThreadTaskRunner({})->PostTask(
      FROM_HERE,
      base::BindOnce(&DefaultSchemeClientWorker::
                         OnCheckIsDefaultAndGetDefaultClientNameComplete,
                     this, state, program_name, std::move(callback)));
}

DefaultWebClientState DefaultSchemeClientWorker::CheckIsDefaultImpl() {
  return IsDefaultClientForScheme(scheme_);
}

std::u16string DefaultSchemeClientWorker::GetDefaultClientNameImpl() {
  return GetApplicationNameForScheme(url_);
}

void DefaultSchemeClientWorker::SetAsDefaultImpl(
    base::OnceClosure on_finished_callback) {
  switch (GetDefaultSchemeClientSetPermission()) {
    case SET_DEFAULT_NOT_ALLOWED:
      // Not allowed, do nothing.
      break;
    case SET_DEFAULT_UNATTENDED:
      SetAsDefaultClientForScheme(scheme_);
      break;
    case SET_DEFAULT_INTERACTIVE:
#if BUILDFLAG(IS_WIN)
      if (interactive_permitted_) {
        win::SetAsDefaultClientForSchemeUsingSystemSettings(
            scheme_, std::move(on_finished_callback));
        // Early return because the function above takes care of calling
        // `on_finished_callback`.
        return;
      }
#endif  // BUILDFLAG(IS_WIN)
      break;
  }
  std::move(on_finished_callback).Run();
}

}  // namespace shell_integration
