// Copyright 2024 The Fuchsia 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 <fidl/fuchsia.component/cpp/fidl.h>
#include <fidl/fuchsia.hardware.sensors.realm/cpp/fidl.h>
#include <fidl/fuchsia.hardware.sensors/cpp/fidl.h>
#include <lib/async-loop/cpp/loop.h>
#include <lib/component/incoming/cpp/protocol.h>
#include <lib/fdio/directory.h>
#include <lib/fdio/namespace.h>
#include <lib/syslog/cpp/macros.h>
#include <lib/zx/vmo.h>
#include <zircon/syscalls.h>
#include <zircon/syscalls/clock.h>

#include <gtest/gtest.h>

#include "lib/component/incoming/cpp/service.h"
#include "src/sensors/playback/serialization.h"

using fuchsia_component::Namespace;
using fuchsia_component::NamespaceEntry;
using fuchsia_component::NamespaceInputEntry;
using fuchsia_hardware_sensors::Driver;
using fuchsia_hardware_sensors::Playback;
using fuchsia_hardware_sensors::Service;
using fuchsia_hardware_sensors_realm::RealmFactory;
using fuchsia_math::Vec3F;

using fuchsia_hardware_sensors::ConfigureSensorRateError;
using fuchsia_hardware_sensors::FilePlaybackConfig;
using fuchsia_hardware_sensors::FixedValuesPlaybackConfig;
using fuchsia_hardware_sensors::PlaybackSourceConfig;
using fuchsia_sensors_types::EventPayload;
using fuchsia_sensors_types::SensorEvent;
using fuchsia_sensors_types::SensorId;
using fuchsia_sensors_types::SensorInfo;
using fuchsia_sensors_types::SensorRateConfig;
using fuchsia_sensors_types::SensorReportingMode;
using fuchsia_sensors_types::SensorType;
using fuchsia_sensors_types::SensorWakeUpType;

using sensors::playback::io::Serializer;

constexpr SensorId kAccelSensorId = 1;
constexpr int kAccelEventLimit = 100;

constexpr SensorId kGyroSensorId = 2;
constexpr int kGyroEventLimit = 10;

namespace {
std::atomic_int32_t namespace_ctr{1};
}  // namespace

/* RealmFactory related boilerplate that will be replaced when there is a C++ client library */
class InstalledNamespace {
 public:
  InstalledNamespace(std::string prefix, zx::channel realm_factory)
      : prefix_(std::move(prefix)), realm_factory_(std::move(realm_factory)) {}
  ~InstalledNamespace() {
    fdio_ns_t* ns;
    EXPECT_EQ(fdio_ns_get_installed(&ns), ZX_OK);
    EXPECT_EQ(fdio_ns_unbind(ns, prefix_.c_str()), ZX_OK);
  }

  template <typename Interface>
  zx_status_t Connect(
      fidl::ServerEnd<Interface> request,
      const std::string& interface_name = fidl::DiscoverableProtocolName<Interface>) const {
    return Connect(interface_name, request.TakeChannel());
  }

  zx_status_t Connect(const std::string& interface_name, zx::channel request) const {
    const std::string path = prefix_ + "/" + interface_name;
    return fdio_service_connect(path.c_str(), request.release());
  }

  std::string prefix() const { return prefix_; }

 private:
  std::string prefix_;
  /// This is not used, but it keeps the RealmFactory connection alive.
  ///
  /// The RealmFactory server may use this connection to pin the lifetime of the realm created
  /// for the test.
  zx::channel realm_factory_;
};
template <typename Interface>
InstalledNamespace ExtendNamespace(
    fidl::ClientEnd<fuchsia_component_sandbox::Dictionary> dictionary,
    fidl::ClientEnd<Interface> realm_factory) {
  std::string prefix = std::string("/dict-") + std::to_string(namespace_ctr++);

  zx::result namespace_client_end = component::Connect<Namespace>();
  EXPECT_TRUE(namespace_client_end.is_ok());
  fidl::SyncClient<Namespace> ns_client(std::move(*namespace_client_end));

  std::vector<NamespaceInputEntry> entries;
  entries.emplace_back(NamespaceInputEntry{{
      .path = prefix,
      .dictionary = std::move(dictionary),
  }});
  fidl::Result<Namespace::Create> namespace_create_result = ns_client->Create(std::move(entries));
  EXPECT_TRUE(namespace_create_result.is_ok());

  std::vector<NamespaceEntry> namespace_entries =
      std::move(namespace_create_result.value().entries());
  EXPECT_EQ(namespace_entries.size(), 1u);
  auto& entry = namespace_entries[0];
  EXPECT_TRUE(entry.path() && entry.directory());
  EXPECT_EQ(entry.path(), prefix);

  fdio_ns_t* ns;
  EXPECT_EQ(fdio_ns_get_installed(&ns), ZX_OK);
  zx_handle_t dir_handle = entry.directory()->TakeChannel().release();
  EXPECT_EQ(fdio_ns_bind(ns, prefix.c_str(), dir_handle), ZX_OK);
  return InstalledNamespace(std::move(prefix), realm_factory.TakeChannel());
}
/* End of RealmFactory boilerplate. */

InstalledNamespace SetupNamespace() {
  zx::result realm_factory_client_end = component::Connect<RealmFactory>();
  EXPECT_TRUE(realm_factory_client_end.is_ok());
  fidl::SyncClient<RealmFactory> realm_factory(std::move(*realm_factory_client_end));

  auto [dictionary_client_end, dictionary_server_end] =
      fidl::Endpoints<fuchsia_component_sandbox::Dictionary>::Create();
  fidl::Result<RealmFactory::CreateRealm> create_realm_result =
      realm_factory->CreateRealm(std::move(dictionary_server_end));
  EXPECT_TRUE(create_realm_result.is_ok());

  return ExtendNamespace(std::move(dictionary_client_end), realm_factory.TakeClientEnd());
}

std::pair<fidl::ClientEnd<Playback>, fidl::ClientEnd<Driver>> CreateStandardEndpoints(
    InstalledNamespace& test_ns) {
  auto [playback_client_end, playback_server_end] = fidl::Endpoints<Playback>::Create();
  EXPECT_EQ(test_ns.Connect(std::move(playback_server_end)), ZX_OK);
  auto [driver_client_end, driver_server_end] = fidl::Endpoints<Driver>::Create();

  zx::result<fidl::ClientEnd<fuchsia_io::Directory>> svc =
      component::OpenServiceRoot(test_ns.prefix());
  EXPECT_TRUE(svc.is_ok());
  auto service = component::OpenServiceAt<Service>(svc.value(), "playback_sensor_driver");
  EXPECT_TRUE(service.is_ok());
  EXPECT_TRUE(service->connect_driver(std::move(driver_server_end)).is_ok());

  return std::make_pair(std::move(playback_client_end), std::move(driver_client_end));
}

class PlaybackEventHandler : public fidl::AsyncEventHandler<Playback> {
 public:
  PlaybackEventHandler(async::Loop& loop) : loop_(loop) {}

  void handle_unknown_event(fidl::UnknownEventMetadata<Playback> metadata) override {
    FX_LOGS(ERROR) << "Saw unknown event.";
    saw_error_ = true;
    loop_.Quit();
  }

  void on_fidl_error(fidl::UnbindInfo error) override {
    if (expecting_error_) {
      FX_LOGS(INFO) << "Saw aync error: " << error;
    } else {
      FX_LOGS(ERROR) << "Saw async error: " << error;
    }
    saw_error_ = true;
    error_ = error;
    loop_.Quit();
  }

  bool saw_error() { return saw_error_; }
  fidl::UnbindInfo error() { return error_; }
  void reset_error() {
    saw_error_ = false;
    error_ = fidl::UnbindInfo();
  }
  void expecting_error(bool expecting) { expecting_error_ = expecting; }

 private:
  bool expecting_error_ = false;
  bool saw_error_ = false;
  fidl::UnbindInfo error_;
  async::Loop& loop_;
};

