// Copyright 2018 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/ui/fullscreen_keyboard_browsertest_base.h"

#include <memory>
#include <string>

#include "base/strings/string_util.h"
#include "base/strings/to_string.h"
#include "build/build_config.h"
#include "chrome/app/chrome_command_ids.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_commands.h"
#include "chrome/browser/ui/browser_list.h"
#include "chrome/browser/ui/browser_window/public/browser_window_features.h"
#include "chrome/browser/ui/browser_window/public/browser_window_interface_iterator.h"
#include "chrome/browser/ui/exclusive_access/exclusive_access_context.h"
#include "chrome/browser/ui/exclusive_access/exclusive_access_manager.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "chrome/test/base/interactive_test_utils.h"
#include "chrome/test/base/ui_test_utils.h"
#include "content/public/test/browser_test_utils.h"
#include "content/public/test/test_utils.h"
#include "third_party/blink/public/common/switches.h"
#include "ui/events/keycodes/dom/keycode_converter.h"
#include "ui/events/keycodes/keyboard_code_conversion.h"
#include "ui/events/keycodes/keyboard_codes.h"
#include "url/gurl.h"
#include "url/url_constants.h"

#if BUILDFLAG(IS_MAC)
#include "base/mac/mac_util.h"
#endif

namespace {

// The html file to receive key events, prevent defaults and export all the
// events with "getKeyEventReport()" function. It has two magic keys: pressing
// "S" to enter fullscreen mode; pressing "X" to indicate the end of all the
// keys (see FinishTestAndVerifyResult() function).
constexpr char kFullscreenKeyboardLockHTML[] =
    "/fullscreen_keyboardlock/fullscreen_keyboardlock.html";

// On MacOSX command key is used for most of the shortcuts, so replace it with
// control to reduce the complexity of comparison of the results.
void NormalizeMetaKeyForMacOS(std::string* output) {
#if BUILDFLAG(IS_MAC)
  base::ReplaceSubstringsAfterOffset(output, 0, "MetaLeft", "ControlLeft");
#endif
}

}  // namespace

FullscreenKeyboardBrowserTestBase::FullscreenKeyboardBrowserTestBase() =
    default;

FullscreenKeyboardBrowserTestBase::~FullscreenKeyboardBrowserTestBase() =
    default;

net::EmbeddedTestServer*
FullscreenKeyboardBrowserTestBase::GetEmbeddedTestServer() {
  return embedded_test_server();
}

bool FullscreenKeyboardBrowserTestBase::IsActiveTabFullscreen() const {
  auto* contents = GetActiveWebContents();
  return contents->GetDelegate()->IsFullscreenForTabOrPending(contents);
}

bool FullscreenKeyboardBrowserTestBase::IsInBrowserFullscreen() const {
  return GetActiveBrowser()
      ->GetFeatures()
      .exclusive_access_manager()
      ->fullscreen_controller()
      ->IsFullscreenForBrowser();
}

content::WebContents* FullscreenKeyboardBrowserTestBase::GetActiveWebContents()
    const {
  return GetActiveBrowser()->GetTabStripModel()->GetActiveWebContents();
}

int FullscreenKeyboardBrowserTestBase::GetActiveTabIndex() const {
  return GetActiveBrowser()->GetTabStripModel()->active_index();
}

int FullscreenKeyboardBrowserTestBase::GetTabCount() const {
  return GetActiveBrowser()->GetTabStripModel()->count();
}

size_t FullscreenKeyboardBrowserTestBase::GetBrowserCount() const {
  return BrowserList::GetInstance()->size();
}

BrowserWindowInterface* FullscreenKeyboardBrowserTestBase::GetActiveBrowser()
    const {
  return GetLastActiveBrowserWindowInterfaceWithAnyProfile();
}

BrowserWindowInterface*
FullscreenKeyboardBrowserTestBase::CreateNewBrowserInstance() {
  BrowserWindowInterface* const first_instance = GetActiveBrowser();
  const size_t initial_browser_count = GetBrowserCount();
  EXPECT_NO_FATAL_FAILURE(SendShortcut(ui::VKEY_N));
  WaitForBrowserCount(initial_browser_count + 1);
  BrowserWindowInterface* const second_instance = GetActiveBrowser();
  EXPECT_NE(first_instance, second_instance);

  return second_instance;
}

