// Copyright 2021 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <fidl/fuchsia.input.virtualkeyboard/cpp/fidl.h>
#include <fidl/fuchsia.ui.input3/cpp/fidl.h>
#include <lib/fit/function.h>

#include "base/fuchsia/fuchsia_logging.h"
#include "base/fuchsia/koid.h"
#include "base/fuchsia/scoped_service_binding.h"
#include "base/fuchsia/test_component_context_for_process.h"
#include "base/functional/callback.h"
#include "base/numerics/safe_conversions.h"
#include "base/strings/stringprintf.h"
#include "base/test/scoped_feature_list.h"
#include "content/public/test/browser_test.h"
#include "fuchsia_web/common/test/frame_for_test.h"
#include "fuchsia_web/common/test/frame_test_util.h"
#include "fuchsia_web/common/test/test_navigation_listener.h"
#include "fuchsia_web/webengine/browser/context_impl.h"
#include "fuchsia_web/webengine/browser/frame_impl.h"
#include "fuchsia_web/webengine/browser/mock_virtual_keyboard.h"
#include "fuchsia_web/webengine/features.h"
#include "fuchsia_web/webengine/test/scenic_test_helper.h"
#include "fuchsia_web/webengine/test/scoped_connection_checker.h"
#include "fuchsia_web/webengine/test/test_data.h"
#include "fuchsia_web/webengine/test/web_engine_browser_test.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace virtualkeyboard = fuchsia_input_virtualkeyboard;

namespace {

const gfx::Point kNoTarget = {999, 999};

constexpr char kInputFieldText[] = "input-text";
constexpr char kInputFieldModeTel[] = "input-mode-tel";
constexpr char kInputFieldModeNumeric[] = "input-mode-numeric";
constexpr char kInputFieldModeUrl[] = "input-mode-url";
constexpr char kInputFieldModeEmail[] = "input-mode-email";
constexpr char kInputFieldModeDecimal[] = "input-mode-decimal";
constexpr char kInputFieldModeSearch[] = "input-mode-search";
constexpr char kInputFieldTypeTel[] = "input-type-tel";
constexpr char kInputFieldTypeNumber[] = "input-type-number";
constexpr char kInputFieldTypePassword[] = "input-type-password";

class VirtualKeyboardTest : public WebEngineBrowserTest {
 public:
  VirtualKeyboardTest() {
    set_test_server_root(base::FilePath(kTestServerRoot));
  }
  ~VirtualKeyboardTest() override = default;

  void SetUp() override {
    scoped_feature_list_.InitWithFeatures(
        {features::kVirtualKeyboard, features::kKeyboardInput}, {});
    WebEngineBrowserTest::SetUp();
  }

  void SetUpOnMainThread() override {
    WebEngineBrowserTest::SetUpOnMainThread();
    ASSERT_TRUE(embedded_test_server()->Start());

    fuchsia::web::CreateFrameParams params;
    frame_for_test_ = FrameForTest::Create(context(), std::move(params));

    component_context_.emplace(
        base::TestComponentContextForProcess::InitialState::kCloneAll);
    controller_creator_.emplace(&component_context_.value());

    controller_ = controller_creator_->CreateController();

    // Ensure that the fuchsia.ui.input3.Keyboard service is connected.
    component_context_->additional_services()
        ->RemovePublicService<fuchsia_ui_input3::Keyboard>(
            fidl::DiscoverableProtocolName<fuchsia_ui_input3::Keyboard>);
    keyboard_input_checker_.emplace(component_context_->additional_services());

    fuchsia::web::NavigationControllerPtr controller;
    frame_for_test_.ptr()->GetNavigationController(controller.NewRequest());
    const GURL test_url(embedded_test_server()->GetURL("/input_fields.html"));
    EXPECT_TRUE(LoadUrlAndExpectResponse(
        controller.get(), fuchsia::web::LoadUrlParams(), test_url.spec()));
    frame_for_test_.navigation_listener().RunUntilUrlEquals(test_url);

    fuchsia::web::FramePtr* frame_ptr = &(frame_for_test_.ptr());
    web_contents_ =
        context_impl()->GetFrameImplForTest(frame_ptr)->web_contents();
    scenic_test_helper_.CreateScenicView(
        context_impl()->GetFrameImplForTest(frame_ptr), frame_for_test_.ptr());
    scenic_test_helper_.SetUpViewForInteraction(web_contents_);

    controller_->AwaitWatchAndRespondWith(false);
    ASSERT_EQ(
        base::GetKoid(controller_->view_ref().reference()).value(),
        base::GetKoid(scenic_test_helper_.CloneViewRef().reference).value());
  }