class DriverEventHandler : public fidl::AsyncEventHandler<Driver> {
 public:
  DriverEventHandler(async::Loop& loop, uint64_t accel_event_limit = kAccelEventLimit,
                     uint64_t gyro_event_limit = kGyroEventLimit)
      : accel_event_limit_(accel_event_limit), gyro_event_limit_(gyro_event_limit), loop_(loop) {}

  void OnSensorEvent(fidl::Event<Driver::OnSensorEvent>& e) override {
    const SensorEvent& event = e.event();
    sensor_events_[event.sensor_id()].push_back(event);
    event_arrival_timestamps_[event.sensor_id()].push_back(zx::time(zx_clock_get_monotonic()));

    if (sensor_events_[event.sensor_id()].size() == 1) {
      FX_LOGS(INFO) << "Got first event from sensor " << event.sensor_id();
    }

    if (sensor_events_[kAccelSensorId].size() >= accel_event_limit_ &&
        sensor_events_[kGyroSensorId].size() >= gyro_event_limit_ && !saw_final_event_) {
      FX_LOGS(INFO) << "Got final event from sensor " << event.sensor_id();
      loop_.Quit();
      saw_final_event_ = true;
    }
  }

  void handle_unknown_event(fidl::UnknownEventMetadata<Driver> metadata) override {
    FX_LOGS(ERROR) << "Saw unknown event.";
    saw_error_ = true;
    loop_.Quit();
  }

  void on_fidl_error(fidl::UnbindInfo error) override {
    if (expecting_error_) {
      FX_LOGS(INFO) << "Saw aync error: " << error;
    } else {
      FX_LOGS(ERROR) << "Saw async error: " << error;
    }
    saw_error_ = true;
    error_ = error;
    loop_.Quit();
  }

  const std::unordered_map<SensorId, std::vector<SensorEvent>>& sensor_events() {
    return sensor_events_;
  }

  const std::unordered_map<SensorId, std::vector<zx::time>>& event_arrival_timestamps() {
    return event_arrival_timestamps_;
  }

  bool saw_error() { return saw_error_; }
  fidl::UnbindInfo error() { return error_; }
  void reset_error() {
    saw_error_ = false;
    error_ = fidl::UnbindInfo();
  }
  void expecting_error(bool expecting) { expecting_error_ = expecting; }

 private:
  const uint64_t accel_event_limit_;
  const uint64_t gyro_event_limit_;

  bool expecting_error_ = false;
  bool saw_error_ = false;
  fidl::UnbindInfo error_;

  bool saw_final_event_ = false;
  std::unordered_map<SensorId, std::vector<SensorEvent>> sensor_events_;
  std::unordered_map<SensorId, std::vector<zx::time>> event_arrival_timestamps_;
  async::Loop& loop_;
};

SensorInfo CreateAccelerometer(SensorId accel_sensor_id) {
  SensorInfo accelerometer_info;
  accelerometer_info.sensor_id(accel_sensor_id);
  accelerometer_info.name("accelerometer");
  accelerometer_info.vendor("Accelomax");
  accelerometer_info.version(1);
  accelerometer_info.sensor_type(SensorType::kAccelerometer);
  accelerometer_info.wake_up(SensorWakeUpType::kWakeUp);
  accelerometer_info.reporting_mode(SensorReportingMode::kContinuous);
  return accelerometer_info;
}

SensorInfo CreateGyroscope(SensorId gyro_sensor_id) {
  SensorInfo gyroscope_info;
  gyroscope_info.sensor_id(gyro_sensor_id);
  gyroscope_info.name("gyroscope");
  gyroscope_info.vendor("Gyrocorp");
  gyroscope_info.version(1);
  gyroscope_info.sensor_type(SensorType::kGyroscope);
  gyroscope_info.wake_up(SensorWakeUpType::kWakeUp);
  gyroscope_info.reporting_mode(SensorReportingMode::kContinuous);
  return gyroscope_info;
}

void CreateAccelerometerEvents(SensorId accel_sensor_id, int num_events,
                               std::vector<SensorEvent>& event_list) {
  const int64_t kOneMillisecondInNanoseconds = 1e6;
  for (int i = 0; i < num_events; i++) {
    Vec3F sample{{
        .x = i % 3 == 0 ? 1.0f : 0.0f,
        .y = i % 3 == 1 ? 1.0f : 0.0f,
        .z = i % 3 == 2 ? 1.0f : 0.0f,
    }};

    SensorEvent event{{.payload = EventPayload::WithVec3(sample)}};
    event.timestamp() = i * 10 * kOneMillisecondInNanoseconds;
    event.sensor_id() = accel_sensor_id;
    event.sensor_type() = SensorType::kAccelerometer;
    event.sequence_number() = i;

    event_list.push_back(event);
  }
}

void CreateGyroscopeEvents(SensorId gyro_sensor_id, int num_events,
                           std::vector<SensorEvent>& event_list) {
  const int64_t kOneMillisecondInNanoseconds = 1e6;
  for (int i = 0; i < num_events; i++) {
    Vec3F sample{{
        .x = i % 3 == 1 ? 1.0f : 0.0f,
        .y = i % 3 == 2 ? 1.0f : 0.0f,
        .z = i % 3 == 0 ? 1.0f : 0.0f,
    }};

    SensorEvent event{{.payload = EventPayload::WithVec3(sample)}};
    event.timestamp() = i * 100 * kOneMillisecondInNanoseconds;
    event.sensor_id() = gyro_sensor_id;
    event.sensor_type() = SensorType::kGyroscope;
    event.sequence_number() = i;

    event_list.push_back(event);
  }
}

const char kTestDatasetOutputPath[] = "/custom_artifacts/accel_gyro_dataset";
const int kNumUniqueFileAccelEvents = 200;
const int kNumUniqueFileGyroEvents = 20;
void CreateProtoDataFile() {
  // Generate a small dataset and write it to a file.
  const std::string dataset_name = "Test Dataset";
  std::vector<SensorInfo> sensor_list;
  std::vector<SensorEvent> event_list;

  sensor_list.push_back(CreateAccelerometer(kAccelSensorId));
  CreateAccelerometerEvents(kAccelSensorId, kNumUniqueFileAccelEvents, event_list);

  sensor_list.push_back(CreateGyroscope(kGyroSensorId));
  CreateGyroscopeEvents(kGyroSensorId, kNumUniqueFileGyroEvents, event_list);

  std::sort(event_list.begin(), event_list.end(), [](const SensorEvent& a, const SensorEvent& b) {
    return a.timestamp() < b.timestamp();
  });
  {
    Serializer serializer(kTestDatasetOutputPath);

    ASSERT_EQ(serializer.Open(dataset_name, sensor_list), ZX_OK);

    for (const SensorEvent& event : event_list) {
      ASSERT_EQ(serializer.WriteEvent(event, event.timestamp()), ZX_OK);
    }
  }
}

const int kNumUniqueFixedAccelEvents = 3;
const int kNumUniqueFixedGyroEvents = 3;
PlaybackSourceConfig CreateFixedValuesPlaybackConfig(std::vector<SensorInfo>& sensor_list) {
  std::vector<SensorEvent> fixed_event_list;

  sensor_list.push_back(CreateAccelerometer(kAccelSensorId));
  CreateAccelerometerEvents(kAccelSensorId, kNumUniqueFixedAccelEvents, fixed_event_list);

  sensor_list.push_back(CreateGyroscope(kGyroSensorId));
  CreateGyroscopeEvents(kGyroSensorId, kNumUniqueFixedGyroEvents, fixed_event_list);

  FixedValuesPlaybackConfig fixed_config;
  fixed_config.sensor_list(sensor_list);
  fixed_config.sensor_events(fixed_event_list);

  return PlaybackSourceConfig::WithFixedValuesConfig(fixed_config);
}

const char kTestDatasetInputPath[] = "/pkg/data/accel_gyro_dataset";
PlaybackSourceConfig CreateFilePlaybackConfig() {
  FilePlaybackConfig file_config;
  file_config.file_path(kTestDatasetInputPath);

  return PlaybackSourceConfig::WithFilePlaybackConfig(file_config);
}

