// 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"

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;
}

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;
  for (double base_latency_f = 0; base_latency_f < 1; 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
