// Copyright 2013 The Flutter 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 <fuchsia/accessibility/semantics/cpp/fidl.h>
#include <fuchsia/buildinfo/cpp/fidl.h>
#include <fuchsia/component/cpp/fidl.h>
#include <fuchsia/fonts/cpp/fidl.h>
#include <fuchsia/intl/cpp/fidl.h>
#include <fuchsia/kernel/cpp/fidl.h>
#include <fuchsia/memorypressure/cpp/fidl.h>
#include <fuchsia/metrics/cpp/fidl.h>
#include <fuchsia/net/interfaces/cpp/fidl.h>
#include <fuchsia/sysmem/cpp/fidl.h>
#include <fuchsia/tracing/provider/cpp/fidl.h>
#include <fuchsia/ui/app/cpp/fidl.h>
#include <fuchsia/ui/input/cpp/fidl.h>
#include <fuchsia/ui/policy/cpp/fidl.h>
#include <fuchsia/ui/scenic/cpp/fidl.h>
#include <fuchsia/ui/test/input/cpp/fidl.h>
#include <fuchsia/ui/test/scene/cpp/fidl.h>
#include <fuchsia/web/cpp/fidl.h>
#include <lib/async-loop/testing/cpp/real_loop.h>
#include <lib/async/cpp/task.h>
#include <lib/fidl/cpp/binding_set.h>
#include <lib/sys/component/cpp/testing/realm_builder.h>
#include <lib/sys/component/cpp/testing/realm_builder_types.h>
#include <lib/sys/cpp/component_context.h>
#include <lib/ui/scenic/cpp/resources.h>
#include <lib/ui/scenic/cpp/session.h>
#include <lib/ui/scenic/cpp/view_token_pair.h>
#include <lib/zx/clock.h>
#include <lib/zx/time.h>
#include <zircon/status.h>
#include <zircon/types.h>
#include <zircon/utc.h>

#include <cstddef>
#include <cstdint>
#include <iostream>
#include <memory>
#include <type_traits>
#include <utility>
#include <vector>

#include <gtest/gtest.h>

#include "flutter/fml/logging.h"
#include "flutter/shell/platform/fuchsia/flutter/tests/integration/utils/portable_ui_test.h"

// This test exercises the touch input dispatch path from Input Pipeline to a
// Scenic client. It is a multi-component test, and carefully avoids sleeping or
// polling for component coordination.
// - It runs real Root Presenter, Input Pipeline, and Scenic components.
// - It uses a fake display controller; the physical device is unused.
//
// Components involved
// - This test program
// - Input Pipeline
// - Root Presenter
// - Scenic
// - Child view, a Scenic client
//
// Touch dispatch path
// - Test program's injection -> Input Pipeline -> Scenic -> Child view
//
// Setup sequence
// - The test sets up this view hierarchy:
//   - Top level scene, owned by Root Presenter.
//   - Child view, owned by the ui client.
// - The test waits for a Scenic event that verifies the child has UI content in
// the scene graph.
// - The test injects input into Input Pipeline, emulating a display's touch
// report.
// - Input Pipeline dispatches the touch event to Scenic, which in turn
// dispatches it to the child.
// - The child receives the touch event and reports back to the test over a
// custom test-only FIDL.
// - Test waits for the child to report a touch; when the test receives the
// report, the test quits
//   successfully.
//
// This test uses the realm_builder library to construct the topology of
// components and routes services between them. For v2 components, every test
// driver component sits as a child of test_manager in the topology. Thus, the
// topology of a test driver component such as this one looks like this:
//
//     test_manager
//         |
//   touch-input-test.cml (this component)
//
// With the usage of the realm_builder library, we construct a realm during
// runtime and then extend the topology to look like:
//
//    test_manager
//         |
//   touch-input-test.cml (this component)
//         |
//   <created realm root>
//      /      \
//   scenic  input-pipeline
//
// For more information about testing v2 components and realm_builder,
// visit the following links:
//
// Testing: https://fuchsia.dev/fuchsia-src/concepts/testing/v2
// Realm Builder:
// https://fuchsia.dev/fuchsia-src/development/components/v2/realm_builder