struct TimestampDiffHistogram {
  // Number of bins.
  int num_bins;
  // Lower limit of lowest bin.
  int64_t lowest_bin_lower_limit;
  // Upper limit of the highest bin.
  int64_t highest_bin_upper_limit;
  // Width of each bin.
  uint64_t bin_width;

  // Total number of points
  unsigned long total_points;
  // Number of points below all the bins.
  int outliers_below;
  // List of (bin_index, bin_point_count) pairs.
  std::vector<std::pair<int, int>> bin_point_counts;
  // Number of points above all the bins.
  int outliers_above;
};

// Assumes timestamp_diffs is sorted in ascending order.
TimestampDiffHistogram CreateTimestampDiffHistogram(const std::vector<int64_t>& timestamp_diffs,
                                                    int64_t lowest_bin_lower_limit,
                                                    uint64_t bin_width, int num_bins) {
  TimestampDiffHistogram hist;
  hist.num_bins = num_bins;
  hist.lowest_bin_lower_limit = lowest_bin_lower_limit;
  hist.highest_bin_upper_limit = lowest_bin_lower_limit + (bin_width * num_bins);
  hist.bin_width = bin_width;
  hist.total_points = timestamp_diffs.size();
  hist.outliers_below = 0;
  hist.outliers_above = 0;

  int current_bin = 0;
  int current_bin_point_count = 0;
  int64_t current_bin_lower_limit = lowest_bin_lower_limit;
  int64_t current_bin_upper_limit = current_bin_lower_limit + bin_width;
  for (unsigned long i = 0; i < timestamp_diffs.size(); i++) {
    if (timestamp_diffs[i] < lowest_bin_lower_limit) {
      hist.outliers_below += 1;
      continue;
    }
    if (timestamp_diffs[i] >= hist.highest_bin_upper_limit) {
      hist.outliers_above += 1;
      continue;
    }

    if (timestamp_diffs[i] >= current_bin_lower_limit &&
        timestamp_diffs[i] < current_bin_upper_limit) {
      current_bin_point_count += 1;
    } else if (timestamp_diffs[i] >= current_bin_upper_limit) {
      // Store all the points we've counted so far for the bin (if there were any).
      if (current_bin_point_count > 0) {
        hist.bin_point_counts.push_back(std::make_pair(current_bin, current_bin_point_count));
      }
      // Move to the next bin and reconsider this data point.
      current_bin += 1;
      current_bin_point_count = 0;
      current_bin_lower_limit += bin_width;
      current_bin_upper_limit += bin_width;
      i -= 1;
    } else {
      FX_LOGS(ERROR) << "Saw data value out of order when making histogram.";
    }
  }
  if (current_bin_point_count > 0) {
    hist.bin_point_counts.push_back(std::make_pair(current_bin, current_bin_point_count));
  }

  return hist;
}

// Tests that the playback component only allows one Playback protocol client at a time.
TEST(SensorsPlaybackTest, MultiplePlaybackClientsRejected) {
  async::Loop loop(&kAsyncLoopConfigNeverAttachToThread);
  async_dispatcher_t* dispatcher = loop.dispatcher();
  PlaybackEventHandler handler(loop);
  PlaybackEventHandler handler2(loop);
  handler2.expecting_error(true);

  // Create first connection.
  auto test_ns = SetupNamespace();
  auto [playback_client_end, playback_server_end] = fidl::Endpoints<Playback>::Create();
  ASSERT_EQ(test_ns.Connect(std::move(playback_server_end)), ZX_OK);
  fidl::Client playback_client(std::move(playback_client_end), dispatcher, &handler);

  // Run an operation on the connection to make sure this one is actually connected first.
  std::vector<SensorInfo> sensor_list;
  std::optional<bool> result_ok;
  playback_client->ConfigurePlayback(CreateFixedValuesPlaybackConfig(sensor_list))
      .ThenExactlyOnce([&](fidl::Result<Playback::ConfigurePlayback>& result) {
        result_ok = result.is_ok();
        loop.Quit();
      });

  loop.Run();
  loop.ResetQuit();
  ASSERT_FALSE(handler.saw_error());
  ASSERT_TRUE(result_ok.has_value());
  ASSERT_TRUE(*result_ok);

  // Create the second connection.
  auto [playback_client_end2, playback_server_end2] = fidl::Endpoints<Playback>::Create();
  ASSERT_EQ(test_ns.Connect(std::move(playback_server_end2)), ZX_OK);
  fidl::Client playback_client2(std::move(playback_client_end2), dispatcher, &handler2);

  // Let the looper run until we get the asynchronous Playback disconnect error.
  loop.Run();
  loop.ResetQuit();
  EXPECT_FALSE(handler.saw_error());
  ASSERT_TRUE(handler2.saw_error());
}

// Tests that the playback component only allows one Driver protocol client at a time.
TEST(SensorsPlaybackTest, MultipleDriverClientsRejected) {
  async::Loop loop(&kAsyncLoopConfigNeverAttachToThread);
  async_dispatcher_t* dispatcher = loop.dispatcher();
  PlaybackEventHandler playback_handler(loop);
  DriverEventHandler handler(loop);
  DriverEventHandler handler2(loop);
  handler2.expecting_error(true);

  // Connect to both protocols and set a valid config just to keep the flow nominal up till
  // the second Driver connection.
  auto test_ns = SetupNamespace();
  auto [playback_client_end, driver_client_end] = CreateStandardEndpoints(test_ns);
  fidl::Client playback_client(std::move(playback_client_end), dispatcher, &playback_handler);
  fidl::Client driver_client(std::move(driver_client_end), dispatcher, &handler);

  std::vector<SensorInfo> sensor_list;
  std::optional<bool> result_ok;
  playback_client->ConfigurePlayback(CreateFixedValuesPlaybackConfig(sensor_list))
      .ThenExactlyOnce([&](fidl::Result<Playback::ConfigurePlayback>& result) {
        result_ok = result.is_ok();
        loop.Quit();
      });

  loop.Run();
  loop.ResetQuit();
  ASSERT_FALSE(handler.saw_error());
  ASSERT_TRUE(result_ok.has_value());
  ASSERT_TRUE(*result_ok);

  // Run an operation on the driver connection to make sure it is actually connected first.
  result_ok = std::nullopt;
  handler.reset_error();
  driver_client->GetSensorsList().ThenExactlyOnce(
      [&](fidl::Result<Driver::GetSensorsList>& result) {
        result_ok = result.is_ok();
        if (!result.is_ok()) {
          FX_LOGS(INFO) << "Saw error: " << result.error_value();
        }
        loop.Quit();
      });

  loop.Run();
  loop.ResetQuit();
  ASSERT_TRUE(result_ok.has_value());
  ASSERT_TRUE(*result_ok);
  ASSERT_FALSE(handler.saw_error());

  // Create the second connection.
  auto [driver_client_end2, driver_server_end2] = fidl::Endpoints<Driver>::Create();
  ASSERT_EQ(test_ns.Connect(std::move(driver_server_end2)), ZX_OK);
  fidl::Client driver_client2(std::move(driver_client_end2), dispatcher, &handler2);

  // Let the looper run until we get the asynchronous Driver disconnect error.
  loop.Run();
  loop.ResetQuit();
  EXPECT_FALSE(handler.saw_error());
  ASSERT_TRUE(handler2.saw_error());
}

