// Copyright 2013 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 <memory>

#include "base/run_loop.h"
#include "base/stl_util.h"
#include "base/strings/utf_string_conversions.h"
#include "build/build_config.h"
#include "chrome/browser/extensions/extension_browsertest.h"
#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/prefs/session_startup_pref.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/search/search.h"
#include "chrome/browser/search_engines/template_url_service_factory.h"
#include "chrome/browser/search_engines/ui_thread_search_terms_data.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/pref_names.h"
#include "chrome/test/base/search_test_utils.h"
#include "components/prefs/pref_service.h"
#include "components/search_engines/default_search_manager.h"
#include "components/search_engines/search_engines_test_util.h"
#include "components/search_engines/template_url.h"
#include "components/search_engines/template_url_prepopulate_data.h"
#include "components/search_engines/template_url_service.h"
#include "components/version_info/version_info.h"
#include "extensions/browser/extension_registry.h"
#include "extensions/browser/mock_external_provider.h"
#include "extensions/browser/test_extension_registry_observer.h"
#include "extensions/common/feature_switch.h"
#include "extensions/common/features/feature_channel.h"

namespace extensions {

namespace {
#if defined(OS_WIN) || defined(OS_MACOSX)
// Prepopulated id hardcoded in test_extension.
const int kTestExtensionPrepopulatedId = 1;
// TemplateURLData with search engines settings from test extension manifest.
// chrome/test/data/extensions/settings_override/manifest.json
std::unique_ptr<TemplateURLData> TestExtensionSearchEngine(PrefService* prefs) {
  auto result = std::make_unique<TemplateURLData>();
  result->SetShortName(base::ASCIIToUTF16("name.de"));
  result->SetKeyword(base::ASCIIToUTF16("keyword.de"));
  result->SetURL("http://www.foo.de/s?q={searchTerms}&id=10");
  result->favicon_url = GURL("http://www.foo.de/favicon.ico?id=10");
  result->suggestions_url = "http://www.foo.de/suggest?q={searchTerms}&id=10";
  result->image_url = "http://www.foo.de/image?q={searchTerms}&id=10";
  result->search_url_post_params = "search_lang=de";
  result->suggestions_url_post_params = "suggest_lang=de";
  result->image_url_post_params = "image_lang=de";
  result->alternate_urls.push_back("http://www.moo.de/s?q={searchTerms}&id=10");
  result->alternate_urls.push_back("http://www.noo.de/s?q={searchTerms}&id=10");
  result->input_encodings.push_back("UTF-8");

  std::unique_ptr<TemplateURLData> prepopulated =
      TemplateURLPrepopulateData::GetPrepopulatedEngine(
          prefs, kTestExtensionPrepopulatedId);
  // Values below do not exist in extension manifest and are taken from
  // prepopulated engine with prepopulated_id set in extension manifest.
  result->contextual_search_url = prepopulated->contextual_search_url;
  result->new_tab_url = prepopulated->new_tab_url;
  return result;
}

testing::AssertionResult VerifyTemplateURLServiceLoad(
    TemplateURLService* service) {
  if (service->loaded())
    return testing::AssertionSuccess();
  search_test_utils::WaitForTemplateURLServiceToLoad(service);
  if (service->loaded())
    return testing::AssertionSuccess();
  return testing::AssertionFailure() << "TemplateURLService isn't loaded";
}

IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, OverrideHomePageSettings) {
  PrefService* prefs = profile()->GetPrefs();
  ASSERT_TRUE(prefs);
  prefs->SetString(prefs::kHomePage, "http://google.com/");
  prefs->SetBoolean(prefs::kHomePageIsNewTabPage, true);

  const extensions::Extension* extension = LoadExtensionWithInstallParam(
      test_data_dir_.AppendASCII("settings_override"), kFlagEnableFileAccess,
      "10");
  ASSERT_TRUE(extension);
  EXPECT_EQ("http://www.homepage.de/?param=10",
            prefs->GetString(prefs::kHomePage));
  EXPECT_FALSE(prefs->GetBoolean(prefs::kHomePageIsNewTabPage));
  UnloadExtension(extension->id());
  EXPECT_EQ("http://google.com/", prefs->GetString(prefs::kHomePage));
  EXPECT_TRUE(prefs->GetBoolean(prefs::kHomePageIsNewTabPage));
}

IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, OverrideStartupPagesSettings) {
  PrefService* prefs = profile()->GetPrefs();
  ASSERT_TRUE(prefs);
  const GURL urls[] = {GURL("http://foo"), GURL("http://bar")};
  SessionStartupPref startup_pref(SessionStartupPref::LAST);
  startup_pref.urls.assign(urls, urls + base::size(urls));
  SessionStartupPref::SetStartupPref(prefs, startup_pref);

  const extensions::Extension* extension = LoadExtensionWithInstallParam(
      test_data_dir_.AppendASCII("settings_override"),
      kFlagEnableFileAccess,
      "10");
  ASSERT_TRUE(extension);
  startup_pref = SessionStartupPref::GetStartupPref(prefs);
  EXPECT_EQ(SessionStartupPref::URLS, startup_pref.type);
  EXPECT_EQ(std::vector<GURL>(1, GURL("http://www.startup.de/?param=10")),
            startup_pref.urls);
  UnloadExtension(extension->id());
  startup_pref = SessionStartupPref::GetStartupPref(prefs);
  EXPECT_EQ(SessionStartupPref::LAST, startup_pref.type);
  EXPECT_EQ(std::vector<GURL>(urls, urls + base::size(urls)),
            startup_pref.urls);
}

IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, OverrideDSE) {
  PrefService* prefs = profile()->GetPrefs();
  ASSERT_TRUE(prefs);
  TemplateURLService* url_service =
      TemplateURLServiceFactory::GetForProfile(profile());
  ASSERT_TRUE(url_service);
  EXPECT_TRUE(VerifyTemplateURLServiceLoad(url_service));
  const TemplateURL* default_provider = url_service->GetDefaultSearchProvider();
  ASSERT_TRUE(default_provider);
  EXPECT_EQ(TemplateURL::NORMAL, default_provider->type());

  const extensions::Extension* extension = LoadExtensionWithInstallParam(
      test_data_dir_.AppendASCII("settings_override"), kFlagEnableFileAccess,
      "10");
  ASSERT_TRUE(extension);
  const TemplateURL* current_dse = url_service->GetDefaultSearchProvider();
  EXPECT_EQ(TemplateURL::NORMAL_CONTROLLED_BY_EXTENSION, current_dse->type());

  std::unique_ptr<TemplateURLData> extension_dse =
      TestExtensionSearchEngine(prefs);
  ExpectSimilar(extension_dse.get(), &current_dse->data());

  UnloadExtension(extension->id());
  EXPECT_EQ(default_provider, url_service->GetDefaultSearchProvider());
}

// Install and load extension into test profile.
IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, PRE_OverridenDSEPersists) {
  PrefService* prefs = profile()->GetPrefs();
  ASSERT_TRUE(prefs);
  TemplateURLService* url_service =
      TemplateURLServiceFactory::GetForProfile(profile());
  ASSERT_TRUE(url_service);
  EXPECT_TRUE(VerifyTemplateURLServiceLoad(url_service));
  const TemplateURL* default_provider = url_service->GetDefaultSearchProvider();
  ASSERT_TRUE(default_provider);
  // Check that default provider is normal before extension is
  // installed and loaded.
  EXPECT_EQ(TemplateURL::NORMAL, default_provider->type());
  EXPECT_NE(base::ASCIIToUTF16("name.de"), default_provider->short_name());
  EXPECT_NE(base::ASCIIToUTF16("keyword.de"), default_provider->keyword());

  // Install extension that overrides DSE.
  const extensions::Extension* extension = LoadExtensionWithInstallParam(
      test_data_dir_.AppendASCII("settings_override"), kFlagEnableFileAccess,
      "10");
  ASSERT_TRUE(extension);
}

// PRE_OverridenDSEPersists already installed extension with overriden DSE into
// profile. Current test checks that after extension is installed,
// default_search_manager correctly determines extension overriden DSE
// from profile.
IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, OverridenDSEPersists) {
  Profile* profile = browser()->profile();
  DefaultSearchManager default_manager(
      profile->GetPrefs(), DefaultSearchManager::ObserverCallback());

  DefaultSearchManager::Source source;
  const TemplateURLData* current_dse =
      default_manager.GetDefaultSearchEngine(&source);

  ASSERT_TRUE(current_dse);
  std::unique_ptr<TemplateURLData> extension_dse =
      TestExtensionSearchEngine(profile->GetPrefs());
  ExpectSimilar(extension_dse.get(), current_dse);
  EXPECT_EQ(DefaultSearchManager::FROM_EXTENSION, source);

  // Check that new tab url is correctly overriden by extension.
  TemplateURL ext_turl(*extension_dse,
                       TemplateURL::NORMAL_CONTROLLED_BY_EXTENSION);

  std::string new_tab_url_ext = ext_turl.new_tab_url_ref().ReplaceSearchTerms(
      TemplateURLRef::SearchTermsArgs(base::string16()),
      UIThreadSearchTermsData(profile));

  EXPECT_EQ(new_tab_url_ext, search::GetNewTabPageURL(profile).spec());

  // Check that after template url service is loaded, extension dse persists.
  TemplateURLService* url_service =
      TemplateURLServiceFactory::GetForProfile(profile);
  ASSERT_TRUE(url_service);
  EXPECT_TRUE(VerifyTemplateURLServiceLoad(url_service));
  EXPECT_TRUE(url_service->IsExtensionControlledDefaultSearch());
  const TemplateURL* default_provider = url_service->GetDefaultSearchProvider();
  ASSERT_TRUE(default_provider);
  ExpectSimilar(extension_dse.get(), &default_provider->data());
}

