// Copyright (c) 2012 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 <stddef.h>

#include <memory>

#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/command_line.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "base/test/thread_test_helper.h"
#include "chrome/browser/extensions/extension_apitest.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chrome/test/base/ui_test_utils.h"
#include "content/public/browser/browser_thread.h"
#include "extensions/browser/api/declarative/rules_registry_service.h"
#include "extensions/browser/api/declarative_webrequest/webrequest_constants.h"
#include "extensions/browser/api/declarative_webrequest/webrequest_rules_registry.h"
#include "extensions/browser/extension_prefs.h"
#include "extensions/common/extension.h"
#include "extensions/test/extension_test_message_listener.h"
#include "extensions/test/test_extension_dir.h"

using content::BrowserThread;

namespace extensions {

namespace {

const char kArbitraryUrl[] = "http://www.example.com";  // Must be http://.

// The extension in "declarative/redirect_to_data" redirects every navigation to
// a page with title |kTestTitle|.
#define TEST_TITLE_STRING ":TEST:"
const char kTestTitle[] = TEST_TITLE_STRING;

// All methods and constands below containing "RedirectToData" in their names
// are parts of a test extension "Redirect to 'data:'".
std::string GetRedirectToDataManifestWithVersion(unsigned version) {
  return base::StringPrintf(
      "{\n"
      "  \"name\": \"Redirect to 'data:' (declarative apitest)\",\n"
      "  \"version\": \"%d\",\n"
      "  \"manifest_version\": 2,\n"
      "  \"description\": \"Redirects all requests to a fixed data: URI.\",\n"
      "  \"background\": {\n"
      "    \"scripts\": [\"background.js\"]\n"
      "  },\n"
      "  \"permissions\": [\n"
      "    \"declarativeWebRequest\", \"<all_urls>\"\n"
      "  ]\n"
      "}\n",
      version);
}

const char kRedirectToDataConstants[] =
    "var redirectDataURI =\n"
    "    'data:text/html;charset=utf-8,<html><head><title>' +\n"
    "    '" TEST_TITLE_STRING "' +\n"
    "    '<%2Ftitle><%2Fhtml>';\n";
#undef TEST_TITLE_STRING

const char kRedirectToDataRules[] =
    "var rules = [{\n"
    "  conditions: [\n"
    "    new chrome.declarativeWebRequest.RequestMatcher({\n"
    "        url: {schemes: ['http']}})\n"
    "  ],\n"
    "  actions: [\n"
    "    new chrome.declarativeWebRequest.RedirectRequest({\n"
    "      redirectUrl: redirectDataURI\n"
    "    })\n"
    "  ]\n"
    "}];\n";

const char kRedirectToDataInstallRules[] =
    "function report(details) {\n"
    "  if (chrome.extension.lastError) {\n"
    "    chrome.test.log(chrome.extension.lastError.message);\n"
    "  } else {\n"
    "    chrome.test.sendMessage(\"ready\", function(reply) {})\n"
    "  }\n"
    "}\n"
    "\n"
    "chrome.runtime.onInstalled.addListener(function(details) {\n"
    "  if (details.reason == 'install')\n"
    "    chrome.declarativeWebRequest.onRequest.addRules(rules, report);\n"
    "});\n";

const char kRedirectToDataNoRules[] =
    "chrome.runtime.onInstalled.addListener(function(details) {\n"
    "  chrome.test.sendMessage(\"ready\", function(reply) {})\n"
    "});\n";

}  // namespace

class DeclarativeApiTest : public ExtensionApiTest {
 public:
  std::string GetTitle() {
    base::string16 title(
        browser()->tab_strip_model()->GetActiveWebContents()->GetTitle());
    return base::UTF16ToUTF8(title);
  }