namespace touch_input_test::testing {
namespace {
// Types imported for the realm_builder library.
using component_testing::ChildRef;
using component_testing::ConfigValue;
using component_testing::DirectoryContents;
using component_testing::LocalComponent;
using component_testing::LocalComponentHandles;
using component_testing::ParentRef;
using component_testing::Protocol;
using component_testing::Realm;
using component_testing::RealmRoot;
using component_testing::Route;

using fuchsia_test_utils::PortableUITest;

using RealmBuilder = component_testing::RealmBuilder;

// Max timeout in failure cases.
// Set this as low as you can that still works across all test platforms.
constexpr zx::duration kTimeout = zx::min(1);

constexpr auto kTestUIStackUrl =
    "fuchsia-pkg://fuchsia.com/gfx-root-presenter-test-ui-stack#meta/"
    "test-ui-stack.cm";

constexpr auto kMockTouchInputListener = "touch_input_listener";
constexpr auto kMockTouchInputListenerRef = ChildRef{kMockTouchInputListener};

constexpr auto kTouchInputView = "touch-input-view";
constexpr auto kTouchInputViewRef = ChildRef{kTouchInputView};
constexpr auto kTouchInputViewUrl =
    "fuchsia-pkg://fuchsia.com/touch-input-view#meta/touch-input-view.cm";
constexpr auto kEmbeddingFlutterView = "embedding-flutter-view";
constexpr auto kEmbeddingFlutterViewRef = ChildRef{kEmbeddingFlutterView};
constexpr auto kEmbeddingFlutterViewUrl =
    "fuchsia-pkg://fuchsia.com/embedding-flutter-view#meta/"
    "embedding-flutter-view.cm";

bool CompareDouble(double f0, double f1, double epsilon) {
  return std::abs(f0 - f1) <= epsilon;
}

// This component implements the TouchInput protocol
// and the interface for a RealmBuilder LocalComponent. A LocalComponent
// is a component that is implemented here in the test, as opposed to
// elsewhere in the system. When it's inserted to the realm, it will act
// like a proper component. This is accomplished, in part, because the
// realm_builder library creates the necessary plumbing. It creates a manifest
// for the component and routes all capabilities to and from it.
// LocalComponent:
// https://fuchsia.dev/fuchsia-src/development/testing/components/realm_builder#mock-components
class TouchInputListenerServer
    : public fuchsia::ui::test::input::TouchInputListener,
      public LocalComponent {
 public:
  explicit TouchInputListenerServer(async_dispatcher_t* dispatcher)
      : dispatcher_(dispatcher) {}

  // |fuchsia::ui::test::input::TouchInputListener|
  void ReportTouchInput(
      fuchsia::ui::test::input::TouchInputListenerReportTouchInputRequest
          request) override {
    FML_LOG(INFO) << "Received ReportTouchInput event";
    events_received_.push_back(std::move(request));
  }

  // |LocalComponent::Start|
  // When the component framework requests for this component to start, this
  // method will be invoked by the realm_builder library.
  void Start(std::unique_ptr<LocalComponentHandles> local_handles) override {
    FML_LOG(INFO) << "Starting TouchInputListenerServer";
    // When this component starts, add a binding to the
    // protocol to this component's outgoing directory.
    ASSERT_EQ(ZX_OK, local_handles->outgoing()->AddPublicService(
                         fidl::InterfaceRequestHandler<
                             fuchsia::ui::test::input::TouchInputListener>(
                             [this](auto request) {
                               bindings_.AddBinding(this, std::move(request),
                                                    dispatcher_);
                             })));
    local_handles_.emplace_back(std::move(local_handles));
  }

  const std::vector<
      fuchsia::ui::test::input::TouchInputListenerReportTouchInputRequest>&
  events_received() {
    return events_received_;
  }

 private:
  async_dispatcher_t* dispatcher_ = nullptr;
  std::vector<std::unique_ptr<LocalComponentHandles>> local_handles_;
  fidl::BindingSet<fuchsia::ui::test::input::TouchInputListener> bindings_;
  std::vector<
      fuchsia::ui::test::input::TouchInputListenerReportTouchInputRequest>
      events_received_;
};

class FlutterTapTestBase : public PortableUITest,
                           public ::testing::Test,
                           public ::testing::WithParamInterface<std::string> {
 protected:
  ~FlutterTapTestBase() override {
    FML_CHECK(touch_injection_request_count() > 0)
        << "Injection expected but didn't happen.";
  }

  void SetUp() override {
    PortableUITest::SetUp();

    // Post a "just in case" quit task, if the test hangs.
    async::PostDelayedTask(
        dispatcher(),
        [] {
          FML_LOG(FATAL)
              << "\n\n>> Test did not complete in time, terminating.  <<\n\n";
        },
        kTimeout);

    // Get the display dimensions.
    FML_LOG(INFO) << "Waiting for scenic display info";
    scenic_ = realm_root()->template Connect<fuchsia::ui::scenic::Scenic>();
    scenic_->GetDisplayInfo([this](fuchsia::ui::gfx::DisplayInfo display_info) {
      display_width_ = display_info.width_in_px;
      display_height_ = display_info.height_in_px;
      FML_LOG(INFO) << "Got display_width = " << display_width_
                    << " and display_height = " << display_height_;
    });
    RunLoopUntil(
        [this] { return display_width_ != 0 && display_height_ != 0; });

    // Register input injection device.
    FML_LOG(INFO) << "Registering input injection device";
    RegisterTouchScreen();
  }

  bool LastEventReceivedMatches(float expected_x,
                                float expected_y,
                                std::string component_name) {
    const auto& events_received =
        touch_input_listener_server_->events_received();

    if (events_received.empty()) {
      return false;
    }

    const auto& last_event = events_received.back();

    auto pixel_scale = last_event.has_device_pixel_ratio()
                           ? last_event.device_pixel_ratio()
                           : 1;

    auto actual_x = pixel_scale * last_event.local_x();
    auto actual_y = pixel_scale * last_event.local_y();
    auto actual_component = last_event.component_name();

    bool last_event_matches =
        CompareDouble(actual_x, expected_x, pixel_scale) &&
        CompareDouble(actual_y, expected_y, pixel_scale) &&
        last_event.component_name() == component_name;

    if (last_event_matches) {
      FML_LOG(INFO) << "Received event for component " << component_name
                    << " at (" << expected_x << ", " << expected_y << ")";
    } else {
      FML_LOG(WARNING) << "Expecting event for component " << component_name
                       << " at (" << expected_x << ", " << expected_y << "). "
                       << "Instead received event for component "
                       << actual_component << " at (" << actual_x << ", "
                       << actual_y << "), accounting for pixel scale of "
                       << pixel_scale;
    }

    return last_event_matches;
  }

  // Guaranteed to be initialized after SetUp().
  uint32_t display_width() const { return display_width_; }
  uint32_t display_height() const { return display_height_; }

  ParamType GetTestUIStackUrl() override { return GetParam(); };

  std::unique_ptr<TouchInputListenerServer> touch_input_listener_server_;
};

class FlutterTapTest : public FlutterTapTestBase {
 private:
  void ExtendRealm() override {
    FML_LOG(INFO) << "Extending realm";
    // Key part of service setup: have this test component vend the
    // |TouchInputListener| service in the constructed realm.
    touch_input_listener_server_ =
        std::make_unique<TouchInputListenerServer>(dispatcher());
    realm_builder()->AddLocalChild(kMockTouchInputListener,
                                   touch_input_listener_server_.get());

    // Add touch-input-view to the Realm
    realm_builder()->AddChild(kTouchInputView, kTouchInputViewUrl,
                              component_testing::ChildOptions{
                                  .environment = kFlutterRunnerEnvironment,
                              });

    // Route the TouchInput protocol capability to the Dart component
    realm_builder()->AddRoute(
        Route{.capabilities = {Protocol{
                  fuchsia::ui::test::input::TouchInputListener::Name_}},
              .source = kMockTouchInputListenerRef,
              .targets = {kFlutterJitRunnerRef, kTouchInputViewRef}});

    realm_builder()->AddRoute(
        Route{.capabilities = {Protocol{fuchsia::ui::app::ViewProvider::Name_}},
              .source = kTouchInputViewRef,
              .targets = {ParentRef()}});
  }
};

class FlutterEmbedTapTest : public FlutterTapTestBase {
 protected:
  void SetUp() override {
    PortableUITest::SetUp(false);

    // Post a "just in case" quit task, if the test hangs.
    async::PostDelayedTask(
        dispatcher(),
        [] {
          FML_LOG(FATAL)
              << "\n\n>> Test did not complete in time, terminating.  <<\n\n";
        },
        kTimeout);
  }