void FullscreenKeyboardBrowserTestBase::FocusOnLastActiveBrowser() {
  ASSERT_TRUE(ui_test_utils::BringBrowserWindowToFront(GetActiveBrowser()));
}

void FullscreenKeyboardBrowserTestBase::WaitForBrowserCount(size_t expected) {
  while (GetBrowserCount() != expected) {
    base::RunLoop().RunUntilIdle();
  }
}

void FullscreenKeyboardBrowserTestBase::WaitForTabCount(int expected) {
  while (GetTabCount() != expected) {
    base::RunLoop().RunUntilIdle();
  }
}

void FullscreenKeyboardBrowserTestBase::WaitForActiveTabIndex(int expected) {
  while (GetActiveTabIndex() != expected) {
    base::RunLoop().RunUntilIdle();
  }
}

void FullscreenKeyboardBrowserTestBase::WaitForInactiveTabIndex(int expected) {
  while (GetActiveTabIndex() == expected) {
    base::RunLoop().RunUntilIdle();
  }
}

void FullscreenKeyboardBrowserTestBase::StartFullscreenLockPage() {
  // Ensures the initial states.
  ASSERT_EQ(1, GetTabCount());
  ASSERT_EQ(0, GetActiveTabIndex());
  ASSERT_EQ(1U, GetBrowserCount());
  // Add a second tab for counting and focus purposes.
  ASSERT_TRUE(
      AddTabAtIndex(1, GURL(url::kAboutBlankURL), ui::PAGE_TRANSITION_LINK));
  ASSERT_EQ(2, GetTabCount());
  ASSERT_EQ(1U, GetBrowserCount());

  if (!GetEmbeddedTestServer()->Started()) {
    ASSERT_TRUE(GetEmbeddedTestServer()->Start());
  }
  ui_test_utils::NavigateToURLWithDisposition(
      GetActiveBrowser(),
      GetEmbeddedTestServer()->GetURL(kFullscreenKeyboardLockHTML),
      WindowOpenDisposition::CURRENT_TAB,
      ui_test_utils::BROWSER_TEST_WAIT_FOR_LOAD_STOP);
}

void FullscreenKeyboardBrowserTestBase::SendShortcut(ui::KeyboardCode key,
                                                     bool shift /* = false */) {
#if BUILDFLAG(IS_MAC)
  const bool control_modifier = false;
  const bool command_modifier = true;
#else
  const bool control_modifier = true;
  const bool command_modifier = false;
#endif
  ASSERT_TRUE(ui_test_utils::SendKeyPressSync(GetActiveBrowser(), key,
                                              control_modifier, shift, false,
                                              command_modifier));

  expected_result_ += ui::KeycodeConverter::DomCodeToCodeString(
      ui::UsLayoutKeyboardCodeToDomCode(key));
  expected_result_ += " ctrl:";
  expected_result_ += base::ToString(control_modifier);
  expected_result_ += " shift:";
  expected_result_ += base::ToString(shift);
  expected_result_ += " alt:false";
  expected_result_ += " meta:";
  expected_result_ += base::ToString(command_modifier);
  expected_result_ += '\n';
}

void FullscreenKeyboardBrowserTestBase::SendShiftShortcut(
    ui::KeyboardCode key) {
  ASSERT_NO_FATAL_FAILURE(SendShortcut(key, true));
}

void FullscreenKeyboardBrowserTestBase::SendFullscreenShortcutAndWait() {
  // On MacOSX, entering and exiting fullscreen are not synchronous. So we wait
  // for the observer to notice the change of fullscreen state.
  bool current = GetActiveBrowser()
                     ->GetFeatures()
                     .exclusive_access_manager()
                     ->context()
                     ->IsFullscreen();
  ui_test_utils::FullscreenWaiter waiter(
      GetActiveBrowser(), current
                              ? ui_test_utils::FullscreenWaiter::kNoFullscreen
                              : ui_test_utils::FullscreenWaiter::Expectation{
                                    .browser_fullscreen = true});
// Enter fullscreen.
#if BUILDFLAG(IS_MAC)
  // On MACOSX, Command + Control + F is used.
  ASSERT_TRUE(ui_test_utils::SendKeyPressSync(GetActiveBrowser(), ui::VKEY_F,
                                              true, false, false, true));
#elif BUILDFLAG(IS_CHROMEOS)
  // A dedicated fullscreen key is used on Chrome OS, so send a fullscreen
  // command directly instead, to avoid constructing the key press.
  ASSERT_TRUE(chrome::ExecuteCommand(GetActiveBrowser(), IDC_FULLSCREEN));
#else
  ASSERT_TRUE(ui_test_utils::SendKeyPressSync(GetActiveBrowser(), ui::VKEY_F11,
                                              false, false, false, false));
#endif

// Mac fullscreen is simulated in tests and is performed synchronously with the
// keyboard events. As a result, content doesn't actually know it has entered
// fullscreen. For more details, see ScopedFakeNSWindowFullscreen.
// TODO(crbug.com/41385780): Remove this once ScopedFakeNSWindowFullscreen fires
// OnFullscreenStateChanged.
#if !BUILDFLAG(IS_MAC)
  waiter.Wait();
#endif
}