  // Reports the number of rules registered for the |extension_id| with the
  // non-webview rules registry.
  size_t NumberOfRegisteredRules(const std::string& extension_id) {
    RulesRegistryService* rules_registry_service =
        extensions::RulesRegistryService::Get(browser()->profile());
    scoped_refptr<RulesRegistry> rules_registry =
        rules_registry_service->GetRulesRegistry(
            RulesRegistryService::kDefaultRulesRegistryID,
            extensions::declarative_webrequest_constants::kOnRequest);

    std::vector<linked_ptr<api::events::Rule>> rules;
    BrowserThread::PostTask(
        BrowserThread::IO, FROM_HERE,
        base::BindOnce(&RulesRegistry::GetAllRules, rules_registry,
                       extension_id, &rules));
    scoped_refptr<base::ThreadTestHelper> io_helper(new base::ThreadTestHelper(
        BrowserThread::GetTaskRunnerForThread(BrowserThread::IO).get()));
    EXPECT_TRUE(io_helper->Run());
    return rules.size();
  }
};

IN_PROC_BROWSER_TEST_F(DeclarativeApiTest, DeclarativeApi) {
  ASSERT_TRUE(RunExtensionTest("declarative/api")) << message_;

  // Check that uninstalling the extension has removed all rules.
  std::string extension_id = GetSingleLoadedExtension()->id();
  UninstallExtension(extension_id);

  // UnloadExtension posts a task to the owner thread of the extension
  // to process this unloading. The next task to retrive all rules
  // is therefore processed after the UnloadExtension task has been executed.
  EXPECT_EQ(0u, NumberOfRegisteredRules(extension_id));
}

// PersistRules test first installs an extension, which registers some rules.
// Then after browser restart, it checks that the rules are still in effect.
IN_PROC_BROWSER_TEST_F(DeclarativeApiTest, PRE_PersistRules) {
  // Note that we cannot use an extension generated by *GetRedirectToData*
  // helpers in a TestExtensionDir, because we need the extension to persist
  // until the PersistRules test is run.
  ASSERT_TRUE(RunExtensionTest("declarative/redirect_to_data")) << message_;
}

IN_PROC_BROWSER_TEST_F(DeclarativeApiTest, PersistRules) {
  ui_test_utils::NavigateToURL(browser(), GURL(kArbitraryUrl));
  EXPECT_EQ(kTestTitle, GetTitle());
}

// Test that the rules are correctly persisted and (de)activated during
// changing the "installed" and "enabled" status of an extension.
IN_PROC_BROWSER_TEST_F(DeclarativeApiTest, ExtensionLifetimeRulesHandling) {
  TestExtensionDir ext_dir;

  // 1. Install the extension. Rules should become active.
  ext_dir.WriteManifest(GetRedirectToDataManifestWithVersion(1));
  ext_dir.WriteFile(FILE_PATH_LITERAL("background.js"),
                    base::StringPrintf("%s%s%s",
                                       kRedirectToDataConstants,
                                       kRedirectToDataRules,
                                       kRedirectToDataInstallRules));
  ExtensionTestMessageListener ready("ready", /*will_reply=*/false);
  const Extension* extension = InstallExtensionWithUIAutoConfirm(
      ext_dir.Pack(), 1 /*+1 installed extension*/, browser());
  ASSERT_TRUE(extension);
  std::string extension_id(extension->id());
  ASSERT_TRUE(ready.WaitUntilSatisfied());
  ui_test_utils::NavigateToURL(browser(), GURL(kArbitraryUrl));
  EXPECT_EQ(kTestTitle, GetTitle());
  EXPECT_EQ(1u, NumberOfRegisteredRules(extension_id));

  // 2. Disable the extension. Rules are no longer active, but are still
  // registered.
  DisableExtension(extension_id);
  ui_test_utils::NavigateToURL(browser(), GURL(kArbitraryUrl));
  EXPECT_NE(kTestTitle, GetTitle());
  EXPECT_EQ(1u, NumberOfRegisteredRules(extension_id));

  // 3. Enable the extension again. Rules are active again.
  EnableExtension(extension_id);
  ui_test_utils::NavigateToURL(browser(), GURL(kArbitraryUrl));
  EXPECT_EQ(kTestTitle, GetTitle());
  EXPECT_EQ(1u, NumberOfRegisteredRules(extension_id));

  // 4. Bump the version and update, without the code to add the rules. Rules
  // are still active, because the registry does not drop them unless the
  // extension gets uninstalled.
  ext_dir.WriteManifest(GetRedirectToDataManifestWithVersion(2));
  ext_dir.WriteFile(
      FILE_PATH_LITERAL("background.js"),
      base::StringPrintf(
          "%s%s", kRedirectToDataConstants, kRedirectToDataNoRules));
  ExtensionTestMessageListener ready_after_update("ready",
                                                  /*will_reply=*/false);
  EXPECT_TRUE(UpdateExtension(
      extension_id, ext_dir.Pack(), 0 /*no new installed extension*/));
  ASSERT_TRUE(ready_after_update.WaitUntilSatisfied());
  ui_test_utils::NavigateToURL(browser(), GURL(kArbitraryUrl));
  EXPECT_EQ(kTestTitle, GetTitle());
  EXPECT_EQ(1u, NumberOfRegisteredRules(extension_id));

  // 5. Reload the extension. Rules remain active.
  ReloadExtension(extension_id);
  ui_test_utils::NavigateToURL(browser(), GURL(kArbitraryUrl));
  EXPECT_EQ(kTestTitle, GetTitle());
  EXPECT_EQ(1u, NumberOfRegisteredRules(extension_id));

  // 6. Uninstall the extension. Rules are gone.
  UninstallExtension(extension_id);
  ui_test_utils::NavigateToURL(browser(), GURL(kArbitraryUrl));
  EXPECT_NE(kTestTitle, GetTitle());
  EXPECT_EQ(0u, NumberOfRegisteredRules(extension_id));
}

// When an extenion is uninstalled, the state store deletes all preferences
// stored for that extension. We need to make sure we don't store anything after
// that deletion occurs.
IN_PROC_BROWSER_TEST_F(DeclarativeApiTest, NoTracesAfterUninstalling) {
  TestExtensionDir ext_dir;

  // 1. Install the extension. Verify that rules become active and some prefs
  // are stored.
  ext_dir.WriteManifest(GetRedirectToDataManifestWithVersion(1));
  ext_dir.WriteFile(FILE_PATH_LITERAL("background.js"),
                    base::StringPrintf("%s%s%s",
                                       kRedirectToDataConstants,
                                       kRedirectToDataRules,
                                       kRedirectToDataInstallRules));
  ExtensionTestMessageListener ready("ready", /*will_reply=*/false);
  const Extension* extension = InstallExtensionWithUIAutoConfirm(
      ext_dir.Pack(), 1 /*+1 installed extension*/, browser());
  ASSERT_TRUE(extension);
  std::string extension_id(extension->id());
  ASSERT_TRUE(ready.WaitUntilSatisfied());
  ui_test_utils::NavigateToURL(browser(), GURL(kArbitraryUrl));
  EXPECT_EQ(kTestTitle, GetTitle());
  EXPECT_EQ(1u, NumberOfRegisteredRules(extension_id));
  ExtensionPrefs* extension_prefs = ExtensionPrefs::Get(browser()->profile());
  EXPECT_TRUE(extension_prefs->HasPrefForExtension(extension_id));

  // 2. Uninstall the extension. Rules are gone and preferences should be empty.
  UninstallExtension(extension_id);
  ui_test_utils::NavigateToURL(browser(), GURL(kArbitraryUrl));
  EXPECT_NE(kTestTitle, GetTitle());
  EXPECT_EQ(0u, NumberOfRegisteredRules(extension_id));
  EXPECT_FALSE(extension_prefs->HasPrefForExtension(extension_id));
}

}  // namespace extensions
