// 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 "chrome/browser/extensions/active_tab_permission_granter.h"
#include "chrome/browser/extensions/api/commands/command_service.h"
#include "chrome/browser/extensions/browser_action_test_util.h"
#include "chrome/browser/extensions/extension_action.h"
#include "chrome/browser/extensions/extension_action_manager.h"
#include "chrome/browser/extensions/extension_apitest.h"
#include "chrome/browser/extensions/tab_helper.h"
#include "chrome/browser/sessions/session_tab_helper.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chrome/test/base/interactive_test_utils.h"
#include "chrome/test/base/ui_test_utils.h"
#include "content/public/browser/notification_service.h"
#include "content/public/browser/web_contents.h"
#include "content/public/test/browser_test_utils.h"
#include "extensions/common/extension.h"
#include "extensions/common/feature_switch.h"
#include "extensions/common/permissions/permissions_data.h"

using content::WebContents;

namespace extensions {

class CommandsApiTest : public ExtensionApiTest {
 public:
  CommandsApiTest() {}
  virtual ~CommandsApiTest() {}

 protected:
  BrowserActionTestUtil GetBrowserActionsBar() {
    return BrowserActionTestUtil(browser());
  }

  bool IsGrantedForTab(const Extension* extension,
                       const content::WebContents* web_contents) {
    return PermissionsData::HasAPIPermissionForTab(
        extension,
        SessionID::IdForTab(web_contents),
        APIPermission::kTab);
  }
};

class ScriptBadgesCommandsApiTest : public ExtensionApiTest {
 public:
  ScriptBadgesCommandsApiTest() {
    // We cannot add this to CommandsApiTest because then PageActions get
    // treated like BrowserActions and the PageAction test starts failing.
    FeatureSwitch::script_badges()->SetOverrideValue(
        FeatureSwitch::OVERRIDE_ENABLED);
  }
  virtual ~ScriptBadgesCommandsApiTest() {}
};

// Test the basic functionality of the Keybinding API:
// - That pressing the shortcut keys should perform actions (activate the
//   browser action or send an event).
// - Note: Page action keybindings are tested in PageAction test below.
// - The shortcut keys taken by one extension are not overwritten by the last
//   installed extension.
IN_PROC_BROWSER_TEST_F(CommandsApiTest, Basic) {
  ASSERT_TRUE(test_server()->Start());
  ASSERT_TRUE(RunExtensionTest("keybinding/basics")) << message_;
  const Extension* extension = GetSingleLoadedExtension();
  ASSERT_TRUE(extension) << message_;

  // Load this extension, which uses the same keybindings but sets the page
  // to different colors. This is so we can see that it doesn't interfere. We
  // don't test this extension in any other way (it should otherwise be
  // immaterial to this test).
  ASSERT_TRUE(RunExtensionTest("keybinding/conflicting")) << message_;

  // Test that there are two browser actions in the toolbar.
  ASSERT_EQ(2, GetBrowserActionsBar().NumberOfBrowserActions());

  ui_test_utils::NavigateToURL(browser(),
      test_server()->GetURL("files/extensions/test_file.txt"));

  // activeTab shouldn't have been granted yet.
  WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
  ASSERT_TRUE(tab);

  EXPECT_FALSE(IsGrantedForTab(extension, tab));

  // Activate the shortcut (Ctrl+Shift+F).
  ASSERT_TRUE(ui_test_utils::SendKeyPressSync(
      browser(), ui::VKEY_F, true, true, false, false));

  // activeTab should now be granted.
  EXPECT_TRUE(IsGrantedForTab(extension, tab));

  // Verify the command worked.
  bool result = false;
  ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
      tab,
      "setInterval(function(){"
      "  if(document.body.bgColor == 'red'){"
      "    window.domAutomationController.send(true)}}, 100)",
      &result));
  ASSERT_TRUE(result);

  // Activate the shortcut (Ctrl+Shift+Y).
  ASSERT_TRUE(ui_test_utils::SendKeyPressSync(
      browser(), ui::VKEY_Y, true, true, false, false));

  result = false;
  ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
      tab,
      "setInterval(function(){"
      "  if(document.body.bgColor == 'blue'){"
      "    window.domAutomationController.send(true)}}, 100)",
      &result));
  ASSERT_TRUE(result);
}