  void TearDownOnMainThread() override {
    frame_for_test_ = {};
    WebEngineBrowserTest::TearDownOnMainThread();
  }

  // The tests expect to have input processed immediately, even if the
  // content has not been displayed yet. That's fine for the test, but
  // we need to explicitly allow it.
  void SetUpCommandLine(base::CommandLine* command_line) override {
    command_line->AppendSwitch("allow-pre-commit-input");
  }

  gfx::Point GetCoordinatesOfInputField(base::StringPiece id) {
    // Distance to click from the top/left extents of an input field.
    constexpr int kInputFieldClickInset = 8;

    absl::optional<base::Value> result = ExecuteJavaScript(
        frame_for_test_.ptr().get(),
        base::StringPrintf("getPointInsideText('%.*s')",
                           base::saturated_cast<int>(id.length()), id.data()));
    if (!result || !result->is_dict()) {
      ADD_FAILURE() << "!result";
      return {};
    }

    // Note that coordinates are floating point and must be retrieved as such
    // from the Value, but we can cast them to integers and disregard the
    // fractional value with no major consequences.
    return gfx::Point(
        *result->GetDict().FindDouble("x") + kInputFieldClickInset,
        *result->GetDict().FindDouble("y") + kInputFieldClickInset);
  }

 protected:
  FrameForTest frame_for_test_;
  ScenicTestHelper scenic_test_helper_;
  base::test::ScopedFeatureList scoped_feature_list_;

  absl::optional<EnsureConnectedChecker<fuchsia_ui_input3::Keyboard>>
      keyboard_input_checker_;

  // Fake virtual keyboard services for the InputMethod to use.
  absl::optional<base::TestComponentContextForProcess> component_context_;
  absl::optional<MockVirtualKeyboardControllerCreator> controller_creator_;
  std::unique_ptr<MockVirtualKeyboardController> controller_;