void FullscreenKeyboardBrowserTestBase::SendJsFullscreenShortcutAndWait() {
  ui_test_utils::FullscreenWaiter waiter(GetActiveBrowser(),
                                         {.tab_fullscreen = true});
  ASSERT_TRUE(ui_test_utils::SendKeyPressSync(GetActiveBrowser(), ui::VKEY_S,
                                              false, false, false, false));
  expected_result_ += "KeyS ctrl:false shift:false alt:false meta:false\n";
  waiter.Wait();
  ASSERT_TRUE(IsActiveTabFullscreen());
}

void FullscreenKeyboardBrowserTestBase::SendEscape() {
  ASSERT_TRUE(ui_test_utils::SendKeyPressSync(
      GetActiveBrowser(), ui::VKEY_ESCAPE, false, false, false, false));
  expected_result_ += "Escape ctrl:false shift:false alt:false meta:false\n";
}

void FullscreenKeyboardBrowserTestBase::
    SendEscapeAndWaitForExitingFullscreen() {
  ui_test_utils::FullscreenWaiter waiter(GetActiveBrowser(),
                                         {.tab_fullscreen = false});
  ASSERT_TRUE(ui_test_utils::SendKeyPressSync(
      GetActiveBrowser(), ui::VKEY_ESCAPE, false, false, false, false));
  waiter.Wait();
  ASSERT_FALSE(IsActiveTabFullscreen());
}

void FullscreenKeyboardBrowserTestBase::SendShortcutsAndExpectPrevented() {
  const int initial_active_index = GetActiveTabIndex();
  const int initial_tab_count = GetTabCount();
  const size_t initial_browser_count = GetBrowserCount();
  // The tab should not be closed.
  ASSERT_NO_FATAL_FAILURE(SendShortcut(ui::VKEY_W));
  ASSERT_EQ(initial_tab_count, GetTabCount());
  // The window should not be closed.
  ASSERT_NO_FATAL_FAILURE(SendShiftShortcut(ui::VKEY_W));
  ASSERT_EQ(initial_browser_count, GetBrowserCount());
  // A new tab should not be created.
  ASSERT_NO_FATAL_FAILURE(SendShortcut(ui::VKEY_T));
  ASSERT_EQ(initial_tab_count, GetTabCount());
  // A new window should not be created.
  ASSERT_NO_FATAL_FAILURE(SendShortcut(ui::VKEY_N));
  ASSERT_EQ(initial_browser_count, GetBrowserCount());
  // A new incognito window should not be created.
  ASSERT_NO_FATAL_FAILURE(SendShiftShortcut(ui::VKEY_N));
  ASSERT_EQ(initial_browser_count, GetBrowserCount());
  // Last closed tab should not be restored.
  ASSERT_NO_FATAL_FAILURE(SendShiftShortcut(ui::VKEY_T));
  ASSERT_EQ(initial_tab_count, GetTabCount());
  // Browser should not switch to the next tab.
  ASSERT_NO_FATAL_FAILURE(SendShortcut(ui::VKEY_TAB));
  ASSERT_EQ(initial_active_index, GetActiveTabIndex());
  // Browser should not switch to the previous tab.
  ASSERT_NO_FATAL_FAILURE(SendShiftShortcut(ui::VKEY_TAB));
  ASSERT_EQ(initial_active_index, GetActiveTabIndex());
}