// Tests that the playback component disconnects the Driver client if the Playback client
// disconnects.
TEST(SensorsPlaybackTest, DriverDisconnectsIfPlaybackDisconnects) {
  async::Loop loop(&kAsyncLoopConfigNeverAttachToThread);
  async_dispatcher_t* dispatcher = loop.dispatcher();
  DriverEventHandler handler(loop);

  // Connect to the Playback protocol and set a valid playback configuration.
  auto test_ns = SetupNamespace();
  auto [playback_client_end, playback_server_end] = fidl::Endpoints<Playback>::Create();
  ASSERT_EQ(test_ns.Connect(std::move(playback_server_end)), ZX_OK);
  std::optional<fidl::Client<Playback>> playback_client =
      fidl::Client<Playback>(std::move(playback_client_end), dispatcher);

  std::optional<bool> result_ok;
  std::vector<SensorInfo> sensor_list;
  (*playback_client)
      ->ConfigurePlayback(CreateFixedValuesPlaybackConfig(sensor_list))
      .ThenExactlyOnce([&](fidl::Result<Playback::ConfigurePlayback>& result) {
        result_ok = result.is_ok();
        loop.Quit();
      });
  loop.Run();
  loop.ResetQuit();
  ASSERT_FALSE(handler.saw_error());
  ASSERT_TRUE(result_ok.has_value());
  ASSERT_TRUE(*result_ok);

  // Connect to the Driver protocol and call a method to make sure it's connected.
  auto [driver_client_end, driver_server_end] = fidl::Endpoints<Driver>::Create();

  zx::result<fidl::ClientEnd<fuchsia_io::Directory>> svc =
      component::OpenServiceRoot(test_ns.prefix());
  ASSERT_TRUE(svc.is_ok());
  zx::result service = component::OpenServiceAt<Service>(*svc, "playback_sensor_driver");
  ASSERT_TRUE(service.is_ok());
  ASSERT_TRUE(service->connect_driver(std::move(driver_server_end)).is_ok());

  fidl::Client driver_client(std::move(driver_client_end), dispatcher, &handler);

  result_ok = std::nullopt;
  handler.reset_error();
  driver_client->GetSensorsList().ThenExactlyOnce(
      [&](fidl::Result<Driver::GetSensorsList>& result) {
        result_ok = result.is_ok();
        if (!result.is_ok()) {
          FX_LOGS(INFO) << "Saw error: " << result.error_value();
        }
        loop.Quit();
      });

  loop.Run();
  loop.ResetQuit();
  ASSERT_TRUE(result_ok.has_value());
  ASSERT_TRUE(*result_ok);
  ASSERT_FALSE(handler.saw_error());

  // Destroy the Playback connection. This will cause the playback configuration in the playback
  // component to be cleared and the Driver connection to be closed remotely. Set the handler to
  // expect an asynchronous error (the remote Driver connection closure).
  handler.expecting_error(true);
  playback_client = std::nullopt;

  // Let the looper run until we get the asynchronous Driver disconnect error.
  loop.Run();
  loop.ResetQuit();
  ASSERT_TRUE(handler.saw_error());
}

// Tests the following features of the playback component:
// - Play back a bunch of fixed valued sensor events provided by the client.
// - Generate "ideal" timestamps based on the configured sampling period.
// This does not test sensor data buffering (max reporting latency is set to 0).
TEST(SensorsPlaybackTest, FixedValues_Unbuffered_IdealScheduling) {
  async::Loop loop(&kAsyncLoopConfigNeverAttachToThread);
  async_dispatcher_t* dispatcher = loop.dispatcher();
  DriverEventHandler handler(loop);

  auto test_ns = SetupNamespace();
  auto [playback_client_end, driver_client_end] = CreateStandardEndpoints(test_ns);

  fidl::Client playback_client(std::move(playback_client_end), dispatcher);
  fidl::Client driver_client(std::move(driver_client_end), dispatcher, &handler);

  // Set fixed playback mode with the generated sensor list and set of events.
  std::vector<SensorInfo> sensor_list;
  std::optional<bool> result_ok = std::nullopt;
  playback_client->ConfigurePlayback(CreateFixedValuesPlaybackConfig(sensor_list))
      .ThenExactlyOnce([&](fidl::Result<Playback::ConfigurePlayback>& result) {
        result_ok = result.is_ok();
        loop.Quit();
      });

  loop.Run();
  loop.ResetQuit();
  ASSERT_TRUE(result_ok.has_value());
  ASSERT_TRUE(*result_ok);
  ASSERT_FALSE(handler.saw_error());

  // Check that we get back the sensor list we just configured.
  result_ok = std::nullopt;
  driver_client->GetSensorsList().ThenExactlyOnce(
      [&](fidl::Result<Driver::GetSensorsList>& result) {
        result_ok = sensor_list == result->sensor_list();
        loop.Quit();
      });

  loop.Run();
  loop.ResetQuit();
  ASSERT_TRUE(result_ok.has_value());
  ASSERT_TRUE(*result_ok);
  ASSERT_FALSE(handler.saw_error());

  // Accelerometer rate.
  SensorRateConfig accel_rate_config;
  accel_rate_config.sampling_period_ns(1e7);      // One hundredth of a second.
  accel_rate_config.max_reporting_latency_ns(0);  // No buffering.

  result_ok = std::nullopt;
  driver_client->ConfigureSensorRate({kAccelSensorId, accel_rate_config})
      .ThenExactlyOnce([&](fidl::Result<Driver::ConfigureSensorRate>& result) {
        result_ok = result.is_ok();
        loop.Quit();
      });

  loop.Run();
  loop.ResetQuit();
  ASSERT_TRUE(result_ok.has_value());
  ASSERT_TRUE(*result_ok);
  ASSERT_FALSE(handler.saw_error());

  // Gyroscope rate.
  SensorRateConfig gyro_rate_config;
  gyro_rate_config.sampling_period_ns(1e8);      // One tenth of a second.
  gyro_rate_config.max_reporting_latency_ns(0);  // No buffering.

  result_ok = std::nullopt;
  driver_client->ConfigureSensorRate({kGyroSensorId, gyro_rate_config})
      .ThenExactlyOnce([&](fidl::Result<Driver::ConfigureSensorRate>& result) {
        result_ok = result.is_ok();
        loop.Quit();
      });

  loop.Run();
  loop.ResetQuit();
  ASSERT_TRUE(result_ok.has_value());
  ASSERT_TRUE(*result_ok);
  ASSERT_FALSE(handler.saw_error());

  // Activate the accelerometer.
  std::optional<bool> accel_result_ok;
  driver_client->ActivateSensor({kAccelSensorId})
      .ThenExactlyOnce(
          [&](fidl::Result<Driver::ActivateSensor>& result) { accel_result_ok = result.is_ok(); });

  // Activate the gyroscope.
  std::optional<bool> gyro_result_ok;
  driver_client->ActivateSensor({kGyroSensorId})
      .ThenExactlyOnce(
          [&](fidl::Result<Driver::ActivateSensor>& result) { gyro_result_ok = result.is_ok(); });

  // Set deadline of 10 seconds and run.
  FX_LOGS(INFO) << "Waiting for sensor events.";
  zx_status_t run_result = loop.Run(zx::deadline_after(zx::sec(10)));
  loop.ResetQuit();

  if (run_result == ZX_ERR_TIMED_OUT) {
    FX_LOGS(ERROR) << "Timed out waiting for sensor events.";
  }

  ASSERT_TRUE(accel_result_ok.has_value());
  ASSERT_TRUE(*accel_result_ok);
  ASSERT_TRUE(gyro_result_ok.has_value());
  ASSERT_TRUE(*gyro_result_ok);
  ASSERT_EQ(run_result, ZX_ERR_CANCELED);
  ASSERT_FALSE(handler.saw_error());
  ASSERT_GE(handler.sensor_events().at(kAccelSensorId).size(), 100ul);
  ASSERT_GE(handler.sensor_events().at(kGyroSensorId).size(), 10ul);

  // Deactivate the accelerometer.
  accel_result_ok = std::nullopt;
  driver_client->DeactivateSensor({kAccelSensorId})
      .ThenExactlyOnce([&](fidl::Result<Driver::DeactivateSensor>& result) {
        accel_result_ok = result.is_ok();
        loop.Quit();
      });

  loop.Run();
  loop.ResetQuit();
  ASSERT_TRUE(accel_result_ok.has_value());
  ASSERT_TRUE(*accel_result_ok);
  ASSERT_FALSE(handler.saw_error());

  // Deactivate the gyroscope.
  gyro_result_ok = std::nullopt;
  driver_client->DeactivateSensor({kGyroSensorId})
      .ThenExactlyOnce([&](fidl::Result<Driver::DeactivateSensor>& result) {
        gyro_result_ok = result.is_ok();
        loop.Quit();
      });

  loop.Run();
  loop.ResetQuit();
  ASSERT_TRUE(gyro_result_ok.has_value());
  ASSERT_TRUE(*gyro_result_ok);
  ASSERT_FALSE(handler.saw_error());

  // Do some statistics on the timestamps to see if they make sense.
  const std::vector<zx::time>& accel_arrival_times =
      handler.event_arrival_timestamps().at(kAccelSensorId);

  // Calculate the differences between all the timestamps, then sort the differences.
  std::vector<int64_t> accel_arrival_diffs;
  for (unsigned long i = 1; i < accel_arrival_times.size(); ++i) {
    zx::duration arrival_diff = accel_arrival_times.at(i) - accel_arrival_times.at(i - 1);
    accel_arrival_diffs.push_back(arrival_diff.get());
  }
  std::sort(accel_arrival_diffs.begin(), accel_arrival_diffs.end());

  // Create a histogram of the timestamp differences. The bins will be 1e7 nanoseconds (0.01
  // seconds) wide. The bottom end of the lowest bin will start at -5e6 nanoseconds (or -0.005
  // seconds) and thus the lowest bin will be centered around 0. There will be 11 bins in total,
  // with the highest bin centered on 1e8 nanoseconds (0.1 seconds) and topping out at 1.05e8
  // nanoseconds (0.105 seconds).
  const int64_t kBottomBinLowerLimit = -5e6;
  const uint64_t kBinWidth = 1e7;
  const int64_t kNumBins = 11;
  TimestampDiffHistogram hist =
      CreateTimestampDiffHistogram(accel_arrival_diffs, kBottomBinLowerLimit, kBinWidth, kNumBins);

  /* The accelerometer is sampling at 100 Hz with no buffering.

     The expected histogram with perfect timing would be this:
     Bin    | 00 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 |
     -------*----*----*----*----*----*----*----*----*----*----*----*
     Points | 00 | 99 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 00 |

     Since buffering is not enabled, the events should be coming evenly spaced by the sampling
     period, which is 1e7 nanoseconds (0.01 seconds). Thus we would expect all 99 data points to
     fall into bin 1.

     Rather than assert that all of the timestamp differences fit exactly into their ideal bins,
     this test will merely assert that bin 1 contains the most points, followed by any outliers
     above. This will ensure the general shape of the timing is correct but reduce flakes by being
     incredibly robust to all but the most massive and repeated test environment performance hiccups
     hiccups (theoretically anyways).
  */

  // Outliers below the bottom bin should not be possible as all of the timestamp differences should
  // be positive.
  ASSERT_EQ(hist.outliers_below, 0);

  // Sort the per-bin point counts in descending order by count.
  std::sort(hist.bin_point_counts.begin(), hist.bin_point_counts.end(),
            [](const std::pair<int, int>& bin1, const std::pair<int, int>& bin2) {
              return bin1.second >= bin2.second;
            });

  // There should be data points in at least one bin.
  ASSERT_GE(hist.bin_point_counts.size(), 1u);
  // Assert the bin with the highest count is bin 1.
  ASSERT_EQ(hist.bin_point_counts[0].first, 1);

  // Outliers above the top bin could conceivably exist but it would be exceptionally unlikely for
  // there to be more of them than data points in bin 1.
  ASSERT_LT(hist.outliers_above, hist.bin_point_counts[0].second);
}

