// 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 "flutter/shell/common/shell_test.h"
#include "flutter/testing/testing.h"

// CREATE_NATIVE_ENTRY is leaky by design
// NOLINTBEGIN(clang-analyzer-core.StackAddressEscape)

namespace flutter {
namespace testing {

// Throughout these tests, the choice of time unit is irrelevant as long as all
// times have the same units.
using UnitlessTime = int;

// Signature of a generator function that takes the frame index as input and
// returns the time of that frame.
using Generator = std::function<UnitlessTime(int)>;

//----------------------------------------------------------------------------
/// Simulate n input events where the i-th one is delivered at delivery_time(i).
///
/// Simulation results will be written into events_consumed_at_frame whose
/// length will be equal to the number of frames drawn. Each element in the
/// vector is the number of input events consumed up to that frame. (We can't
/// return such vector because ASSERT_TRUE requires return type of void.)
///
/// We assume (and check) that the delivery latency is some base latency plus a
/// random latency where the random latency must be within one frame:
///
///   1.  latency = delivery_time(i) - j * frame_time = base_latency +
///       random_latency
///   2.  0 <= base_latency, 0 <= random_latency < frame_time
///
/// We also assume that there will be at least one input event per frame if
/// there were no latency. Let j = floor( (delivery_time(i) - base_latency) /
/// frame_time ) be the frame index if there were no latency. Then the set of j
/// should be all integers from 0 to continuous_frame_count - 1 for some
/// integer continuous_frame_count.
///
/// (Note that there coulds be multiple input events within one frame.)
///
/// The test here is insensitive to the choice of time unit as long as
/// delivery_time and frame_time are in the same unit.
static void TestSimulatedInputEvents(
    ShellTest* fixture,
    int num_events,
    UnitlessTime base_latency,
    Generator delivery_time,
    UnitlessTime frame_time,
    std::vector<UnitlessTime>& events_consumed_at_frame,
    bool restart_engine = false) {
  ///// Begin constructing shell ///////////////////////////////////////////////
  auto settings = fixture->CreateSettingsForFixture();
  std::unique_ptr<Shell> shell = fixture->CreateShell(settings, true);

  auto configuration = RunConfiguration::InferFromSettings(settings);
  configuration.SetEntrypoint("onPointerDataPacketMain");

  // The following 4 variables are only accessed in the UI thread by
  // nativeOnPointerDataPacket and nativeOnBeginFrame between their
  // initializations and `shell.reset()`.
  events_consumed_at_frame.clear();
  bool will_draw_new_frame = true;
  int events_consumed = 0;
  int frame_drawn = 0;
  auto nativeOnPointerDataPacket = [&events_consumed_at_frame,
                                    &will_draw_new_frame, &events_consumed,
                                    &frame_drawn](Dart_NativeArguments args) {
    events_consumed += 1;
    if (will_draw_new_frame) {
      frame_drawn += 1;
      will_draw_new_frame = false;
      events_consumed_at_frame.push_back(events_consumed);
    } else {
      events_consumed_at_frame.back() = events_consumed;
    }
  };
  fixture->AddNativeCallback("NativeOnPointerDataPacket",
                             CREATE_NATIVE_ENTRY(nativeOnPointerDataPacket));

  ASSERT_TRUE(configuration.IsValid());
  fixture->RunEngine(shell.get(), std::move(configuration));

  if (restart_engine) {
    auto new_configuration = RunConfiguration::InferFromSettings(settings);
    new_configuration.SetEntrypoint("onPointerDataPacketMain");
    ASSERT_TRUE(new_configuration.IsValid());
    fixture->RestartEngine(shell.get(), std::move(new_configuration));
  }
  ///// End constructing shell /////////////////////////////////////////////////

  ASSERT_GE(base_latency, 0);

  // Check that delivery_time satisfies our assumptions.
  int continuous_frame_count = 0;
  for (int i = 0; i < num_events; i += 1) {
    // j is the frame index of event i if there were no latency.
    int j = static_cast<int>((delivery_time(i) - base_latency) / frame_time);
    if (j == continuous_frame_count) {
      continuous_frame_count += 1;
    }
    double random_latency = delivery_time(i) - j * frame_time - base_latency;
    ASSERT_GE(random_latency, 0);
    ASSERT_LT(random_latency, frame_time);

    // If there were no latency, there should be at least one event per frame.
    // Hence j should never skip any integer less than continuous_frame_count.
    ASSERT_LT(j, continuous_frame_count);
  }

  // This has to be running on a different thread than Platform thread to avoid
  // dead locks.
  auto simulation = std::async(std::launch::async, [&]() {
    // i is the input event's index.
    // j is the frame's index.
    for (int i = 0, j = 0; i < num_events; j += 1) {
      double t = j * frame_time;
      while (i < num_events && delivery_time(i) <= t) {
        ShellTest::DispatchFakePointerData(shell.get());
        i += 1;
      }
      ShellTest::VSyncFlush(shell.get(), will_draw_new_frame);
    }
    // Finally, issue a vsync for the pending event that may be generated duing
    // the last vsync.
    ShellTest::VSyncFlush(shell.get(), will_draw_new_frame);
  });

  simulation.wait();

  TaskRunners task_runners = fixture->GetTaskRunnersForFixture();
  fml::AutoResetWaitableEvent latch;
  task_runners.GetPlatformTaskRunner()->PostTask([&shell, &latch]() mutable {
    shell.reset();
    latch.Signal();
  });
  latch.Wait();

  // Make sure that all events have been consumed so
  // https://github.com/flutter/flutter/issues/40863 won't happen again.
  ASSERT_EQ(events_consumed_at_frame.back(), num_events);
}

void CreateSimulatedPointerData(PointerData& data,
                                PointerData::Change change,
                                double dx,
                                double dy) {
  data.time_stamp = 0;
  data.change = change;
  data.kind = PointerData::DeviceKind::kTouch;
  data.signal_kind = PointerData::SignalKind::kNone;
  data.device = 0;
  data.pointer_identifier = 0;
  data.physical_x = dx;
  data.physical_y = dy;
  data.physical_delta_x = 0.0;
  data.physical_delta_y = 0.0;
  data.buttons = 0;
  data.obscured = 0;
  data.synthesized = 0;
  data.pressure = 0.0;
  data.pressure_min = 0.0;
  data.pressure_max = 0.0;
  data.distance = 0.0;
  data.distance_max = 0.0;
  data.size = 0.0;
  data.radius_major = 0.0;
  data.radius_minor = 0.0;
  data.radius_min = 0.0;
  data.radius_max = 0.0;
  data.orientation = 0.0;
  data.tilt = 0.0;
  data.platformData = 0;
  data.scroll_delta_x = 0.0;
  data.scroll_delta_y = 0.0;
  data.preferred_auxiliary_stylus_action =
      PointerData::PreferredStylusAuxiliaryAction::kIgnore;
}

TEST_F(ShellTest, MissAtMostOneFrameForIrregularInputEvents) {
  // We don't use `constexpr int frame_time` here because MSVC doesn't handle
  // it well with lambda capture.
  UnitlessTime frame_time = 10;
  UnitlessTime base_latency = 0.5 * frame_time;
  Generator extreme = [frame_time, base_latency](int i) {
    return static_cast<UnitlessTime>(
        i * frame_time + base_latency +
        (i % 2 == 0 ? 0.1 * frame_time : 0.9 * frame_time));
  };
  constexpr int n = 40;
  std::vector<int> events_consumed_at_frame;
  TestSimulatedInputEvents(this, n, base_latency, extreme, frame_time,
                           events_consumed_at_frame);
  int frame_drawn = events_consumed_at_frame.size();
  ASSERT_GE(frame_drawn, n - 1);

  // Make sure that it also works after an engine restart.
  TestSimulatedInputEvents(this, n, base_latency, extreme, frame_time,
                           events_consumed_at_frame, true /* restart_engine */);
  int frame_drawn_after_restart = events_consumed_at_frame.size();
  ASSERT_GE(frame_drawn_after_restart, n - 1);
}

TEST_F(ShellTest, DelayAtMostOneEventForFasterThanVSyncInputEvents) {
  // We don't use `constexpr int frame_time` here because MSVC doesn't handle
  // it well with lambda capture.
  UnitlessTime frame_time = 10;
  UnitlessTime base_latency = 0.2 * frame_time;
  Generator double_sampling = [frame_time, base_latency](int i) {
    return static_cast<UnitlessTime>(i * 0.5 * frame_time + base_latency);
  };
  constexpr int n = 40;
  std::vector<int> events_consumed_at_frame;
  TestSimulatedInputEvents(this, n, base_latency, double_sampling, frame_time,
                           events_consumed_at_frame);

  // Draw one extra frame due to delaying a pending packet for the next frame.
  int frame_drawn = events_consumed_at_frame.size();
  ASSERT_EQ(frame_drawn, n / 2 + 1);

  for (int i = 0; i < n / 2; i += 1) {
    ASSERT_GE(events_consumed_at_frame[i], 2 * i - 1);
  }
}

TEST_F(ShellTest, HandlesActualIphoneXsInputEvents) {
  // Actual delivery times measured on iPhone Xs, in the unit of frame_time
  // (16.67ms for 60Hz).
  static constexpr double iphone_xs_times[] = {0.15,
                                               1.0773046874999999,
                                               2.1738720703124996,
                                               3.0579052734374996,
                                               4.0890087890624995,
                                               5.0952685546875,
                                               6.1251708984375,
                                               7.1253076171875,
                                               8.125927734374999,
                                               9.37248046875,
                                               10.133950195312499,
                                               11.161201171875,
                                               12.226992187499999,
                                               13.1443798828125,
                                               14.440327148437499,
                                               15.091684570312498,
                                               16.138681640625,
                                               17.126469726562497,
                                               18.1592431640625,
                                               19.371372070312496,
                                               20.033774414062496,
                                               21.021782226562497,
                                               22.070053710937497,
                                               23.325541992187496,
                                               24.119648437499997,
                                               25.084262695312496,
                                               26.077866210937497,
                                               27.036547851562496,
                                               28.035073242187497,
                                               29.081411132812498,
                                               30.066064453124998,
                                               31.089360351562497,
                                               32.086142578125,
                                               33.4618798828125,
                                               34.14697265624999,
                                               35.0513525390625,
                                               36.136025390624994,
                                               37.1618408203125,
                                               38.144472656249995,
                                               39.201123046875,
                                               40.4339501953125,
                                               41.1552099609375,
                                               42.102128906249995,
                                               43.0426318359375,
                                               44.070131835937495,
                                               45.08862304687499,
                                               46.091469726562494};
  constexpr int n = sizeof(iphone_xs_times) / sizeof(iphone_xs_times[0]);
  // We don't use `constexpr int frame_time` here because MSVC doesn't handle
  // it well with lambda capture.
  UnitlessTime frame_time = 10000;
  double base_latency_f = 0.0;
  for (int i = 0; i < 10; i++) {
    base_latency_f += 0.1;
    // Everything is converted to int to avoid floating point error in
    // TestSimulatedInputEvents.
    UnitlessTime base_latency =
        static_cast<UnitlessTime>(base_latency_f * frame_time);
    Generator iphone_xs_generator = [frame_time, base_latency](int i) {
      return base_latency +
             static_cast<UnitlessTime>(iphone_xs_times[i] * frame_time);
    };
    std::vector<int> events_consumed_at_frame;
    TestSimulatedInputEvents(this, n, base_latency, iphone_xs_generator,
                             frame_time, events_consumed_at_frame);
    int frame_drawn = events_consumed_at_frame.size();
    ASSERT_GE(frame_drawn, n - 1);
  }
}

TEST_F(ShellTest, CanCorrectlyPipePointerPacket) {
  // Sets up shell with test fixture.
  auto settings = CreateSettingsForFixture();
  std::unique_ptr<Shell> shell = CreateShell(settings, true);

  auto configuration = RunConfiguration::InferFromSettings(settings);
  configuration.SetEntrypoint("onPointerDataPacketMain");
  // Sets up native handler.
  fml::AutoResetWaitableEvent reportLatch;
  std::vector<int64_t> result_sequence;
  auto nativeOnPointerDataPacket = [&reportLatch, &result_sequence](
                                       Dart_NativeArguments args) {
    Dart_Handle exception = nullptr;
    result_sequence = tonic::DartConverter<std::vector<int64_t>>::FromArguments(
        args, 0, exception);
    reportLatch.Signal();
  };
  // Starts engine.
  AddNativeCallback("NativeOnPointerDataPacket",
                    CREATE_NATIVE_ENTRY(nativeOnPointerDataPacket));
  ASSERT_TRUE(configuration.IsValid());
  RunEngine(shell.get(), std::move(configuration));
  // Starts test.
  auto packet = std::make_unique<PointerDataPacket>(6);
  PointerData data;
  CreateSimulatedPointerData(data, PointerData::Change::kAdd, 0.0, 0.0);
  packet->SetPointerData(0, data);
  CreateSimulatedPointerData(data, PointerData::Change::kHover, 3.0, 0.0);
  packet->SetPointerData(1, data);
  CreateSimulatedPointerData(data, PointerData::Change::kDown, 3.0, 0.0);
  packet->SetPointerData(2, data);
  CreateSimulatedPointerData(data, PointerData::Change::kMove, 3.0, 4.0);
  packet->SetPointerData(3, data);
  CreateSimulatedPointerData(data, PointerData::Change::kUp, 3.0, 4.0);
  packet->SetPointerData(4, data);
  CreateSimulatedPointerData(data, PointerData::Change::kRemove, 3.0, 4.0);
  packet->SetPointerData(5, data);
  ShellTest::DispatchPointerData(shell.get(), std::move(packet));
  bool will_draw_new_frame;
  ShellTest::VSyncFlush(shell.get(), will_draw_new_frame);

  reportLatch.Wait();
  size_t expect_length = 6;
  ASSERT_EQ(result_sequence.size(), expect_length);
  ASSERT_EQ(PointerData::Change(result_sequence[0]), PointerData::Change::kAdd);
  ASSERT_EQ(PointerData::Change(result_sequence[1]),
            PointerData::Change::kHover);
  ASSERT_EQ(PointerData::Change(result_sequence[2]),
            PointerData::Change::kDown);
  ASSERT_EQ(PointerData::Change(result_sequence[3]),
            PointerData::Change::kMove);
  ASSERT_EQ(PointerData::Change(result_sequence[4]), PointerData::Change::kUp);
  ASSERT_EQ(PointerData::Change(result_sequence[5]),
            PointerData::Change::kRemove);

  // Cleans up shell.
  ASSERT_TRUE(DartVMRef::IsInstanceRunning());
  DestroyShell(std::move(shell));
  ASSERT_FALSE(DartVMRef::IsInstanceRunning());
}

TEST_F(ShellTest, CanCorrectlySynthesizePointerPacket) {
  // Sets up shell with test fixture.
  auto settings = CreateSettingsForFixture();
  std::unique_ptr<Shell> shell = CreateShell(settings, true);

  auto configuration = RunConfiguration::InferFromSettings(settings);
  configuration.SetEntrypoint("onPointerDataPacketMain");
  // Sets up native handler.
  fml::AutoResetWaitableEvent reportLatch;
  std::vector<int64_t> result_sequence;
  auto nativeOnPointerDataPacket = [&reportLatch, &result_sequence](
                                       Dart_NativeArguments args) {
    Dart_Handle exception = nullptr;
    result_sequence = tonic::DartConverter<std::vector<int64_t>>::FromArguments(
        args, 0, exception);
    reportLatch.Signal();
  };
  // Starts engine.
  AddNativeCallback("NativeOnPointerDataPacket",
                    CREATE_NATIVE_ENTRY(nativeOnPointerDataPacket));
  ASSERT_TRUE(configuration.IsValid());
  RunEngine(shell.get(), std::move(configuration));
  // Starts test.
  auto packet = std::make_unique<PointerDataPacket>(4);
  PointerData data;
  CreateSimulatedPointerData(data, PointerData::Change::kAdd, 0.0, 0.0);
  packet->SetPointerData(0, data);
  CreateSimulatedPointerData(data, PointerData::Change::kDown, 3.0, 0.0);
  packet->SetPointerData(1, data);
  CreateSimulatedPointerData(data, PointerData::Change::kUp, 3.0, 4.0);
  packet->SetPointerData(2, data);
  CreateSimulatedPointerData(data, PointerData::Change::kRemove, 3.0, 4.0);
  packet->SetPointerData(3, data);
  ShellTest::DispatchPointerData(shell.get(), std::move(packet));
  bool will_draw_new_frame;
  ShellTest::VSyncFlush(shell.get(), will_draw_new_frame);

  reportLatch.Wait();
  size_t expect_length = 6;
  ASSERT_EQ(result_sequence.size(), expect_length);
  ASSERT_EQ(PointerData::Change(result_sequence[0]), PointerData::Change::kAdd);
  // The pointer data packet converter should synthesize a hover event.
  ASSERT_EQ(PointerData::Change(result_sequence[1]),
            PointerData::Change::kHover);
  ASSERT_EQ(PointerData::Change(result_sequence[2]),
            PointerData::Change::kDown);
  // The pointer data packet converter should synthesize a move event.
  ASSERT_EQ(PointerData::Change(result_sequence[3]),
            PointerData::Change::kMove);
  ASSERT_EQ(PointerData::Change(result_sequence[4]), PointerData::Change::kUp);
  ASSERT_EQ(PointerData::Change(result_sequence[5]),
            PointerData::Change::kRemove);

  // Cleans up shell.
  ASSERT_TRUE(DartVMRef::IsInstanceRunning());
  DestroyShell(std::move(shell));
  ASSERT_FALSE(DartVMRef::IsInstanceRunning());
}

}  // namespace testing
}  // namespace flutter

// NOLINTEND(clang-analyzer-core.StackAddressEscape)