void FullscreenKeyboardBrowserTestBase::SendShortcutsAndExpectNotPrevented(
    bool js_fullscreen) {
  const int initial_active_index = GetActiveTabIndex();
  const int initial_tab_count = GetTabCount();
  const size_t initial_browser_count = GetBrowserCount();
  const auto enter_fullscreen = [this, js_fullscreen]() {
    ASSERT_TRUE(
        ui_test_utils::BringBrowserWindowToFront(this->GetActiveBrowser()));
    if (js_fullscreen) {
      if (!this->IsActiveTabFullscreen()) {
        static const std::string page =
            "<html><head></head><body></body><script>"
            "document.addEventListener('keydown', "
            "    (e) => {"
            "      if (e.code == 'KeyS') { "
            "        document.body.webkitRequestFullscreen();"
            "      }"
            "    });"
            "</script></html>";
        ui_test_utils::NavigateToURLWithDisposition(
            this->GetActiveBrowser(), GURL("data:text/html," + page),
            WindowOpenDisposition::CURRENT_TAB,
            ui_test_utils::BROWSER_TEST_WAIT_FOR_LOAD_STOP);
        ASSERT_NO_FATAL_FAILURE(this->SendJsFullscreenShortcutAndWait());
      }
    } else {
      if (!this->IsInBrowserFullscreen()) {
        ASSERT_NO_FATAL_FAILURE(this->SendFullscreenShortcutAndWait());
      }
      ASSERT_TRUE(this->IsInBrowserFullscreen());
    }
  };

  ASSERT_NO_FATAL_FAILURE(enter_fullscreen());

  // A new tab should be created and focused.
  ASSERT_NO_FATAL_FAILURE(SendShortcut(ui::VKEY_T));
  WaitForTabCount(initial_tab_count + 1);
  ASSERT_NE(initial_active_index, GetActiveTabIndex());

  ASSERT_NO_FATAL_FAILURE(enter_fullscreen());

  // The newly created tab should be closed.
  ASSERT_NO_FATAL_FAILURE(SendShortcut(ui::VKEY_W));
  WaitForTabCount(initial_tab_count);
  ASSERT_EQ(initial_active_index, GetActiveTabIndex());

  ASSERT_NO_FATAL_FAILURE(enter_fullscreen());

  // A new tab should be created and focused.
  ASSERT_NO_FATAL_FAILURE(SendShortcut(ui::VKEY_T));
  WaitForTabCount(initial_tab_count + 1);
  ASSERT_NE(initial_active_index, GetActiveTabIndex());

  ASSERT_NO_FATAL_FAILURE(enter_fullscreen());

  // The previous tab should be focused.
  ASSERT_TRUE(ui_test_utils::SendKeyPressSync(GetActiveBrowser(), ui::VKEY_TAB,
                                              true, true, false, false));
  WaitForActiveTabIndex(initial_active_index);
  ASSERT_EQ(initial_active_index, GetActiveTabIndex());

  ASSERT_NO_FATAL_FAILURE(enter_fullscreen());

  // The newly created tab should be focused.
  ASSERT_TRUE(ui_test_utils::SendKeyPressSync(GetActiveBrowser(), ui::VKEY_TAB,
                                              true, false, false, false));
  WaitForInactiveTabIndex(initial_active_index);
  ASSERT_NE(initial_active_index, GetActiveTabIndex());

  ASSERT_NO_FATAL_FAILURE(enter_fullscreen());

  // The newly created tab should be closed.
  ASSERT_NO_FATAL_FAILURE(SendShortcut(ui::VKEY_W));
  WaitForTabCount(initial_tab_count);
  ASSERT_EQ(initial_active_index, GetActiveTabIndex());

  ASSERT_NO_FATAL_FAILURE(enter_fullscreen());

  // A new window should be created and focused.
  ASSERT_NO_FATAL_FAILURE(SendShortcut(ui::VKEY_N));
  WaitForBrowserCount(initial_browser_count + 1);
  ASSERT_EQ(initial_browser_count + 1, GetBrowserCount());

  ASSERT_NO_FATAL_FAILURE(enter_fullscreen());

  // The newly created window should be closed.
  ASSERT_NO_FATAL_FAILURE(SendShiftShortcut(ui::VKEY_W));
  WaitForBrowserCount(initial_browser_count);

  ASSERT_EQ(initial_browser_count, GetBrowserCount());
  ASSERT_EQ(initial_active_index, GetActiveTabIndex());

  ASSERT_NO_FATAL_FAILURE(enter_fullscreen());
}