// Tests the following features of the playback component:
// - Play back a bunch of fixed valued sensor events provided by the client.
// - Generate "ideal" timestamps based on the configured sampling period.
// - Simulate hardware buffering of sensor data (use a maximum reporting
//   latency greater than 0).
TEST(SensorsPlaybackTest, FixedValues_Buffered_IdealScheduling) {
  async::Loop loop(&kAsyncLoopConfigNeverAttachToThread);
  async_dispatcher_t* dispatcher = loop.dispatcher();
  DriverEventHandler handler(loop);

  auto test_ns = SetupNamespace();
  auto [playback_client_end, driver_client_end] = CreateStandardEndpoints(test_ns);

  fidl::Client playback_client(std::move(playback_client_end), dispatcher);
  fidl::Client driver_client(std::move(driver_client_end), dispatcher, &handler);

  // Set fixed playback mode with the generated sensor list and set of events.
  std::vector<SensorInfo> sensor_list;
  std::optional<bool> result_ok;
  playback_client->ConfigurePlayback(CreateFixedValuesPlaybackConfig(sensor_list))
      .ThenExactlyOnce([&](fidl::Result<Playback::ConfigurePlayback>& result) {
        result_ok = result.is_ok();
        loop.Quit();
      });

  loop.Run();
  loop.ResetQuit();
  ASSERT_TRUE(result_ok.has_value());
  ASSERT_TRUE(*result_ok);
  ASSERT_FALSE(handler.saw_error());

  // Check that we get back the sensor list we just configured.
  result_ok = std::nullopt;
  driver_client->GetSensorsList().ThenExactlyOnce(
      [&](fidl::Result<Driver::GetSensorsList>& result) {
        result_ok = sensor_list == result->sensor_list();
        loop.Quit();
      });

  loop.Run();
  loop.ResetQuit();
  ASSERT_TRUE(result_ok.has_value());
  ASSERT_TRUE(*result_ok);
  ASSERT_FALSE(handler.saw_error());

  // Accelerometer rate.
  // Set a non-zero maximum reporting latency (one tenth of a second). This will
  // cause the playback component to simulate hardware FIFO buffering.
  SensorRateConfig accel_rate_config;
  accel_rate_config.sampling_period_ns(1e7);        // One hundredth of a second.
  accel_rate_config.max_reporting_latency_ns(1e8);  // One tenth of a second.

  result_ok = std::nullopt;
  driver_client->ConfigureSensorRate({kAccelSensorId, accel_rate_config})
      .ThenExactlyOnce([&](fidl::Result<Driver::ConfigureSensorRate>& result) {
        result_ok = result.is_ok();
        loop.Quit();
      });

  loop.Run();
  loop.ResetQuit();
  ASSERT_TRUE(result_ok.has_value());
  ASSERT_TRUE(*result_ok);
  ASSERT_FALSE(handler.saw_error());

  // Gyroscope rate.
  SensorRateConfig gyro_rate_config;
  gyro_rate_config.sampling_period_ns(1e8);      // One tenth of a second.
  gyro_rate_config.max_reporting_latency_ns(0);  // No buffering.

  result_ok = std::nullopt;
  driver_client->ConfigureSensorRate({kGyroSensorId, gyro_rate_config})
      .ThenExactlyOnce([&](fidl::Result<Driver::ConfigureSensorRate>& result) {
        result_ok = result.is_ok();
        loop.Quit();
      });

  loop.Run();
  loop.ResetQuit();
  ASSERT_TRUE(result_ok.has_value());
  ASSERT_TRUE(*result_ok);
  ASSERT_FALSE(handler.saw_error());

  // Activate the accelerometer.
  std::optional<bool> accel_result_ok;
  driver_client->ActivateSensor({kAccelSensorId})
      .ThenExactlyOnce(
          [&](fidl::Result<Driver::ActivateSensor>& result) { accel_result_ok = result.is_ok(); });

  // Activate the gyroscope.
  std::optional<bool> gyro_result_ok;
  driver_client->ActivateSensor({kGyroSensorId})
      .ThenExactlyOnce(
          [&](fidl::Result<Driver::ActivateSensor>& result) { gyro_result_ok = result.is_ok(); });

  // Set deadline of 10 seconds and run.
  FX_LOGS(INFO) << "Waiting for sensor events.";
  zx_status_t run_result = loop.Run(zx::deadline_after(zx::sec(10)));
  loop.ResetQuit();

  if (run_result == ZX_ERR_TIMED_OUT) {
    FX_LOGS(ERROR) << "Timed out waiting for sensor events.";
  }

  ASSERT_TRUE(accel_result_ok.has_value());
  ASSERT_TRUE(*accel_result_ok);
  ASSERT_TRUE(gyro_result_ok.has_value());
  ASSERT_TRUE(*gyro_result_ok);
  ASSERT_EQ(run_result, ZX_ERR_CANCELED);
  ASSERT_FALSE(handler.saw_error());
  ASSERT_GE(handler.sensor_events().at(kAccelSensorId).size(), 100ul);
  ASSERT_GE(handler.sensor_events().at(kGyroSensorId).size(), 10ul);

  // Deactivate the accelerometer.
  accel_result_ok = std::nullopt;
  driver_client->DeactivateSensor({kAccelSensorId})
      .ThenExactlyOnce([&](fidl::Result<Driver::DeactivateSensor>& result) {
        accel_result_ok = result.is_ok();
        loop.Quit();
      });

  loop.Run();
  loop.ResetQuit();
  ASSERT_TRUE(accel_result_ok.has_value());
  ASSERT_TRUE(*accel_result_ok);
  ASSERT_FALSE(handler.saw_error());

  // Deactivate the gyroscope.
  gyro_result_ok = std::nullopt;
  driver_client->DeactivateSensor({kGyroSensorId})
      .ThenExactlyOnce([&](fidl::Result<Driver::DeactivateSensor>& result) {
        gyro_result_ok = result.is_ok();
        loop.Quit();
      });

  loop.Run();
  loop.ResetQuit();
  ASSERT_TRUE(gyro_result_ok.has_value());
  ASSERT_TRUE(*gyro_result_ok);
  ASSERT_FALSE(handler.saw_error());

  // Do some statistics on the timestamps to see if they make sense.
  const std::vector<zx::time>& accel_arrival_times =
      handler.event_arrival_timestamps().at(kAccelSensorId);

  // Calculate the differences between all the timestamps, then sort the differences.
  std::vector<int64_t> accel_arrival_diffs;
  for (unsigned long i = 1; i < accel_arrival_times.size(); ++i) {
    zx::duration arrival_diff = accel_arrival_times.at(i) - accel_arrival_times.at(i - 1);
    accel_arrival_diffs.push_back(arrival_diff.get());
  }
  std::sort(accel_arrival_diffs.begin(), accel_arrival_diffs.end());

  // Create a histogram of the timestamp differences. The bins will be 1e7 nanoseconds (0.01
  // seconds) wide. The bottom end of the lowest bin will start at -5e6 nanoseconds (or -0.005
  // seconds) and thus the lowest bin will be centered around 0. There will be 11 bins in total,
  // with the highest bin centered on 1e8 nanoseconds (0.1 seconds) and topping out at 1.05e8
  // nanoseconds (0.105 seconds).
  const int64_t kBottomBinLowerLimit = -5e6;
  const uint64_t kBinWidth = 1e7;
  const int64_t kNumBins = 11;
  TimestampDiffHistogram hist =
      CreateTimestampDiffHistogram(accel_arrival_diffs, kBottomBinLowerLimit, kBinWidth, kNumBins);

  /* The accelerometer is sampling at 100 Hz, but with a buffer that is flushed at 10 Hz.

     The expected histogram with perfect timing would be this:
     Bin    | 00 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 |
     -------*----*----*----*----*----*----*----*----*----*----*----*
     Points | 90 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 09 |

     Since buffering is enabled, the events are coming in 10 bursts of 10. The timestamp difference
     between events in a burst will be very small, and thus we expect bin 0 to contain the most data
     points (90 ideally). In the 9 gaps between the 10 bursts we expect to see timestamp differences
     close to 0.1 seconds, and so ideally there should be 9 data points in bin 10.

     Rather than assert that all of the timestamp differences fit exactly into their ideal bins,
     this test will merely assert that bin 0 contains the most points, followed by bin 10, followed
     by any other bin or outliers above. This will ensure the general shape of the timing is correct
     but reduce flakes by being incredibly robust to all but the most massive and repeated test
     environment performance hiccups (theoretically anyways).
   */

  // Outliers below the bottom bin should not be possible as all of the timestamp differences should
  // be positive.
  ASSERT_EQ(hist.outliers_below, 0);

  // Sort the per-bin point counts in descending order by count.
  std::sort(hist.bin_point_counts.begin(), hist.bin_point_counts.end(),
            [](const std::pair<int, int>& bin1, const std::pair<int, int>& bin2) {
              return bin1.second >= bin2.second;
            });

  // There should be data points in at least two bins.
  ASSERT_GE(hist.bin_point_counts.size(), 2u);
  // Assert the bin with the highest count is bin 0.
  ASSERT_EQ(hist.bin_point_counts[0].first, 0);
  // Assert the bin with the next highest couint is bin 10.
  ASSERT_EQ(hist.bin_point_counts[1].first, 10);
}