// This test checks that an extension overriding the default search engine can
// be correctly loaded before the TemplateURLService is loaded.
IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, BeforeTemplateUrlServiceLoad) {
  PrefService* prefs = profile()->GetPrefs();
  ASSERT_TRUE(prefs);
  TemplateURLService* url_service =
      TemplateURLServiceFactory::GetForProfile(profile());
  ASSERT_TRUE(url_service);

  EXPECT_FALSE(url_service->IsExtensionControlledDefaultSearch());
  const extensions::Extension* extension = LoadExtensionWithInstallParam(
      test_data_dir_.AppendASCII("settings_override"), kFlagEnableFileAccess,
      "10");
  ASSERT_TRUE(extension);
  const TemplateURL* current_dse = url_service->GetDefaultSearchProvider();
  EXPECT_EQ(TemplateURL::NORMAL_CONTROLLED_BY_EXTENSION, current_dse->type());
  EXPECT_TRUE(url_service->IsExtensionControlledDefaultSearch());

  std::unique_ptr<TemplateURLData> extension_dse =
      TestExtensionSearchEngine(prefs);
  ExpectSimilar(extension_dse.get(), &current_dse->data());

  UnloadExtension(extension->id());
  EXPECT_NE(TemplateURL::NORMAL_CONTROLLED_BY_EXTENSION,
            url_service->GetDefaultSearchProvider()->type());
  EXPECT_FALSE(url_service->IsExtensionControlledDefaultSearch());
}

constexpr char kExternalId[] = "eloigjjcaheakkihngcgjhbopomgemdj";

class ExtensionsDisabledWithSettingsOverrideAPI : public ExtensionBrowserTest {
 public:
  ExtensionsDisabledWithSettingsOverrideAPI()
      : prompt_for_external_extensions_(
            FeatureSwitch::prompt_for_external_extensions(),
            false) {}
  ~ExtensionsDisabledWithSettingsOverrideAPI() override = default;

  void SetUpCommandLine(base::CommandLine* command_line) override {
    // A little tricky: we disable extensions (via the commandline) on the
    // non-PRE run. The PRE run is responsible for installing the external
    // extension.
    ExtensionBrowserTest::SetUpCommandLine(command_line);
    const char* test_name =
        testing::UnitTest::GetInstance()->current_test_info()->name();
    if (!base::StartsWith(test_name, "PRE_", base::CompareCase::SENSITIVE)) {
      command_line->AppendSwitch(::switches::kDisableExtensions);
    }
  }

 private:
  FeatureSwitch::ScopedOverride prompt_for_external_extensions_;

  DISALLOW_COPY_AND_ASSIGN(ExtensionsDisabledWithSettingsOverrideAPI);
};

// The following test combo is a regression test for https://crbug.com/828295.
// When extensions are disabled with --disable-extensions, no
// extension-controlled prefs were loaded. However, external extensions (such as
// those from policy or specified in the registry) are still loaded with
// --disable-extensions (this itself is somewhat strange; see
// https://crbug.com/833540). This caused a CHECK failure in the settings
// overrides API when an external extension used the API and
// --disable-extensions was also used.
// As a fix, we ensure that we load extension-controlled preferences for
// extensions that will be loaded, even with --disable-extensions.
IN_PROC_BROWSER_TEST_F(ExtensionsDisabledWithSettingsOverrideAPI,
                       PRE_TestSettingsOverridesWithExtensionsDisabled) {
  // This first part of the test adds an external extension that uses the
  // settings overrides API.
  ExtensionRegistry* registry = ExtensionRegistry::Get(profile());
  TestExtensionRegistryObserver observer(registry);
  auto provider = std::make_unique<MockExternalProvider>(
      extension_service(), Manifest::EXTERNAL_PREF);
  provider->UpdateOrAddExtension(
      kExternalId, "2.1",
      test_data_dir_.AppendASCII("api_test/settings_overrides/homepage.crx"));
  extension_service()->AddProviderForTesting(std::move(provider));
  extension_service()->CheckForExternalUpdates();
  const Extension* extension = observer.WaitForExtensionLoaded();
  EXPECT_EQ(kExternalId, extension->id());
}
IN_PROC_BROWSER_TEST_F(ExtensionsDisabledWithSettingsOverrideAPI,
                       TestSettingsOverridesWithExtensionsDisabled) {
  // The external extension was actually uninstalled at this point (see
  // https://crbug.com/833540). However, it was first loaded, before being
  // orphaned, which would have caused the settings API to look at the
  // extension controlled preferences. As long as this didn't crash, the test
  // succeeded.
  EXPECT_TRUE(ExtensionsBrowserClient::Get()->AreExtensionsDisabled(
      *base::CommandLine::ForCurrentProcess(), profile()));
}

#else
IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, SettingsOverridesDisallowed) {
  const extensions::Extension* extension =
      LoadExtensionWithFlags(test_data_dir_.AppendASCII("settings_override"),
                             kFlagIgnoreManifestWarnings);
  ASSERT_TRUE(extension);
  ASSERT_EQ(1u, extension->install_warnings().size());
  EXPECT_EQ(std::string("'chrome_settings_overrides' "
                        "is not allowed for specified platform."),
            extension->install_warnings().front().message);
}
#endif

}  // namespace
}  // namespace extensions
