// 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.
//
// This file contains tests for extension loading, reloading, and
// unloading behavior.

#include "base/run_loop.h"
#include "base/strings/stringprintf.h"
#include "base/version.h"
#include "build/build_config.h"
#include "chrome/browser/devtools/devtools_window.h"
#include "chrome/browser/devtools/devtools_window_testing.h"
#include "chrome/browser/extensions/devtools_util.h"
#include "chrome/browser/extensions/extension_browsertest.h"
#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "chrome/test/base/ui_test_utils.h"
#include "content/public/browser/devtools_agent_host.h"
#include "content/public/test/browser_test.h"
#include "content/public/test/browser_test_utils.h"
#include "extensions/browser/extension_registry.h"
#include "extensions/browser/process_manager.h"
#include "extensions/common/permissions/permissions_data.h"
#include "extensions/test/extension_test_message_listener.h"
#include "extensions/test/test_extension_dir.h"
#include "net/test/embedded_test_server/embedded_test_server.h"
#include "testing/gmock/include/gmock/gmock.h"

#if defined(OS_WIN)
#include "base/win/windows_version.h"
#endif

namespace extensions {
namespace {

class ExtensionLoadingTest : public ExtensionBrowserTest {
};

// Check the fix for http://crbug.com/178542.
IN_PROC_BROWSER_TEST_F(ExtensionLoadingTest,
                       UpgradeAfterNavigatingFromOverriddenNewTabPage) {
  ASSERT_TRUE(embedded_test_server()->Start());

  TestExtensionDir extension_dir;
  constexpr char kManifestTemplate[] =
      R"({
           "name": "Overrides New Tab",
           "version": "%d",
           "description": "Overrides New Tab",
           "manifest_version": 2,
           "background": {
             "persistent": false,
             "scripts": ["event.js"]
           },
           "chrome_url_overrides": {
             "newtab": "newtab.html"
           }
         })";
  extension_dir.WriteManifest(base::StringPrintf(kManifestTemplate, 1));
  extension_dir.WriteFile(FILE_PATH_LITERAL("event.js"), "");
  extension_dir.WriteFile(FILE_PATH_LITERAL("newtab.html"),
                          "<h1>Overridden New Tab Page</h1>");

  const Extension* new_tab_extension =
      InstallExtension(extension_dir.Pack(), 1 /*new install*/);
  ASSERT_TRUE(new_tab_extension);

  // Visit the New Tab Page to get a renderer using the extension into history.
  ui_test_utils::NavigateToURL(browser(), GURL("chrome://newtab"));

  // Navigate that tab to a non-extension URL to swap out the extension's
  // renderer.
  const GURL test_link_from_NTP =
      embedded_test_server()->GetURL("/README.chromium");
  EXPECT_THAT(test_link_from_NTP.spec(), testing::EndsWith("/README.chromium"))
      << "Check that the test server started.";
  NavigateInRenderer(browser()->tab_strip_model()->GetActiveWebContents(),
                     test_link_from_NTP);

  // Increase the extension's version.
  extension_dir.WriteManifest(base::StringPrintf(kManifestTemplate, 2));

  // Upgrade the extension.
  new_tab_extension = UpdateExtension(
      new_tab_extension->id(), extension_dir.Pack(), 0 /*expected upgrade*/);
  EXPECT_THAT(new_tab_extension->version().components(),
              testing::ElementsAre(2));

  // The extension takes a couple round-trips to the renderer in order
  // to crash, so open a new tab to wait long enough.
  AddTabAtIndex(browser()->tab_strip_model()->count(),
                GURL("http://www.google.com/"),
                ui::PAGE_TRANSITION_TYPED);

  // Check that the extension hasn't crashed.
  ExtensionRegistry* registry = ExtensionRegistry::Get(profile());
  EXPECT_EQ(0U, registry->terminated_extensions().size());
  EXPECT_TRUE(registry->enabled_extensions().Contains(new_tab_extension->id()));
}