// Uncomment this locally and run fx test with --ffx-output-directory <output_dir> in
// order to regenerate the file that the ProtoFile tests below expect.
TEST(SensorsPlaybackTest, DISABLED_GenerateTestDatasetProtoFile) { CreateProtoDataFile(); }

// Tests the following features of the playback component:
// - Play back data recorded to a binary protobuf file.
// - Uses the "receipt timestamps" of events in the dataset as "presentation timestamps" during
//   playback.
// This does not test sensor data buffering (max reporting latency is set to 0).
TEST(SensorsPlaybackTest, ProtoFile_Unbuffered_PresentationTimeScheduling) {
  // Expected sensor data.
  std::vector<SensorInfo> sensor_list;
  sensor_list.push_back(CreateAccelerometer(kAccelSensorId));
  sensor_list.push_back(CreateGyroscope(kGyroSensorId));

  // Play back the data from the file.
  async::Loop loop(&kAsyncLoopConfigNeverAttachToThread);
  async_dispatcher_t* dispatcher = loop.dispatcher();
  // Increase the event limits in the handler to make sure the file wraps a few times.
  DriverEventHandler handler(loop, 1000, 100);

  auto test_ns = SetupNamespace();
  auto [playback_client_end, driver_client_end] = CreateStandardEndpoints(test_ns);

  fidl::Client playback_client(std::move(playback_client_end), dispatcher);
  fidl::Client driver_client(std::move(driver_client_end), dispatcher, &handler);

  std::optional<bool> result_ok;
  playback_client->ConfigurePlayback(CreateFilePlaybackConfig())
      .ThenExactlyOnce([&](fidl::Result<Playback::ConfigurePlayback>& result) {
        result_ok = result.is_ok();
        loop.Quit();
      });

  loop.Run();
  loop.ResetQuit();
  ASSERT_TRUE(result_ok.has_value());
  ASSERT_TRUE(*result_ok);
  ASSERT_FALSE(handler.saw_error());

  // Check that we get the sensor list we expect from the file.
  result_ok = std::nullopt;
  std::vector<SensorInfo> result_list;
  driver_client->GetSensorsList().ThenExactlyOnce(
      [&](fidl::Result<Driver::GetSensorsList>& result) {
        result_list = result->sensor_list();
        loop.Quit();
      });

  loop.Run();
  loop.ResetQuit();
  ASSERT_FALSE(handler.saw_error());
  ASSERT_EQ(sensor_list, result_list);

  // Accelerometer rate. We expect the sampling period to be ignored.
  SensorRateConfig accel_rate_config;
  accel_rate_config.sampling_period_ns(1e7);      // One hundredth of a second.
  accel_rate_config.max_reporting_latency_ns(0);  // No buffering.

  result_ok = std::nullopt;
  driver_client->ConfigureSensorRate({kAccelSensorId, accel_rate_config})
      .ThenExactlyOnce([&](fidl::Result<Driver::ConfigureSensorRate>& result) {
        result_ok = result.is_ok();
        loop.Quit();
      });

  loop.Run();
  loop.ResetQuit();
  ASSERT_TRUE(result_ok.has_value());
  ASSERT_TRUE(*result_ok);
  ASSERT_FALSE(handler.saw_error());

  // Gyroscope rate. We expect the sampling period to be ignored.
  SensorRateConfig gyro_rate_config;
  gyro_rate_config.sampling_period_ns(1e8);      // One tenth of a second.
  gyro_rate_config.max_reporting_latency_ns(0);  // No buffering.

  result_ok = std::nullopt;
  driver_client->ConfigureSensorRate({kGyroSensorId, gyro_rate_config})
      .ThenExactlyOnce([&](fidl::Result<Driver::ConfigureSensorRate>& result) {
        result_ok = result.is_ok();
        loop.Quit();
      });

  loop.Run();
  loop.ResetQuit();
  ASSERT_TRUE(result_ok.has_value());
  ASSERT_TRUE(*result_ok);
  ASSERT_FALSE(handler.saw_error());

  // Activate the accelerometer.
  std::optional<bool> accel_result_ok;
  driver_client->ActivateSensor({kAccelSensorId})
      .ThenExactlyOnce(
          [&](fidl::Result<Driver::ActivateSensor>& result) { accel_result_ok = result.is_ok(); });

  // Activate the gyroscope.
  std::optional<bool> gyro_result_ok;
  driver_client->ActivateSensor({kGyroSensorId})
      .ThenExactlyOnce(
          [&](fidl::Result<Driver::ActivateSensor>& result) { gyro_result_ok = result.is_ok(); });

  // Set deadline of 20 seconds and run.
  FX_LOGS(INFO) << "Waiting for sensor events.";
  zx_status_t run_result = loop.Run(zx::deadline_after(zx::sec(20)));
  loop.ResetQuit();

  if (run_result == ZX_ERR_TIMED_OUT) {
    FX_LOGS(ERROR) << "Timed out waiting for sensor events.";
  }

  ASSERT_TRUE(accel_result_ok.has_value());
  ASSERT_TRUE(*accel_result_ok);
  ASSERT_TRUE(gyro_result_ok.has_value());
  ASSERT_TRUE(*gyro_result_ok);
  ASSERT_EQ(run_result, ZX_ERR_CANCELED);
  ASSERT_FALSE(handler.saw_error());
  ASSERT_GE(handler.sensor_events().at(kAccelSensorId).size(), 100ul);
  ASSERT_GE(handler.sensor_events().at(kGyroSensorId).size(), 10ul);

  // Deactivate the accelerometer.
  accel_result_ok = std::nullopt;
  driver_client->DeactivateSensor({kAccelSensorId})
      .ThenExactlyOnce([&](fidl::Result<Driver::DeactivateSensor>& result) {
        accel_result_ok = result.is_ok();
        loop.Quit();
      });

  loop.Run();
  loop.ResetQuit();
  ASSERT_TRUE(accel_result_ok.has_value());
  ASSERT_TRUE(*accel_result_ok);
  ASSERT_FALSE(handler.saw_error());

  // Deactivate the gyroscope.
  gyro_result_ok = std::nullopt;
  driver_client->DeactivateSensor({kGyroSensorId})
      .ThenExactlyOnce([&](fidl::Result<Driver::DeactivateSensor>& result) {
        gyro_result_ok = result.is_ok();
        loop.Quit();
      });

  loop.Run();
  loop.ResetQuit();
  ASSERT_TRUE(gyro_result_ok.has_value());
  ASSERT_TRUE(*gyro_result_ok);
  ASSERT_FALSE(handler.saw_error());

  // Do some statistics on the timestamps to see if they make sense.
  const std::vector<zx::time>& accel_arrival_times =
      handler.event_arrival_timestamps().at(kAccelSensorId);

  // Calculate the differences between all the timestamps, then sort the differences.
  std::vector<int64_t> accel_arrival_diffs;
  for (unsigned long i = 1; i < accel_arrival_times.size(); ++i) {
    zx::duration arrival_diff = accel_arrival_times.at(i) - accel_arrival_times.at(i - 1);
    accel_arrival_diffs.push_back(arrival_diff.get());
  }
  std::sort(accel_arrival_diffs.begin(), accel_arrival_diffs.end());

  // Create a histogram of the timestamp differences. The bins will be 1e7 nanoseconds (0.01
  // seconds) wide. The bottom end of the lowest bin will start at -5e6 nanoseconds (or -0.005
  // seconds) and thus the lowest bin will be centered around 0. There will be 11 bins in total,
  // with the highest bin centered on 1e8 nanoseconds (0.1 seconds) and topping out at 1.05e8
  // nanoseconds (0.105 seconds).
  const int64_t kBottomBinLowerLimit = -5e6;
  const uint64_t kBinWidth = 1e7;
  const int64_t kNumBins = 11;
  TimestampDiffHistogram hist =
      CreateTimestampDiffHistogram(accel_arrival_diffs, kBottomBinLowerLimit, kBinWidth, kNumBins);

  /* The accelerometer is sampling at 100 Hz with no buffering.

     The expected histogram with perfect timing would be this:
     Bin    | 00 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 |
     -------*----*----*----*----*----*----*----*----*----*----*----*
     Points | 00 | 99 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 00 |

     Since buffering is not enabled, the events should be coming evenly spaced by the sampling
     period, which is 1e7 nanoseconds (0.01 seconds). Thus we would expect all 99 data points to
     fall into bin 1.

     Rather than assert that all of the timestamp differences fit exactly into their ideal bins,
     this test will merely assert that bin 1 contains the most points, followed by any outliers
     above. This will ensure the general shape of the timing is correct but reduce flakes by being
     incredibly robust to all but the most massive and repeated test environment performance hiccups
     hiccups (theoretically anyways).
   */

  // Outliers below the bottom bin should not be possible as all of the timestamp differences should
  // be positive.
  ASSERT_EQ(hist.outliers_below, 0);

  // Sort the per-bin point counts in descending order by count.
  std::sort(hist.bin_point_counts.begin(), hist.bin_point_counts.end(),
            [](const std::pair<int, int>& bin1, const std::pair<int, int>& bin2) {
              return bin1.second >= bin2.second;
            });

  // There should be data points in at least one bin.
  ASSERT_GE(hist.bin_point_counts.size(), 1u);
  // Assert the bin with the highest count is bin 1.
  ASSERT_EQ(hist.bin_point_counts[0].first, 1);

  // Outliers above the top bin could conceivably exist but it would be exceptionally unlikely for
  // there to be more of them than data points in bin 1.
  ASSERT_LT(hist.outliers_above, hist.bin_point_counts[0].second);
}