  content::WebContents* web_contents_ = nullptr;
};

// Verifies that RequestShow() is not called redundantly if the virtual
// keyboard is reported as visible.
IN_PROC_BROWSER_TEST_F(VirtualKeyboardTest, ShowAndHideWithVisibility) {
  testing::InSequence s;

  // Alphanumeric field click.
  base::RunLoop on_show_run_loop;
  EXPECT_CALL(*controller_, RequestShow(testing::_))
      .WillOnce(testing::InvokeWithoutArgs(
          [&on_show_run_loop]() { on_show_run_loop.Quit(); }))
      .RetiresOnSaturation();

  // Numeric field click.
  base::RunLoop click_numeric_run_loop;
  EXPECT_CALL(*controller_, RequestHide(testing::_)).RetiresOnSaturation();
  EXPECT_CALL(
      *controller_,
      SetTextType(testing::Eq(MockVirtualKeyboardController::SetTextTypeRequest{
                      {.text_type = virtualkeyboard::TextType::kNumeric}}),
                  testing::_))
      .RetiresOnSaturation();
  EXPECT_CALL(*controller_, RequestShow(testing::_))
      .WillOnce(testing::InvokeWithoutArgs(
          [&click_numeric_run_loop]() { click_numeric_run_loop.Quit(); }))
      .RetiresOnSaturation();

  // Input blur click.
  base::RunLoop on_hide_run_loop;
  EXPECT_CALL(*controller_, RequestHide(testing::_))
      .WillOnce(testing::InvokeWithoutArgs(
          [&on_hide_run_loop]() { on_hide_run_loop.Quit(); }))
      .RetiresOnSaturation();

  // In some cases, Blink may signal an
  // InputMethodClient::OnTextInputTypeChanged event, which will cause
  // an extra call to VirtualKeyboardController:RequestHide. This is harmless
  // in practice due to RequestHide()'s idempotence, however we still need to
  // anticipate that behavior in the controller mocks.
  EXPECT_CALL(*controller_, RequestHide(testing::_)).Times(testing::AtMost(1));

  // Give focus to an alphanumeric input field, which will result in
  // RequestShow() being called.
  content::SimulateTapAt(web_contents_,
                         GetCoordinatesOfInputField(kInputFieldText));
  on_show_run_loop.Run();
  EXPECT_EQ(controller_->text_type(), virtualkeyboard::TextType::kAlphanumeric);

  // Indicate that the virtual keyboard is now visible.
  controller_->AwaitWatchAndRespondWith(true);
  base::RunLoop().RunUntilIdle();

  // Tap on another text field. RequestShow should not be called a second time
  // since the keyboard is already onscreen.
  content::SimulateTapAt(web_contents_,
                         GetCoordinatesOfInputField(kInputFieldModeNumeric));
  click_numeric_run_loop.Run();

  // Trigger input blur by clicking outside any input element.
  content::SimulateTapAt(web_contents_, kNoTarget);
  on_hide_run_loop.Run();
}

// Gives focus to a sequence of HTML <input> nodes with different InputModes,
// and verifies that the InputMode's FIDL equivalent is sent via SetTextType().
IN_PROC_BROWSER_TEST_F(VirtualKeyboardTest, InputModeMappings) {
  // Note that the service will elide type updates if there is no change,
  // so the array is ordered to produce an update on each entry.
  const std::vector<std::pair<base::StringPiece, virtualkeyboard::TextType>>
      kInputTypeMappings = {
          {kInputFieldModeTel, virtualkeyboard::TextType::kPhone},
          {kInputFieldModeSearch, virtualkeyboard::TextType::kAlphanumeric},
          {kInputFieldModeNumeric, virtualkeyboard::TextType::kNumeric},
          {kInputFieldModeUrl, virtualkeyboard::TextType::kAlphanumeric},
          {kInputFieldModeDecimal, virtualkeyboard::TextType::kNumeric},
          {kInputFieldModeEmail, virtualkeyboard::TextType::kAlphanumeric},
          {kInputFieldTypeTel, virtualkeyboard::TextType::kPhone},
          {kInputFieldTypeNumber, virtualkeyboard::TextType::kNumeric},
          {kInputFieldTypePassword, virtualkeyboard::TextType::kAlphanumeric},
      };

  // GMock expectations must be set upfront, hence the redundant for-each loop.
  testing::InSequence s;
  virtualkeyboard::TextType previous_text_type =
      virtualkeyboard::TextType::kAlphanumeric;
  std::vector<base::RunLoop> set_type_loops(std::size(kInputTypeMappings));
  for (size_t i = 0; i < std::size(kInputTypeMappings); ++i) {
    const auto& field_type_pair = kInputTypeMappings[i];
    EXPECT_NE(field_type_pair.second, previous_text_type);

    EXPECT_CALL(
        *controller_,
        SetTextType(
            testing::Eq(MockVirtualKeyboardController::SetTextTypeRequest{
                {.text_type = field_type_pair.second}}),
            testing::_))
        .WillOnce(testing::InvokeWithoutArgs(
            [run_loop = &set_type_loops[i]]() mutable { run_loop->Quit(); }))
        .RetiresOnSaturation();
    previous_text_type = field_type_pair.second;
  }

  controller_->AwaitWatchAndRespondWith(false);

  for (size_t i = 0; i < std::size(kInputTypeMappings); ++i) {
    content::SimulateTapAt(
        web_contents_, GetCoordinatesOfInputField(kInputTypeMappings[i].first));

    // Spin the runloop until we've received the type update.
    set_type_loops[i].Run();
  }
}

IN_PROC_BROWSER_TEST_F(VirtualKeyboardTest, Disconnection) {
  testing::InSequence s;
  base::RunLoop on_show_run_loop;
  EXPECT_CALL(*controller_, RequestShow(testing::_))
      .WillOnce([&on_show_run_loop](
                    MockVirtualKeyboardController::RequestShowCompleter::Sync&
                        completer) { on_show_run_loop.Quit(); });

  // Tapping inside the text field should show the IME and signal RequestShow.
  content::SimulateTapAt(web_contents_,
                         GetCoordinatesOfInputField(kInputFieldText));
  on_show_run_loop.Run();

  controller_->AwaitWatchAndRespondWith(true);
  base::RunLoop().RunUntilIdle();

  // Disconnect the FIDL service.
  controller_.reset();
  base::RunLoop().RunUntilIdle();

  // Focus on another text field, then defocus. Nothing should crash.
  content::SimulateTapAt(web_contents_,
                         GetCoordinatesOfInputField(kInputFieldModeNumeric));
  content::SimulateTapAt(web_contents_, kNoTarget);
}

}  // namespace