IN_PROC_BROWSER_TEST_F(ExtensionLoadingTest,
                       UpgradeAddingNewTabPagePermissionNoPrompt) {
  ASSERT_TRUE(embedded_test_server()->Start());

  TestExtensionDir extension_dir;
  constexpr char kManifestTemplate[] =
      R"({
           "name": "Overrides New Tab",
           "version": "%d",
           "description": "Will override New Tab soon",
           %s  // Placeholder for future NTP url override block.
           "manifest_version": 2
         })";
  extension_dir.WriteManifest(base::StringPrintf(kManifestTemplate, 1, ""));
  extension_dir.WriteFile(FILE_PATH_LITERAL("event.js"), "");
  extension_dir.WriteFile(FILE_PATH_LITERAL("newtab.html"),
                          "<h1>Overridden New Tab Page</h1>");

  const Extension* new_tab_extension =
      InstallExtension(extension_dir.Pack(), 1 /*new install*/);
  ASSERT_TRUE(new_tab_extension);

  EXPECT_FALSE(new_tab_extension->permissions_data()->HasAPIPermission(
      mojom::APIPermissionID::kNewTabPageOverride));

  // Navigate that tab to a non-extension URL to swap out the extension's
  // renderer.
  const GURL test_link_from_ntp =
      embedded_test_server()->GetURL("/README.chromium");
  EXPECT_THAT(test_link_from_ntp.spec(), testing::EndsWith("/README.chromium"))
      << "Check that the test server started.";
  NavigateInRenderer(browser()->tab_strip_model()->GetActiveWebContents(),
                     test_link_from_ntp);

  // Increase the extension's version and add the NTP url override which will
  // add the kNewTabPageOverride permission.
  constexpr char kNtpOverrideString[] =
      R"("chrome_url_overrides": {
            "newtab": "newtab.html"
         },)";
  extension_dir.WriteManifest(
      base::StringPrintf(kManifestTemplate, 2, kNtpOverrideString));

  // Upgrade the extension, ensure that the upgrade 'worked' in the sense that
  // the extension is still present and not disabled and that it now has the
  // new API permission.
  // TODO(robertshield): Update this once most of the population is on M62+
  // and adding NTP permissions implies a permission upgrade.
  new_tab_extension = UpdateExtension(
      new_tab_extension->id(), extension_dir.Pack(), 0 /*expected upgrade*/);
  ASSERT_NE(nullptr, new_tab_extension);

  EXPECT_TRUE(new_tab_extension->permissions_data()->HasAPIPermission(
      mojom::APIPermissionID::kNewTabPageOverride));
  EXPECT_THAT(new_tab_extension->version().components(),
              testing::ElementsAre(2));
}

// Tests the behavior described in http://crbug.com/532088.
IN_PROC_BROWSER_TEST_F(ExtensionLoadingTest,
                       KeepAliveWithDevToolsOpenOnReload) {
  ASSERT_TRUE(embedded_test_server()->Start());

  TestExtensionDir extension_dir;
  const char manifest_contents[] =
      R"({
           "name": "Test With Lazy Background Page",
           "version": "0",
           "manifest_version": 2,
           "app": {
             "background": {
                "scripts": ["event.js"]
             }
           }
         })";
  extension_dir.WriteManifest(manifest_contents);
  extension_dir.WriteFile(FILE_PATH_LITERAL("event.js"), "");

  const Extension* extension =
      InstallExtension(extension_dir.Pack(), 1 /*new install*/);
  ASSERT_TRUE(extension);
  std::string extension_id = extension->id();
  const auto dev_tools_activity =
      std::make_pair(Activity::DEV_TOOLS, std::string());

  ProcessManager* process_manager = ProcessManager::Get(profile());
  EXPECT_EQ(0, process_manager->GetLazyKeepaliveCount(extension));
  ProcessManager::ActivitiesMultiset activities =
      process_manager->GetLazyKeepaliveActivities(extension);
  EXPECT_TRUE(activities.empty());

  devtools_util::InspectBackgroundPage(extension, profile());
  EXPECT_EQ(1, process_manager->GetLazyKeepaliveCount(extension));
  activities = process_manager->GetLazyKeepaliveActivities(extension);
  EXPECT_THAT(activities, testing::UnorderedElementsAre(dev_tools_activity));

  // Opening DevTools will cause the background page to load. Wait for it.
  WaitForExtensionViewsToLoad();

  ReloadExtension(extension_id);

  // Flush the MessageLoop to ensure that DevTools has a chance to be reattached
  // and the background page has a chance to begin reloading.
  base::RunLoop().RunUntilIdle();

  // And wait for the background page to finish loading again.
  WaitForExtensionViewsToLoad();

  // Ensure that our DevtoolsAgentHost is actually connected to the new
  // background WebContents.
  content::WebContents* background_contents =
      process_manager->GetBackgroundHostForExtension(extension_id)
          ->host_contents();
  EXPECT_TRUE(content::DevToolsAgentHost::HasFor(background_contents));

  // The old Extension object is no longer valid.
  extension = ExtensionRegistry::Get(profile())
      ->enabled_extensions().GetByID(extension_id);

  // Keepalive count should stabilize back to 1, because DevTools is still open.
  EXPECT_EQ(1, process_manager->GetLazyKeepaliveCount(extension));
  activities = process_manager->GetLazyKeepaliveActivities(extension);
  EXPECT_THAT(activities, testing::UnorderedElementsAre(dev_tools_activity));
}