  void LaunchClientWithEmbeddedView() {
    BuildRealm();

    // Get the display dimensions.
    FML_LOG(INFO) << "Waiting for scenic display info";
    scenic_ = realm_root()->template Connect<fuchsia::ui::scenic::Scenic>();
    scenic_->GetDisplayInfo([this](fuchsia::ui::gfx::DisplayInfo display_info) {
      display_width_ = display_info.width_in_px;
      display_height_ = display_info.height_in_px;
      FML_LOG(INFO) << "Got display_width = " << display_width_
                    << " and display_height = " << display_height_;
    });
    RunLoopUntil(
        [this] { return display_width_ != 0 && display_height_ != 0; });

    // Register input injection device.
    FML_LOG(INFO) << "Registering input injection device";
    RegisterTouchScreen();

    PortableUITest::LaunchClientWithEmbeddedView();
  }

  // Helper method to add a component argument
  // This will be written into an args.csv file that can be parsed and read
  // by embedding-flutter-view.dart
  //
  // Note: You must call this method before LaunchClientWithEmbeddedView()
  // Realm Builder will not allow you to create a new directory / file in a
  // realm that's already been built
  void AddComponentArgument(std::string component_arg) {
    auto config_directory_contents = DirectoryContents();
    config_directory_contents.AddFile("args.csv", component_arg);
    realm_builder()->RouteReadOnlyDirectory(
        "config-data", {kEmbeddingFlutterViewRef},
        std::move(config_directory_contents));
  }