// Flaky on linux and chromeos, http://crbug.com/165825
#if defined(OS_MACOSX) || defined(OS_WIN)
#define MAYBE_PageAction PageAction
#else
#define MAYBE_PageAction DISABLED_PageAction
#endif
IN_PROC_BROWSER_TEST_F(CommandsApiTest, MAYBE_PageAction) {
  ASSERT_TRUE(test_server()->Start());
  ASSERT_TRUE(RunExtensionTest("keybinding/page_action")) << message_;
  const Extension* extension = GetSingleLoadedExtension();
  ASSERT_TRUE(extension) << message_;

  {
    // Load a page, the extension will detect the navigation and request to show
    // the page action icon.
    ResultCatcher catcher;
    ui_test_utils::NavigateToURL(browser(),
        test_server()->GetURL("files/extensions/test_file.txt"));
    ASSERT_TRUE(catcher.GetNextResult());
  }

  // Make sure it appears and is the right one.
  ASSERT_TRUE(WaitForPageActionVisibilityChangeTo(1));
  int tab_id = SessionTabHelper::FromWebContents(
      browser()->tab_strip_model()->GetActiveWebContents())->session_id().id();
  ExtensionAction* action =
      ExtensionActionManager::Get(browser()->profile())->
      GetPageAction(*extension);
  ASSERT_TRUE(action);
  EXPECT_EQ("Make this page red", action->GetTitle(tab_id));

  // Activate the shortcut (Alt+Shift+F).
  ASSERT_TRUE(ui_test_utils::SendKeyPressSync(
      browser(), ui::VKEY_F, false, true, true, false));

  // Verify the command worked (the page action turns the page red).
  WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
  bool result = false;
  ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
      tab,
      "setInterval(function(){"
      "  if(document.body.bgColor == 'red'){"
      "    window.domAutomationController.send(true)}}, 100)",
      &result));
  ASSERT_TRUE(result);
}

// Checked-in in a disabled state, because the necessary functionality to
// automatically verify that the test works hasn't been implemented for the
// script badges yet (see http://crbug.com/140016). The test results, can be
// verified manually by running the test and verifying that the synthesized
// popup for script badges appear. When bug 140016 has been fixed, the popup
// code can signal to the test that the test passed.
// TODO(finnur): Enable this test once the bug is fixed.
IN_PROC_BROWSER_TEST_F(ScriptBadgesCommandsApiTest, DISABLED_ScriptBadge) {
  ASSERT_TRUE(test_server()->Start());
  ASSERT_TRUE(RunExtensionTest("keybinding/script_badge")) << message_;
  const Extension* extension = GetSingleLoadedExtension();
  ASSERT_TRUE(extension) << message_;

  {
    ResultCatcher catcher;
    // Tell the extension to update the script badge state.
    ui_test_utils::NavigateToURL(
        browser(), GURL(extension->GetResourceURL("show.html")));
    ASSERT_TRUE(catcher.GetNextResult());
  }

  {
    ResultCatcher catcher;
    // Activate the shortcut (Ctrl+Shift+F).
    ASSERT_TRUE(ui_test_utils::SendKeyPressSync(
        browser(), ui::VKEY_F, true, true, false, false));
    ASSERT_TRUE(catcher.GetNextResult());
  }
}

// This test validates that the getAll query API function returns registered
// commands as well as synthesized ones and that inactive commands (like the
// synthesized ones are in nature) have no shortcuts.
IN_PROC_BROWSER_TEST_F(CommandsApiTest, SynthesizedCommand) {
  ASSERT_TRUE(test_server()->Start());
  ASSERT_TRUE(RunExtensionTest("keybinding/synthesized")) << message_;
}

// This test validates that an extension cannot request a shortcut that is
// already in use by Chrome.
IN_PROC_BROWSER_TEST_F(CommandsApiTest, DontOverwriteSystemShortcuts) {
  ASSERT_TRUE(test_server()->Start());

  ASSERT_TRUE(ui_test_utils::BringBrowserWindowToFront(browser()));

  ASSERT_TRUE(RunExtensionTest("keybinding/dont_overwrite_system")) << message_;

  ui_test_utils::NavigateToURL(browser(),
      test_server()->GetURL("files/extensions/test_file.txt"));

  WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
  ASSERT_TRUE(tab);

  // Activate the shortcut (Alt+Shift+F) to make page blue.
  {
    ResultCatcher catcher;
    ASSERT_TRUE(ui_test_utils::SendKeyPressSync(
        browser(), ui::VKEY_F, false, true, true, false));
    ASSERT_TRUE(catcher.GetNextResult());
  }

  bool result = false;
  ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
      tab,
      "setInterval(function() {"
      "  if (document.body.bgColor == 'blue') {"
      "    window.domAutomationController.send(true)}}, 100)",
      &result));
  ASSERT_TRUE(result);

  // Activate the shortcut (Ctrl+F) to make page red (should not work).
  ASSERT_TRUE(ui_test_utils::SendKeyPressSync(
      browser(), ui::VKEY_F, true, false, false, false));

  // The page should still be blue.
  result = false;
  ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
      tab,
      "setInterval(function() {"
      "  if (document.body.bgColor == 'blue') {"
      "    window.domAutomationController.send(true)}}, 100)",
      &result));
  ASSERT_TRUE(result);
}

