// 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/build_config.h"
#include "build/chromeos_buildflags.h"
#include "chrome/browser/chrome_for_testing/buildflags.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"

#if BUILDFLAG(IS_CHROMEOS_ASH)
#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/chromium_strings.h"
#include "ui/base/l10n/l10n_util.h"
#endif

using content::BrowserThread;

namespace shell_integration {

namespace {

// TODO(crbug.com/773563): 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();
  return false;
}

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);
  } 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;
}

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_ASH)
  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;

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

void DefaultBrowserWorker::SetAsDefaultImpl(
    base::OnceClosure on_finished_callback) {
  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.scheme()),
      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