 private:
  void ExtendRealm() override {
    FML_LOG(INFO) << "Extending realm";
    // Key part of service setup: have this test component vend the
    // |TouchInputListener| service in the constructed realm.
    touch_input_listener_server_ =
        std::make_unique<TouchInputListenerServer>(dispatcher());
    realm_builder()->AddLocalChild(kMockTouchInputListener,
                                   touch_input_listener_server_.get());

    // Add touch-input-view to the Realm
    realm_builder()->AddChild(kTouchInputView, kTouchInputViewUrl,
                              component_testing::ChildOptions{
                                  .environment = kFlutterRunnerEnvironment,
                              });
    // Add embedding-flutter-view to the Realm
    // This component will embed touch-input-view as a child view
    realm_builder()->AddChild(kEmbeddingFlutterView, kEmbeddingFlutterViewUrl,
                              component_testing::ChildOptions{
                                  .environment = kFlutterRunnerEnvironment,
                              });

    // Route the TouchInput protocol capability to the Dart component
    realm_builder()->AddRoute(
        Route{.capabilities = {Protocol{
                  fuchsia::ui::test::input::TouchInputListener::Name_}},
              .source = kMockTouchInputListenerRef,
              .targets = {kFlutterJitRunnerRef, kTouchInputViewRef,
                          kEmbeddingFlutterViewRef}});

    realm_builder()->AddRoute(
        Route{.capabilities = {Protocol{fuchsia::ui::app::ViewProvider::Name_}},
              .source = kEmbeddingFlutterViewRef,
              .targets = {ParentRef()}});
    realm_builder()->AddRoute(
        Route{.capabilities = {Protocol{fuchsia::ui::app::ViewProvider::Name_}},
              .source = kTouchInputViewRef,
              .targets = {kEmbeddingFlutterViewRef}});
  }
};

// Makes use of gtest's parameterized testing, allowing us
// to test different combinations of test-ui-stack + runners. Currently, there
// is just one combination. Documentation:
// http://go/gunitadvanced#value-parameterized-tests
INSTANTIATE_TEST_SUITE_P(FlutterTapTestParameterized,
                         FlutterTapTest,
                         ::testing::Values(kTestUIStackUrl));

TEST_P(FlutterTapTest, FlutterTap) {
  // Launch client view, and wait until it's rendering to proceed with the test.
  FML_LOG(INFO) << "Initializing scene";
  LaunchClient();
  FML_LOG(INFO) << "Client launched";

  // touch-input-view logical coordinate space doesn't match the fake touch
  // screen injector's coordinate space, which spans [-1000, 1000] on both axes.
  // Scenic handles figuring out where in the coordinate space
  //  to inject a touch event (this is fixed to a display's bounds).
  InjectTap(-500, -500);
  // For a (-500 [x], -500 [y]) tap, we expect a touch event in the middle of
  // the upper-left quadrant of the screen.
  RunLoopUntil([this] {
    return LastEventReceivedMatches(
        /*expected_x=*/static_cast<float>(display_width() / 4.0f),
        /*expected_y=*/static_cast<float>(display_height() / 4.0f),
        /*component_name=*/"touch-input-view");
  });

  // There should be 1 injected tap
  ASSERT_EQ(touch_injection_request_count(), 1);
}

INSTANTIATE_TEST_SUITE_P(FlutterEmbedTapTestParameterized,
                         FlutterEmbedTapTest,
                         ::testing::Values(kTestUIStackUrl));

TEST_P(FlutterEmbedTapTest, FlutterEmbedTap) {
  // Launch view
  FML_LOG(INFO) << "Initializing scene";
  LaunchClientWithEmbeddedView();
  FML_LOG(INFO) << "Client launched";

  {
    // Embedded child view takes up the center of the screen
    // Expect a response from the child view if we inject a tap there
    InjectTap(0, 0);
    RunLoopUntil([this] {
      return LastEventReceivedMatches(
          /*expected_x=*/static_cast<float>(display_width() / 8.0f),
          /*expected_y=*/static_cast<float>(display_height() / 8.0f),
          /*component_name=*/"touch-input-view");
    });
  }

  {
    // Parent view takes up the rest of the screen
    // Validate that parent can still receive taps
    InjectTap(500, 500);
    RunLoopUntil([this] {
      return LastEventReceivedMatches(
          /*expected_x=*/static_cast<float>(display_width() / (4.0f / 3.0f)),
          /*expected_y=*/static_cast<float>(display_height() / (4.0f / 3.0f)),
          /*component_name=*/"embedding-flutter-view");
    });
  }

  // There should be 2 injected taps
  ASSERT_EQ(touch_injection_request_count(), 2);
}

TEST_P(FlutterEmbedTapTest, FlutterEmbedHittestDisabled) {
  FML_LOG(INFO) << "Initializing scene";
  AddComponentArgument("--no-hitTestable");
  LaunchClientWithEmbeddedView();
  FML_LOG(INFO) << "Client launched";

  // Embedded child view takes up the center of the screen
  // hitTestable is turned off for the embedded child view
  // Expect the parent (embedding-flutter-view) to respond if we inject a tap
  // there
  InjectTap(0, 0);
  RunLoopUntil([this] {
    return LastEventReceivedMatches(
        /*expected_x=*/static_cast<float>(display_width() / 2.0f),
        /*expected_y=*/static_cast<float>(display_height() / 2.0f),
        /*component_name=*/"embedding-flutter-view");
  });

  // There should be 1 injected tap
  ASSERT_EQ(touch_injection_request_count(), 1);
}

TEST_P(FlutterEmbedTapTest, FlutterEmbedOverlayEnabled) {
  FML_LOG(INFO) << "Initializing scene";
  AddComponentArgument("--showOverlay");
  LaunchClientWithEmbeddedView();
  FML_LOG(INFO) << "Client launched";

  {
    // The bottom-left corner of the overlay is at the center of the screen
    // Expect the overlay / parent view to respond if we inject a tap there
    // and not the embedded child view
    InjectTap(0, 0);
    RunLoopUntil([this] {
      return LastEventReceivedMatches(
          /*expected_x=*/static_cast<float>(display_width() / 2.0f),
          /*expected_y=*/static_cast<float>(display_height() / 2.0f),
          /*component_name=*/"embedding-flutter-view");
    });
  }

  {
    // The embedded child view is just outside of the bottom-left corner of the
    // overlay
    // Expect the embedded child view to still receive taps
    InjectTap(-1, -1);
    RunLoopUntil([this] {
      return LastEventReceivedMatches(
          /*expected_x=*/static_cast<float>(display_width() / 8.0f),
          /*expected_y=*/static_cast<float>(display_height() / 8.0f),
          /*component_name=*/"touch-input-view");
    });
  }

  // There should be 2 injected taps
  ASSERT_EQ(touch_injection_request_count(), 2);
}

}  // namespace
}  // namespace touch_input_test::testing