#if defined(OS_WIN)
// Currently this feature is implemented on Windows only.
#define MAYBE_AllowDuplicatedMediaKeys AllowDuplicatedMediaKeys
#else
#define MAYBE_AllowDuplicatedMediaKeys DISABLED_AllowDuplicatedMediaKeys
#endif

// Test that media keys go to all extensions that register for them.
IN_PROC_BROWSER_TEST_F(CommandsApiTest, MAYBE_AllowDuplicatedMediaKeys) {
  ResultCatcher catcher;
  ASSERT_TRUE(RunExtensionTest("keybinding/non_global_media_keys_0"))
      << message_;
  ASSERT_TRUE(catcher.GetNextResult());
  ASSERT_TRUE(RunExtensionTest("keybinding/non_global_media_keys_1"))
      << message_;
  ASSERT_TRUE(catcher.GetNextResult());

  // Activate the Media Stop key.
  ASSERT_TRUE(ui_test_utils::SendKeyPressSync(
      browser(), ui::VKEY_MEDIA_STOP, false, false, false, false));

  // We should get two success result.
  ASSERT_TRUE(catcher.GetNextResult());
  ASSERT_TRUE(catcher.GetNextResult());
}

// This test validates that update (including removal) of keybinding preferences
// works correctly.
IN_PROC_BROWSER_TEST_F(CommandsApiTest, UpdateKeybindingPrefsTest) {
#if defined(OS_MACOSX)
  // Send "Tab" on OS X to move the focus, otherwise the omnibox will intercept
  // the key presses we send below.
  ASSERT_TRUE(ui_test_utils::SendKeyPressSync(
      browser(), ui::VKEY_TAB, false, false, false, false));
#endif
  ResultCatcher catcher;
  ASSERT_TRUE(RunExtensionTest("keybinding/command_update"));
  ASSERT_TRUE(catcher.GetNextResult());
  const Extension* extension = GetSingleLoadedExtension();

  CommandService* command_service = CommandService::Get(browser()->profile());
  extensions::CommandMap named_commands;
  command_service->GetNamedCommands(extension->id(),
                                    extensions::CommandService::ACTIVE_ONLY,
                                    extensions::CommandService::ANY_SCOPE,
                                    &named_commands);
  EXPECT_EQ(3u, named_commands.size());

  const char kCommandNameC[] = "command_C";
  command_service->RemoveKeybindingPrefs(extension->id(), kCommandNameC);
  command_service->GetNamedCommands(extension->id(),
                                    extensions::CommandService::ACTIVE_ONLY,
                                    extensions::CommandService::ANY_SCOPE,
                                    &named_commands);
  EXPECT_EQ(2u, named_commands.size());

  // Send "Alt+C", it shouldn't work because it has been removed.
  ASSERT_TRUE(ui_test_utils::SendKeyPressSync(
      browser(), ui::VKEY_C, false, false, true, false));

  const char kCommandNameB[] = "command_B";
  const char kKeyStroke[] = "Alt+A";
  command_service->UpdateKeybindingPrefs(extension->id(),
                                         kCommandNameB,
                                         kKeyStroke);
  command_service->GetNamedCommands(extension->id(),
                                    extensions::CommandService::ACTIVE_ONLY,
                                    extensions::CommandService::ANY_SCOPE,
                                    &named_commands);
  EXPECT_EQ(1u, named_commands.size());

  // Activate the shortcut (Alt+A).
  ASSERT_TRUE(ui_test_utils::SendKeyPressSync(
      browser(), ui::VKEY_A, false, false, true, false));
  ASSERT_TRUE(catcher.GetNextResult()) << message_;
}

}  // namespace extensions