// Tests the following features of the playback component:
// - Play back data recorded to a binary protobuf file.
// - Uses the "receipt timestamps" of events in the dataset as "presentation timestamps" during
//   playback.
// - Simulate hardware buffering of sensor data (use a maximum reporting
//   latency greater than 0).
TEST(SensorsPlaybackTest, ProtoFile_Buffered_PresentationTimeScheduling) {
  // Expected sensor data.
  std::vector<SensorInfo> sensor_list;
  sensor_list.push_back(CreateAccelerometer(kAccelSensorId));
  sensor_list.push_back(CreateGyroscope(kGyroSensorId));

  // Play back the data from the file.
  async::Loop loop(&kAsyncLoopConfigNeverAttachToThread);
  async_dispatcher_t* dispatcher = loop.dispatcher();
  // Increase the event limits in the handler to make sure the file wraps a few times.
  DriverEventHandler handler(loop, 1000, 100);

  auto test_ns = SetupNamespace();
  auto [playback_client_end, driver_client_end] = CreateStandardEndpoints(test_ns);

  fidl::Client playback_client(std::move(playback_client_end), dispatcher);
  fidl::Client driver_client(std::move(driver_client_end), dispatcher, &handler);

  std::optional<bool> result_ok;
  playback_client->ConfigurePlayback(CreateFilePlaybackConfig())
      .ThenExactlyOnce([&](fidl::Result<Playback::ConfigurePlayback>& result) {
        result_ok = result.is_ok();
        loop.Quit();
      });

  loop.Run();
  loop.ResetQuit();
  ASSERT_TRUE(result_ok.has_value());
  ASSERT_TRUE(*result_ok);
  ASSERT_FALSE(handler.saw_error());

  // Check that we get the sensor list we expect from the file.
  result_ok = std::nullopt;
  std::vector<SensorInfo> result_list;
  driver_client->GetSensorsList().ThenExactlyOnce(
      [&](fidl::Result<Driver::GetSensorsList>& result) {
        result_list = result->sensor_list();
        loop.Quit();
      });

  loop.Run();
  loop.ResetQuit();
  ASSERT_FALSE(handler.saw_error());
  ASSERT_EQ(sensor_list, result_list);

  // Accelerometer rate. We expect the sampling period to be ignored.
  SensorRateConfig accel_rate_config;
  accel_rate_config.sampling_period_ns(1e7);        // One hundredth of a second.
  accel_rate_config.max_reporting_latency_ns(1e8);  // One tenth of a second.

  result_ok = std::nullopt;
  driver_client->ConfigureSensorRate({kAccelSensorId, accel_rate_config})
      .ThenExactlyOnce([&](fidl::Result<Driver::ConfigureSensorRate>& result) {
        result_ok = result.is_ok();
        loop.Quit();
      });

  loop.Run();
  loop.ResetQuit();
  ASSERT_TRUE(result_ok.has_value());
  ASSERT_TRUE(*result_ok);
  ASSERT_FALSE(handler.saw_error());

  // Gyroscope rate. We expect the sampling period to be ignored.
  SensorRateConfig gyro_rate_config;
  gyro_rate_config.sampling_period_ns(1e8);      // One tenth of a second.
  gyro_rate_config.max_reporting_latency_ns(0);  // No buffering.

  result_ok = std::nullopt;
  driver_client->ConfigureSensorRate({kGyroSensorId, gyro_rate_config})
      .ThenExactlyOnce([&](fidl::Result<Driver::ConfigureSensorRate>& result) {
        result_ok = result.is_ok();
        loop.Quit();
      });

  loop.Run();
  loop.ResetQuit();
  ASSERT_TRUE(result_ok.has_value());
  ASSERT_TRUE(*result_ok);
  ASSERT_FALSE(handler.saw_error());

  // Activate the accelerometer.
  std::optional<bool> accel_result_ok;
  driver_client->ActivateSensor({kAccelSensorId})
      .ThenExactlyOnce(
          [&](fidl::Result<Driver::ActivateSensor>& result) { accel_result_ok = result.is_ok(); });

  // Activate the gyroscope.
  std::optional<bool> gyro_result_ok;
  driver_client->ActivateSensor({kGyroSensorId})
      .ThenExactlyOnce(
          [&](fidl::Result<Driver::ActivateSensor>& result) { gyro_result_ok = result.is_ok(); });

  // Set deadline of 10 seconds and run.
  FX_LOGS(INFO) << "Waiting for sensor events.";
  zx_status_t run_result = loop.Run(zx::deadline_after(zx::sec(20)));
  loop.ResetQuit();

  if (run_result == ZX_ERR_TIMED_OUT) {
    FX_LOGS(ERROR) << "Timed out waiting for sensor events.";
  }

  ASSERT_TRUE(accel_result_ok.has_value());
  ASSERT_TRUE(*accel_result_ok);
  ASSERT_TRUE(gyro_result_ok.has_value());
  ASSERT_TRUE(*gyro_result_ok);
  ASSERT_EQ(run_result, ZX_ERR_CANCELED);
  ASSERT_FALSE(handler.saw_error());
  ASSERT_GE(handler.sensor_events().at(kAccelSensorId).size(), 100ul);
  ASSERT_GE(handler.sensor_events().at(kGyroSensorId).size(), 10ul);

  // Deactivate the accelerometer.
  accel_result_ok = std::nullopt;
  driver_client->DeactivateSensor({kAccelSensorId})
      .ThenExactlyOnce([&](fidl::Result<Driver::DeactivateSensor>& result) {
        accel_result_ok = result.is_ok();
        loop.Quit();
      });

  loop.Run();
  loop.ResetQuit();
  ASSERT_TRUE(accel_result_ok.has_value());
  ASSERT_TRUE(*accel_result_ok);
  ASSERT_FALSE(handler.saw_error());

  // Deactivate the gyroscope.
  gyro_result_ok = std::nullopt;
  driver_client->DeactivateSensor({kGyroSensorId})
      .ThenExactlyOnce([&](fidl::Result<Driver::DeactivateSensor>& result) {
        gyro_result_ok = result.is_ok();
        loop.Quit();
      });

  loop.Run();
  loop.ResetQuit();
  ASSERT_TRUE(gyro_result_ok.has_value());
  ASSERT_TRUE(*gyro_result_ok);
  ASSERT_FALSE(handler.saw_error());

  // Do some statistics on the timestamps to see if they make sense.
  const std::vector<zx::time>& accel_arrival_times =
      handler.event_arrival_timestamps().at(kAccelSensorId);

  // Calculate the differences between all the timestamps, then sort the differences.
  std::vector<int64_t> accel_arrival_diffs;
  for (unsigned long i = 1; i < accel_arrival_times.size(); ++i) {
    zx::duration arrival_diff = accel_arrival_times.at(i) - accel_arrival_times.at(i - 1);
    accel_arrival_diffs.push_back(arrival_diff.get());
  }
  std::sort(accel_arrival_diffs.begin(), accel_arrival_diffs.end());

  // Create a histogram of the timestamp differences. The bins will be 1e7 nanoseconds (0.01
  // seconds) wide. The bottom end of the lowest bin will start at -5e6 nanoseconds (or -0.005
  // seconds) and thus the lowest bin will be centered around 0. There will be 11 bins in total,
  // with the highest bin centered on 1e8 nanoseconds (0.1 seconds) and topping out at 1.05e8
  // nanoseconds (0.105 seconds).
  const int64_t kBottomBinLowerLimit = -5e6;
  const uint64_t kBinWidth = 1e7;
  const int64_t kNumBins = 11;
  TimestampDiffHistogram hist =
      CreateTimestampDiffHistogram(accel_arrival_diffs, kBottomBinLowerLimit, kBinWidth, kNumBins);

  /* The accelerometer is sampling at 100 Hz, but with a buffer that is flushed at 10 Hz.

     The expected histogram with perfect timing would be this:
     Bin    | 00 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 |
     -------*----*----*----*----*----*----*----*----*----*----*----*
     Points | 90 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 09 |

     Since buffering is enabled, the events are coming in 10 bursts of 10. The timestamp difference
     between events in a burst will be very small, and thus we expect bin 0 to contain the most data
     points (90 ideally). In the 9 gaps between the 10 bursts we expect to see timestamp differences
     close to 0.1 seconds, and so ideally there should be 9 data points in bin 10.

     Rather than assert that all of the timestamp differences fit exactly into their ideal bins,
     this test will merely assert that bin 0 contains the most points, followed by bin 10, followed
     by any other bin or outliers above. This will ensure the general shape of the timing is correct
     but reduce flakes by being incredibly robust to all but the most massive and repeated test
     environment performance hiccups (theoretically anyways).
   */

  // Outliers below the bottom bin should not be possible as all of the timestamp differences should
  // be positive.
  ASSERT_EQ(hist.outliers_below, 0);

  // Sort the per-bin point counts in descending order by count.
  std::sort(hist.bin_point_counts.begin(), hist.bin_point_counts.end(),
            [](const std::pair<int, int>& bin1, const std::pair<int, int>& bin2) {
              return bin1.second >= bin2.second;
            });

  // There should be data points in at least two bins.
  ASSERT_GE(hist.bin_point_counts.size(), 2u);
  // Assert the bin with the highest count is bin 0.
  ASSERT_EQ(hist.bin_point_counts[0].first, 0);
  // Assert the bin with the next highest couint is bin 10.
  ASSERT_EQ(hist.bin_point_counts[1].first, 10);
}