void FullscreenKeyboardBrowserTestBase::VerifyShortcutsAreNotPrevented() {
  const int initial_active_index = GetActiveTabIndex();
  const int initial_tab_count = GetTabCount();
  const size_t initial_browser_count = GetBrowserCount();

  // A new tab should be created and focused.
  ASSERT_NO_FATAL_FAILURE(SendShortcut(ui::VKEY_T));
  WaitForTabCount(initial_tab_count + 1);
  ASSERT_NE(initial_active_index, GetActiveTabIndex());

  // The newly created tab should be closed.
  ASSERT_NO_FATAL_FAILURE(SendShortcut(ui::VKEY_W));
  WaitForTabCount(initial_tab_count);
  ASSERT_EQ(initial_active_index, GetActiveTabIndex());

  // A new tab should be created and focused.
  ASSERT_NO_FATAL_FAILURE(SendShortcut(ui::VKEY_T));
  WaitForTabCount(initial_tab_count + 1);
  ASSERT_NE(initial_active_index, GetActiveTabIndex());

  // The previous tab should be focused.
  ASSERT_TRUE(ui_test_utils::SendKeyPressSync(GetActiveBrowser(), ui::VKEY_TAB,
                                              true, true, false, false));
  WaitForActiveTabIndex(initial_active_index);
  ASSERT_EQ(initial_active_index, GetActiveTabIndex());

  // The newly created tab should be focused.
  ASSERT_TRUE(ui_test_utils::SendKeyPressSync(GetActiveBrowser(), ui::VKEY_TAB,
                                              true, false, false, false));
  WaitForInactiveTabIndex(initial_active_index);
  ASSERT_NE(initial_active_index, GetActiveTabIndex());

  // The newly created tab should be closed.
  ASSERT_NO_FATAL_FAILURE(SendShortcut(ui::VKEY_W));
  WaitForTabCount(initial_tab_count);
  ASSERT_EQ(initial_active_index, GetActiveTabIndex());

  // A new window should be created and focused.
  ASSERT_NO_FATAL_FAILURE(SendShortcut(ui::VKEY_N));
  WaitForBrowserCount(initial_browser_count + 1);
  ASSERT_EQ(initial_browser_count + 1, GetBrowserCount());

  // The newly created window should be closed.
  ASSERT_NO_FATAL_FAILURE(SendShiftShortcut(ui::VKEY_W));
  WaitForBrowserCount(initial_browser_count);

  ASSERT_EQ(initial_browser_count, GetBrowserCount());
  ASSERT_EQ(initial_active_index, GetActiveTabIndex());
}

void FullscreenKeyboardBrowserTestBase::FinishTestAndVerifyResult() {
  // The renderer process receives key events through IPC channel,
  // SendKeyPressSync() cannot guarantee the JS has processed the key event it
  // sent. So we sent a KeyX to the webpage to indicate the end of the test
  // case. After processing this key event, web page is safe to send the record
  // back through window.domAutomationController.
  EXPECT_TRUE(ui_test_utils::SendKeyPressSync(GetActiveBrowser(), ui::VKEY_X,
                                              false, false, false, false));
  expected_result_ += "KeyX ctrl:false shift:false alt:false meta:false";
  std::string result =
      content::EvalJs(GetActiveWebContents(), "getKeyEventReport();")
          .ExtractString();
  NormalizeMetaKeyForMacOS(&result);
  NormalizeMetaKeyForMacOS(&expected_result_);
  base::TrimWhitespaceASCII(result, base::TRIM_ALL, &result);
  ASSERT_EQ(expected_result_, result);
}

std::string FullscreenKeyboardBrowserTestBase::GetFullscreenFramePath() {
  return kFullscreenKeyboardLockHTML;
}

void FullscreenKeyboardBrowserTestBase::SetUpOnMainThread() {
  ASSERT_TRUE(ui_test_utils::BringBrowserWindowToFront(GetActiveBrowser()));
}

void FullscreenKeyboardBrowserTestBase::SetUpCommandLine(
    base::CommandLine* command_line) {
  BrowserTestBase::SetUpCommandLine(command_line);
  command_line->AppendSwitch(blink::switches::kAllowPreCommitInput);
}