// Tests whether the extension runtime stays valid when an extension reloads
// while a devtools extension is hammering the frame with eval requests.
// Regression test for https://crbug.com/544182
IN_PROC_BROWSER_TEST_F(ExtensionLoadingTest, RuntimeValidWhileDevToolsOpen) {
  TestExtensionDir devtools_dir;
  TestExtensionDir inspect_dir;

  constexpr char kDevtoolsManifest[] =
      R"({
           "name": "Devtools",
           "version": "1",
           "manifest_version": 2,
           "devtools_page": "devtools.html"
         })";

  constexpr char kDevtoolsJs[] =
      R"(setInterval(function() {
           chrome.devtools.inspectedWindow.eval('1', function() {
           });
         }, 4);
         chrome.test.sendMessage('devtools_page_ready');)";

  constexpr char kTargetManifest[] =
      R"({
           "name": "Inspect target",
           "version": "1",
           "manifest_version": 2,
           "background": {
             "scripts": ["background.js"]
           }
         })";

  // A script to duck-type whether it runs in a background page.
  const char kTargetJs[] =
      "var is_valid = !!(chrome.tabs && chrome.tabs.create);";

  devtools_dir.WriteManifest(kDevtoolsManifest);
  devtools_dir.WriteFile(FILE_PATH_LITERAL("devtools.js"), kDevtoolsJs);
  devtools_dir.WriteFile(FILE_PATH_LITERAL("devtools.html"),
                         "<script src='devtools.js'></script>");

  inspect_dir.WriteManifest(kTargetManifest);
  inspect_dir.WriteFile(FILE_PATH_LITERAL("background.js"), kTargetJs);
  const Extension* devtools_ext = LoadExtension(devtools_dir.UnpackedPath());
  ASSERT_TRUE(devtools_ext);

  const Extension* inspect_ext = LoadExtension(inspect_dir.UnpackedPath());
  ASSERT_TRUE(inspect_ext);
  const std::string inspect_ext_id = inspect_ext->id();

  // Open the devtools and wait until the devtools_page is ready.
  ExtensionTestMessageListener devtools_ready("devtools_page_ready", false);
  devtools_util::InspectBackgroundPage(inspect_ext, profile());
  ASSERT_TRUE(devtools_ready.WaitUntilSatisfied());

  // Reload the extension. The devtools window will stay open, but temporarily
  // be detached. As soon as the background is attached again, the devtools
  // continues with spamming eval requests.
  ReloadExtension(inspect_ext_id);
  WaitForExtensionViewsToLoad();

  content::WebContents* bg_contents =
      ProcessManager::Get(profile())
          ->GetBackgroundHostForExtension(inspect_ext_id)
          ->host_contents();
  ASSERT_TRUE(bg_contents);

  // Now check whether the extension runtime is valid (see kTargetJs).
  bool is_valid = false;
  ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
      bg_contents, "domAutomationController.send(is_valid);", &is_valid));
  EXPECT_TRUE(is_valid);

  // Tidy up.
  DevToolsWindowTesting::CloseDevToolsWindowSync(
      DevToolsWindow::FindDevToolsWindow(
          content::DevToolsAgentHost::GetOrCreateFor(bg_contents).get()));
}

}  // namespace
}  // namespace extensions
