// Copyright 2020 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 "gt6853.h"

#include <endian.h>
#include <fuchsia/hardware/gpio/cpp/banjo-mock.h>
#include <lib/async-loop/cpp/loop.h>
#include <lib/async-loop/default.h>
#include <lib/ddk/metadata.h>
#include <lib/device-protocol/i2c-channel.h>
#include <lib/fake-i2c/fake-i2c.h>
#include <lib/inspect/testing/cpp/zxtest/inspect.h>
#include <lib/zx/clock.h>

#include <array>
#include <vector>

#include <fbl/algorithm.h>
#include <fbl/auto_lock.h>
#include <fbl/mutex.h>
#include <zxtest/zxtest.h>

#include "src/devices/testing/mock-ddk/mock-device.h"

namespace {

zx::vmo* config_vmo = nullptr;
size_t config_size = 0;

zx::vmo* firmware_vmo = nullptr;
size_t firmware_size = 0;

const char* config_path = nullptr;

}  // namespace

zx_status_t load_firmware_from_driver(zx_driver_t* drv, zx_device_t* device, const char* path,
                                      zx_handle_t* fw, size_t* size) {
  const std::string_view path_str(path);
  if ((path_str == GT6853_CONFIG_9364_PATH || path_str == GT6853_CONFIG_9365_PATH ||
       path_str == GT6853_CONFIG_7703_PATH) &&
      config_vmo && config_vmo->is_valid()) {
    config_path = path;
    *fw = config_vmo->get();
    *size = config_size;
    return ZX_OK;
  }
  if (path_str == GT6853_FIRMWARE_PATH && firmware_vmo && firmware_vmo->is_valid()) {
    *fw = firmware_vmo->get();
    *size = firmware_size;
    return ZX_OK;
  }

  return ZX_ERR_NOT_FOUND;
}

namespace touch {

class FakeTouchDevice : public fake_i2c::FakeI2c {
 public:
  struct FirmwarePacket {
    uint8_t type;
    uint16_t size;
    uint16_t flash_addr;
  };

  void WaitForTouchDataRead() {
    sync_completion_wait(&read_completion_, ZX_TIME_INFINITE);
    sync_completion_reset(&read_completion_);
  }

  bool ok() const { return event_reset_; }

  void set_sensor_id(const uint16_t sensor_id) { sensor_id_ = sensor_id; }
  const std::vector<uint8_t>& get_config_data() const { return config_data_; }
  const std::vector<FirmwarePacket>& get_firmware_packets() const { return firmware_packets_; }

 protected:
  zx_status_t Transact(const uint8_t* write_buffer, size_t write_buffer_size, uint8_t* read_buffer,
                       size_t* read_buffer_size) override {
    constexpr uint8_t kTouchData[] = {
        // clang-format off
        0x80, 0x5a, 0x00, 0xb9, 0x03, 0xae, 0x00, 0x00,
        0xc2, 0xf2, 0x01, 0x44, 0x00, 0x6c, 0x00, 0x00,
        0x01, 0x72, 0x00, 0x14, 0x01, 0x13, 0x00, 0x00,
        0xc3, 0x38, 0x01, 0xbe, 0x00, 0xdf, 0x00, 0x00,
        // clang-format on
    };

    if (write_buffer_size < 2) {
      return ZX_ERR_NOT_SUPPORTED;
    }

    const auto address = static_cast<uint16_t>((write_buffer[0] << 8) | write_buffer[1]);
    write_buffer += 2;
    write_buffer_size -= 2;

    using Register = Gt6853Device::Register;

    if (address == static_cast<uint16_t>(Register::kEventStatusReg)) {
      if (write_buffer_size >= 1 && write_buffer[0] == 0x00) {
        event_reset_ = true;
      } else {
        read_buffer[0] = current_state_ == kIdle ? 0x80 : 0x00;
        *read_buffer_size = 1;
      }
    } else if (address == static_cast<uint16_t>(Register::kContactsReg)) {
      read_buffer[0] = current_state_ == kIdle ? 0x34 : 0x00;
      *read_buffer_size = 1;
    } else if (address == static_cast<uint16_t>(Register::kContactsStartReg)) {
      // The interrupt has been received and the driver is reading out the data registers.
      if (current_state_ == kIdle) {
        memcpy(read_buffer, kTouchData, sizeof(kTouchData));
      } else {
        memset(read_buffer, 0x00, sizeof(kTouchData));
      }
      *read_buffer_size = sizeof(kTouchData);
      sync_completion_signal(&read_completion_);
    } else if (address == static_cast<uint16_t>(Register::kSensorIdReg)) {
      memcpy(read_buffer, &sensor_id_, sizeof(sensor_id_));
      *read_buffer_size = sizeof(sensor_id_);
    } else if (address == static_cast<uint16_t>(Register::kCommandReg) && write_buffer_size == 0) {
      // Reading the device command.
      read_buffer[0] = current_state_ == kWaitingForConfig ? 0x82 : 0xff;
      *read_buffer_size = 1;
    } else if (address == static_cast<uint16_t>(Register::kCommandReg) && write_buffer_size == 3) {
      // Writing the host command. Must write all three registers in one transfer.

      uint8_t checksum = write_buffer[0];
      checksum += write_buffer[1];
      checksum += write_buffer[2];
      if (checksum != 0) {
        return ZX_ERR_IO_DATA_INTEGRITY;
      }

      if (write_buffer[0] == 0x80 && current_state_ == kIdle) {
        current_state_ = kWaitingForConfig;
      } else if (write_buffer[0] == 0x83 && current_state_ == kWaitingForConfig) {
        current_state_ = kIdle;
      } else {
        return ZX_ERR_IO;
      }
    } else if (address == static_cast<uint16_t>(Register::kConfigDataReg) &&
               write_buffer_size > 0) {
      config_data_.insert(config_data_.end(), write_buffer, write_buffer + write_buffer_size);
    } else if (address >= static_cast<uint16_t>(Register::kIspBuffer) &&
               address < (static_cast<uint16_t>(Register::kIspBuffer) + 4096)) {
      const uint16_t offset = address - static_cast<uint16_t>(Register::kIspBuffer);
      if (write_buffer_size > 0) {
        if (offset + write_buffer_size > 4096) {
          return ZX_ERR_IO;
        }
        memcpy(flash_packet_ + offset, write_buffer, write_buffer_size);
      } else {
        memcpy(read_buffer, flash_packet_ + offset, 4096 - offset);
        *read_buffer_size = 4096 - offset;
      }
    } else if (address >= static_cast<uint16_t>(Register::kIspAddr) &&
               address < (static_cast<uint16_t>(Register::kIspAddr) + 4096)) {
      const uint16_t offset = address - static_cast<uint16_t>(Register::kIspAddr);
      if (write_buffer_size > 0) {
        if (offset + write_buffer_size > 4096) {
          return ZX_ERR_IO;
        }
        memcpy(flash_packet_ + offset, write_buffer, write_buffer_size);
      } else {
        memcpy(read_buffer, flash_packet_ + offset, 4096 - offset);
        *read_buffer_size = 4096 - offset;
      }
    } else if (address == static_cast<uint16_t>(Register::kSubsysType)) {
      if (write_buffer_size == 0) {
        read_buffer[0] = subsys_type_;
        read_buffer[1] = subsys_type_;
        *read_buffer_size = 2;
      } else if (write_buffer_size == 2 && write_buffer[0] == write_buffer[1]) {
        subsys_type_ = write_buffer[0];

        FirmwarePacket packet = {};
        packet.type = write_buffer[0];

        memcpy(&packet.size, flash_packet_, sizeof(packet.size));
        packet.size = be16toh(packet.size);

        memcpy(&packet.flash_addr, flash_packet_ + sizeof(packet.size), sizeof(packet.flash_addr));
        packet.flash_addr = be16toh(packet.flash_addr);

        firmware_packets_.push_back(packet);
      } else {
        return ZX_ERR_IO;
      }
    } else if (address == static_cast<uint16_t>(Register::kFlashFlag)) {
      if (write_buffer_size == 0) {
        // The flash state is read twice, report success in two states to handle this.
        if (current_state_ == kFlashingFirmware || current_state_ == kFlashingFirmwareDone) {
          read_buffer[0] = 0xbb;
          read_buffer[1] = 0xbb;
          current_state_ = current_state_ == kFlashingFirmware ? kFlashingFirmwareDone : kIdle;
        } else {
          read_buffer[0] = 0;
          read_buffer[1] = 0;
          current_state_ = kFlashingFirmware;
        }
        *read_buffer_size = 2;
      } else if (write_buffer_size != 2) {
        return ZX_ERR_IO;
      }
    } else if (address == static_cast<uint16_t>(Register::kIspRunFlag)) {
      if (write_buffer_size == 0) {
        read_buffer[0] = 0xaa;
        read_buffer[1] = 0xbb;
        *read_buffer_size = 2;
      } else if (write_buffer_size != 2) {
        return ZX_ERR_IO;
      }
    } else if (address == static_cast<uint16_t>(Register::kAccessPatch0)) {
      if (write_buffer_size == 0) {
        read_buffer[0] = access_patch0;
        *read_buffer_size = 1;
      } else if (write_buffer_size == 1) {
        access_patch0 = write_buffer[0];
      } else {
        return ZX_ERR_IO;
      }
    } else if (address == static_cast<uint16_t>(Register::kCpuCtrl)) {
      if (write_buffer_size == 0) {
        read_buffer[0] = 0x24;  // kCpuCtrlHoldSs51
        *read_buffer_size = 1;
      } else if (write_buffer_size != 1) {
        return ZX_ERR_IO;
      }
    } else if (address == static_cast<uint16_t>(Register::kDspMcuPower)) {
      if (write_buffer_size == 0) {
        read_buffer[0] = 0;
        *read_buffer_size = 1;
      } else if (write_buffer_size != 1) {
        return ZX_ERR_IO;
      }
    } else if (address == static_cast<uint16_t>(Register::kBankSelect) ||
               address == static_cast<uint16_t>(Register::kCache) ||
               address == static_cast<uint16_t>(Register::kEsdKey) ||
               address == static_cast<uint16_t>(Register::kWtdTimer) ||
               address == static_cast<uint16_t>(Register::kScramble)) {
      if (write_buffer_size != 1) {
        return ZX_ERR_IO;
      }
    } else if (address == static_cast<uint16_t>(Register::kCpuRunFrom)) {
      if (write_buffer_size != 8) {
        return ZX_ERR_IO;
      }
    } else {
      return ZX_ERR_IO;
    }

    return ZX_OK;
  }

 private:
  enum State {
    kIdle,
    kWaitingForConfig,
    kFlashingFirmware,
    kFlashingFirmwareDone,
  };

  sync_completion_t read_completion_;
  bool event_reset_ = false;
  uint16_t sensor_id_ = UINT16_MAX;
  State current_state_ = kIdle;
  std::vector<uint8_t> config_data_;
  uint8_t flash_packet_[4096];
  uint8_t subsys_type_ = 0;
  uint8_t access_patch0 = 0;
  std::vector<FirmwarePacket> firmware_packets_;
};

class Gt6853Test : public zxtest::Test {
 public:
  Gt6853Test()
      : fake_parent_(MockDevice::FakeRootParent()), loop_(&kAsyncLoopConfigNeverAttachToThread) {}

  void SetUp() override {
    ASSERT_OK(zx::interrupt::create(zx::resource(ZX_HANDLE_INVALID), 0, ZX_INTERRUPT_VIRTUAL,
                                    &gpio_interrupt_));

    zx::interrupt gpio_interrupt;
    ASSERT_OK(gpio_interrupt_.duplicate(ZX_RIGHT_SAME_RIGHTS, &gpio_interrupt));

    mock_gpio_.ExpectConfigIn(ZX_OK, GPIO_NO_PULL);
    mock_gpio_.ExpectGetInterrupt(ZX_OK, ZX_INTERRUPT_MODE_EDGE_LOW, std::move(gpio_interrupt));

    EXPECT_OK(loop_.StartThread());
  }

  void TearDown() override {
    if (device_) {
      device_async_remove(device_);
      EXPECT_OK(mock_ddk::ReleaseFlaggedDevices(fake_parent_.get()));
    }
    device_ = nullptr;
  }

  zx_status_t Init(uint32_t panel_type_id = 1) {
    panel_type_id_ = panel_type_id;

    fake_parent_->AddProtocol(ZX_PROTOCOL_PDEV, nullptr, nullptr, "pdev");
    fake_parent_->AddProtocol(ZX_PROTOCOL_GPIO, mock_gpio_.GetProto()->ops,
                              mock_gpio_.GetProto()->ctx, "gpio-int");
    fake_parent_->AddProtocol(ZX_PROTOCOL_GPIO, mock_gpio_.GetProto()->ops,
                              mock_gpio_.GetProto()->ctx, "gpio-reset");
    fake_parent_->AddFidlProtocol(
        fidl::DiscoverableProtocolName<fuchsia_hardware_i2c::Device>,
        [&](zx::channel channel) {
          fidl::BindServer(loop_.dispatcher(),
                           fidl::ServerEnd<fuchsia_hardware_i2c::Device>(std::move(channel)),
                           &fake_i2c_);
          return ZX_OK;
        },
        "i2c");

    fake_parent_->SetMetadata(DEVICE_METADATA_BOARD_PRIVATE, &panel_type_id_,
                              sizeof(panel_type_id_));

    config_vmo = &config_vmo_;
    firmware_vmo = &firmware_vmo_;

    zx_status_t status = Gt6853Device::Create(nullptr, fake_parent_.get());
    device_ = fake_parent_->GetLatestChild();
    return status;
  }

 protected:
  zx_status_t WriteConfigData(const std::vector<uint8_t>& data, uint64_t offset) {
    return config_vmo_.write(data.data(), offset, data.size());
  }

  zx_status_t WriteConfigString(const char* data, uint64_t offset) {
    return config_vmo_.write(data, offset, strlen(data) + 1);
  }

  zx_status_t WriteFirmwareData(const std::vector<uint8_t>& data, uint64_t offset) {
    return firmware_vmo_.write(data.data(), offset, data.size());
  }

  void AddDefaultConfig() {
    config_size = 2338;
    ASSERT_OK(zx::vmo::create(fbl::round_up(config_size, ZX_PAGE_SIZE), 0, &config_vmo_));

    const uint32_t config_size_le = htole32(config_size);
    ASSERT_OK(config_vmo_.write(&config_size_le, 0, sizeof(config_size_le)));
    ASSERT_OK(WriteConfigData({0x2b}, 4));
    ASSERT_OK(WriteConfigData({0x03}, 9));
    ASSERT_OK(WriteConfigData({0x16, 0x00, 0x1a, 0x03, 0x1e, 0x06}, 16));
    ASSERT_OK(WriteConfigData({0x04, 0x03, 0x00, 0x00}, 0x0016));
    ASSERT_OK(WriteConfigData({0x02}, 0x0016 + 20));
    ASSERT_OK(WriteConfigString("Config number two", 0x0016 + 121));
    ASSERT_OK(WriteConfigData({0x04, 0x03, 0x00, 0x00}, 0x031a));
    ASSERT_OK(WriteConfigData({0x00}, 0x031a + 20));
    ASSERT_OK(WriteConfigString("Config number zero", 0x031a + 121));
    ASSERT_OK(WriteConfigData({0x04, 0x03, 0x00, 0x00}, 0x061e));
    ASSERT_OK(WriteConfigData({0x01}, 0x061e + 20));
    ASSERT_OK(WriteConfigString("Config number one", 0x061e + 121));

    fake_i2c_.set_sensor_id(0);
  }

  void WaitForNextReader() { device_->GetDeviceContext<Gt6853Device>()->WaitForNextReader(); }

  fidl::ClientEnd<fuchsia_input_report::InputDevice> GetInputDeviceClient() {
    auto endpoints = fidl::CreateEndpoints<fuchsia_input_report::InputDevice>();
    EXPECT_OK(endpoints);

    fidl::BindServer(loop_.dispatcher(), std::move(endpoints->server),
                     device_->GetDeviceContext<Gt6853Device>());

    return std::move(endpoints->client);
  }

  FakeTouchDevice fake_i2c_;
  zx::interrupt gpio_interrupt_;
  MockDevice* device_ = nullptr;
  uint32_t panel_type_id_ = 0;
  zx::vmo config_vmo_;
  zx::vmo firmware_vmo_;
  ddk::MockGpio mock_gpio_;

 private:
  std::shared_ptr<MockDevice> fake_parent_;
  async::Loop loop_;
};

TEST_F(Gt6853Test, GetDescriptor) {
  AddDefaultConfig();
  ASSERT_OK(Init());

  fidl::WireSyncClient client(GetInputDeviceClient());

  auto response = client->GetDescriptor();

  ASSERT_TRUE(response.ok());
  ASSERT_TRUE(response.value().descriptor.has_device_info());
  ASSERT_TRUE(response.value().descriptor.has_touch());
  ASSERT_TRUE(response.value().descriptor.touch().has_input());
  ASSERT_TRUE(response.value().descriptor.touch().input().has_contacts());
  ASSERT_TRUE(response.value().descriptor.touch().input().has_max_contacts());
  ASSERT_TRUE(response.value().descriptor.touch().input().has_touch_type());
  ASSERT_EQ(response.value().descriptor.touch().input().contacts().count(), 10);

  EXPECT_EQ(response.value().descriptor.device_info().vendor_id,
            static_cast<uint32_t>(fuchsia_input_report::wire::VendorId::kGoogle));
  EXPECT_EQ(response.value().descriptor.device_info().product_id,
            static_cast<uint32_t>(
                fuchsia_input_report::wire::VendorGoogleProductId::kFocaltechTouchscreen));

  for (size_t i = 0; i < 10; i++) {
    const auto& contact = response.value().descriptor.touch().input().contacts()[i];
    ASSERT_TRUE(contact.has_position_x());
    ASSERT_TRUE(contact.has_position_y());

    EXPECT_EQ(contact.position_x().range.min, 0);
    EXPECT_EQ(contact.position_x().range.max, 600);
    EXPECT_EQ(contact.position_x().unit.type, fuchsia_input_report::wire::UnitType::kNone);
    EXPECT_EQ(contact.position_x().unit.exponent, 0);

    EXPECT_EQ(contact.position_y().range.min, 0);
    EXPECT_EQ(contact.position_y().range.max, 1024);
    EXPECT_EQ(contact.position_y().unit.type, fuchsia_input_report::wire::UnitType::kNone);
    EXPECT_EQ(contact.position_y().unit.exponent, 0);
  }

  EXPECT_EQ(response.value().descriptor.touch().input().max_contacts(), 10);
  EXPECT_EQ(response.value().descriptor.touch().input().touch_type(),
            fuchsia_input_report::wire::TouchType::kTouchscreen);
}

TEST_F(Gt6853Test, ReadReport) {
  AddDefaultConfig();
  ASSERT_OK(Init());

  fidl::WireSyncClient client(GetInputDeviceClient());

  auto reader_endpoints = fidl::CreateEndpoints<fuchsia_input_report::InputReportsReader>();
  ASSERT_TRUE(reader_endpoints.is_ok());
  auto [reader_client, reader_server] = std::move(reader_endpoints.value());
  // TODO(fxbug.dev/97955) Consider handling the error instead of ignoring it.
  (void)client->GetInputReportsReader(std::move(reader_server));
  fidl::WireSyncClient<fuchsia_input_report::InputReportsReader> reader(std::move(reader_client));
  WaitForNextReader();

  EXPECT_OK(gpio_interrupt_.trigger(0, zx::clock::get_monotonic()));

  fake_i2c_.WaitForTouchDataRead();

  const auto response = reader->ReadInputReports();
  ASSERT_TRUE(response.ok());
  ASSERT_TRUE(response->is_ok());

  const auto& reports = response->value()->reports;

  ASSERT_EQ(reports.count(), 1);
  ASSERT_TRUE(reports[0].has_touch());
  ASSERT_TRUE(reports[0].touch().has_contacts());
  ASSERT_EQ(reports[0].touch().contacts().count(), 4);

  EXPECT_EQ(reports[0].touch().contacts()[0].contact_id(), 0);
  EXPECT_EQ(reports[0].touch().contacts()[0].position_x(), 0x005a);
  EXPECT_EQ(reports[0].touch().contacts()[0].position_y(), 0x03b9);

  EXPECT_EQ(reports[0].touch().contacts()[1].contact_id(), 2);
  EXPECT_EQ(reports[0].touch().contacts()[1].position_x(), 0x01f2);
  EXPECT_EQ(reports[0].touch().contacts()[1].position_y(), 0x0044);

  EXPECT_EQ(reports[0].touch().contacts()[2].contact_id(), 1);
  EXPECT_EQ(reports[0].touch().contacts()[2].position_x(), 0x0072);
  EXPECT_EQ(reports[0].touch().contacts()[2].position_y(), 0x0114);

  EXPECT_EQ(reports[0].touch().contacts()[3].contact_id(), 3);
  EXPECT_EQ(reports[0].touch().contacts()[3].position_x(), 0x0138);
  EXPECT_EQ(reports[0].touch().contacts()[3].position_y(), 0x00be);

  EXPECT_TRUE(fake_i2c_.ok());
}

TEST_F(Gt6853Test, ConfigDownloadPanelType9364) {
  config_size = 2338;
  ASSERT_OK(zx::vmo::create(fbl::round_up(config_size, ZX_PAGE_SIZE), 0, &config_vmo_));

  const uint32_t config_size_le = htole32(config_size);
  ASSERT_OK(config_vmo_.write(&config_size_le, 0, sizeof(config_size_le)));
  ASSERT_OK(WriteConfigData({0x2b}, 4));  // Checksum
  ASSERT_OK(WriteConfigData({0x03}, 9));  // Number of config entries in the table
  ASSERT_OK(WriteConfigData({0x16, 0x00, 0x1a, 0x03, 0x1e, 0x06}, 16));  // Entry offsets
  ASSERT_OK(WriteConfigData({0x04, 0x03, 0x00, 0x00}, 0x0016));          // Entry 0 size
  ASSERT_OK(WriteConfigData({0x02}, 0x0016 + 20));                       // Entry 0 sensor ID
  ASSERT_OK(WriteConfigString("Config number two", 0x0016 + 121));       // Entry 0 config data
  ASSERT_OK(WriteConfigData({0x04, 0x03, 0x00, 0x00}, 0x031a));          // Repeat for entries 1, 2
  ASSERT_OK(WriteConfigData({0x00}, 0x031a + 20));
  ASSERT_OK(WriteConfigString("Config number zero", 0x031a + 121));
  ASSERT_OK(WriteConfigData({0x04, 0x03, 0x00, 0x00}, 0x061e));
  ASSERT_OK(WriteConfigData({0x01}, 0x061e + 20));
  ASSERT_OK(WriteConfigString("Config number one", 0x061e + 121));

  fake_i2c_.set_sensor_id(1);

  ASSERT_OK(Init());

  EXPECT_STREQ(reinterpret_cast<const char*>(fake_i2c_.get_config_data().data()),
               "Config number one");
  EXPECT_STREQ(config_path, GT6853_CONFIG_9364_PATH);
  EXPECT_EQ(fake_i2c_.get_config_data().size(), 0x0304 - 121);
}

TEST_F(Gt6853Test, ConfigDownloadPanelType9365) {
  config_size = 2338;
  ASSERT_OK(zx::vmo::create(fbl::round_up(config_size, ZX_PAGE_SIZE), 0, &config_vmo_));

  const uint32_t config_size_le = htole32(config_size);
  ASSERT_OK(config_vmo_.write(&config_size_le, 0, sizeof(config_size_le)));
  ASSERT_OK(WriteConfigData({0x2b}, 4));
  ASSERT_OK(WriteConfigData({0x03}, 9));
  ASSERT_OK(WriteConfigData({0x16, 0x00, 0x1a, 0x03, 0x1e, 0x06}, 16));
  ASSERT_OK(WriteConfigData({0x04, 0x03, 0x00, 0x00}, 0x0016));
  ASSERT_OK(WriteConfigData({0x02}, 0x0016 + 20));
  ASSERT_OK(WriteConfigString("Config number two", 0x0016 + 121));
  ASSERT_OK(WriteConfigData({0x04, 0x03, 0x00, 0x00}, 0x031a));
  ASSERT_OK(WriteConfigData({0x00}, 0x031a + 20));
  ASSERT_OK(WriteConfigString("Config number zero", 0x031a + 121));
  ASSERT_OK(WriteConfigData({0x04, 0x03, 0x00, 0x00}, 0x061e));
  ASSERT_OK(WriteConfigData({0x01}, 0x061e + 20));
  ASSERT_OK(WriteConfigString("Config number one", 0x061e + 121));

  fake_i2c_.set_sensor_id(0);

  ASSERT_OK(Init(4));  // kPanelTypeKdFiti9365

  EXPECT_STREQ(reinterpret_cast<const char*>(fake_i2c_.get_config_data().data()),
               "Config number zero");
  EXPECT_STREQ(config_path, GT6853_CONFIG_9365_PATH);
  EXPECT_EQ(fake_i2c_.get_config_data().size(), 0x0304 - 121);
}

TEST_F(Gt6853Test, ConfigDownloadPanelType7703) {
  config_size = 2338;
  ASSERT_OK(zx::vmo::create(fbl::round_up(config_size, ZX_PAGE_SIZE), 0, &config_vmo_));

  const uint32_t config_size_le = htole32(config_size);
  ASSERT_OK(config_vmo_.write(&config_size_le, 0, sizeof(config_size_le)));
  ASSERT_OK(WriteConfigData({0x2b}, 4));
  ASSERT_OK(WriteConfigData({0x03}, 9));
  ASSERT_OK(WriteConfigData({0x16, 0x00, 0x1a, 0x03, 0x1e, 0x06}, 16));
  ASSERT_OK(WriteConfigData({0x04, 0x03, 0x00, 0x00}, 0x0016));
  ASSERT_OK(WriteConfigData({0x02}, 0x0016 + 20));
  ASSERT_OK(WriteConfigString("Config number two", 0x0016 + 121));
  ASSERT_OK(WriteConfigData({0x04, 0x03, 0x00, 0x00}, 0x031a));
  ASSERT_OK(WriteConfigData({0x00}, 0x031a + 20));
  ASSERT_OK(WriteConfigString("Config number zero", 0x031a + 121));
  ASSERT_OK(WriteConfigData({0x04, 0x03, 0x00, 0x00}, 0x061e));
  ASSERT_OK(WriteConfigData({0x01}, 0x061e + 20));
  ASSERT_OK(WriteConfigString("Config number one", 0x061e + 121));

  fake_i2c_.set_sensor_id(0);

  ASSERT_OK(Init(6));  // kPanelTypeBoeSit7703

  EXPECT_STREQ(reinterpret_cast<const char*>(fake_i2c_.get_config_data().data()),
               "Config number zero");
  EXPECT_STREQ(config_path, GT6853_CONFIG_7703_PATH);
  EXPECT_EQ(fake_i2c_.get_config_data().size(), 0x0304 - 121);
}

TEST_F(Gt6853Test, ConfigDownloadUnableToLoadConfig) { EXPECT_NOT_OK(Init()); }

TEST_F(Gt6853Test, NoConfigEntry) {
  config_size = 2338;
  ASSERT_OK(zx::vmo::create(fbl::round_up(config_size, ZX_PAGE_SIZE), 0, &config_vmo_));

  const uint32_t config_size_le = htole32(config_size);
  ASSERT_OK(config_vmo_.write(&config_size_le, 0, sizeof(config_size_le)));
  ASSERT_OK(WriteConfigData({0x2b}, 4));
  ASSERT_OK(WriteConfigData({0x03}, 9));
  ASSERT_OK(WriteConfigData({0x16, 0x00, 0x1a, 0x03, 0x1e, 0x06}, 16));
  ASSERT_OK(WriteConfigData({0x04, 0x03, 0x00, 0x00}, 0x0016));
  ASSERT_OK(WriteConfigData({0x02}, 0x0016 + 20));
  ASSERT_OK(WriteConfigString("Config number two", 0x0016 + 121));
  ASSERT_OK(WriteConfigData({0x04, 0x03, 0x00, 0x00}, 0x031a));
  ASSERT_OK(WriteConfigData({0x00}, 0x031a + 20));
  ASSERT_OK(WriteConfigString("Config number zero", 0x031a + 121));
  ASSERT_OK(WriteConfigData({0x04, 0x03, 0x00, 0x00}, 0x061e));
  ASSERT_OK(WriteConfigData({0x01}, 0x061e + 20));
  ASSERT_OK(WriteConfigString("Config number one", 0x061e + 121));

  fake_i2c_.set_sensor_id(4);

  EXPECT_NOT_OK(Init());
}

TEST_F(Gt6853Test, InvalidConfigEntry) {
  config_size = 2338;
  ASSERT_OK(zx::vmo::create(fbl::round_up(config_size, ZX_PAGE_SIZE), 0, &config_vmo_));

  ASSERT_OK(WriteConfigData({0x1c, 0x03, 0x00, 0x00, 0x2b}, 0));
  ASSERT_OK(WriteConfigData({0x03}, 9));
  ASSERT_OK(WriteConfigData({0x16, 0x00, 0x1a, 0x03, 0x1e, 0x06}, 16));
  ASSERT_OK(WriteConfigData({0x04, 0x03, 0x00, 0x00}, 0x0016));
  ASSERT_OK(WriteConfigData({0x02}, 0x0016 + 20));
  ASSERT_OK(WriteConfigString("Config number two", 0x0016 + 121));
  ASSERT_OK(WriteConfigData({0x04, 0x03, 0x00, 0x00}, 0x031a));
  ASSERT_OK(WriteConfigData({0x00}, 0x031a + 20));
  ASSERT_OK(WriteConfigString("Config number zero", 0x031a + 121));
  ASSERT_OK(WriteConfigData({0x04, 0x03, 0x00, 0x00}, 0x061e));
  ASSERT_OK(WriteConfigData({0x01}, 0x061e + 20));
  ASSERT_OK(WriteConfigString("Config number one", 0x061e + 121));

  fake_i2c_.set_sensor_id(1);

  config_size = 0x031a + 2;
  EXPECT_NOT_OK(Init());
}

TEST_F(Gt6853Test, BadConfigChecksum) {
  config_size = 2338;
  ASSERT_OK(zx::vmo::create(fbl::round_up(config_size, ZX_PAGE_SIZE), 0, &config_vmo_));

  const uint32_t config_size_le = htole32(config_size);
  ASSERT_OK(config_vmo_.write(&config_size_le, 0, sizeof(config_size_le)));
  ASSERT_OK(WriteConfigData({0x2b + 1}, 4));
  ASSERT_OK(WriteConfigData({0x03}, 9));
  ASSERT_OK(WriteConfigData({0x16, 0x00, 0x1a, 0x03, 0x1e, 0x06}, 16));
  ASSERT_OK(WriteConfigData({0x04, 0x03, 0x00, 0x00}, 0x0016));
  ASSERT_OK(WriteConfigData({0x02}, 0x0016 + 20));
  ASSERT_OK(WriteConfigString("Config number two", 0x0016 + 121));
  ASSERT_OK(WriteConfigData({0x04, 0x03, 0x00, 0x00}, 0x031a));
  ASSERT_OK(WriteConfigData({0x00}, 0x031a + 20));
  ASSERT_OK(WriteConfigString("Config number zero", 0x031a + 121));
  ASSERT_OK(WriteConfigData({0x04, 0x03, 0x00, 0x00}, 0x061e));
  ASSERT_OK(WriteConfigData({0x01}, 0x061e + 20));
  ASSERT_OK(WriteConfigString("Config number one", 0x061e + 121));

  fake_i2c_.set_sensor_id(1);

  EXPECT_EQ(Init(), ZX_ERR_IO_DATA_INTEGRITY);
}

TEST_F(Gt6853Test, FirmwareDownload) {
  firmware_size = 2048;
  ASSERT_OK(zx::vmo::create(fbl::round_up(firmware_size, ZX_PAGE_SIZE), 0, &firmware_vmo_));
  ASSERT_OK(WriteFirmwareData({0x00, 0x00, 0x07, 0xfa, 0x02, 0x98}, 0));
  ASSERT_OK(WriteFirmwareData({0x03}, 27));
  ASSERT_OK(WriteFirmwareData({0x01, 0x00, 0x00, 0x01, 0x00, 0xab, 0xcd}, 32));
  ASSERT_OK(WriteFirmwareData({0x02, 0x00, 0x00, 0x01, 0x00, 0x12, 0x34}, 40));
  ASSERT_OK(WriteFirmwareData({0x03, 0x00, 0x00, 0x01, 0x00, 0x56, 0x78}, 48));

  AddDefaultConfig();

  mock_gpio_.ExpectConfigOut(ZX_OK, 0);
  mock_gpio_.ExpectWrite(ZX_OK, 1);
  mock_gpio_.ExpectWrite(ZX_OK, 0);
  mock_gpio_.ExpectWrite(ZX_OK, 1);

  EXPECT_OK(Init());

  ASSERT_EQ(fake_i2c_.get_firmware_packets().size(), 2);

  EXPECT_EQ(fake_i2c_.get_firmware_packets()[0].type, 2);
  EXPECT_EQ(fake_i2c_.get_firmware_packets()[0].size, 256);
  EXPECT_EQ(fake_i2c_.get_firmware_packets()[0].flash_addr, 0x1234);

  EXPECT_EQ(fake_i2c_.get_firmware_packets()[1].type, 3);
  EXPECT_EQ(fake_i2c_.get_firmware_packets()[1].size, 256);
  EXPECT_EQ(fake_i2c_.get_firmware_packets()[1].flash_addr, 0x5678);
}

TEST_F(Gt6853Test, FirmwareDownloadInvalidCrc) {
  firmware_size = 2048;
  ASSERT_OK(zx::vmo::create(fbl::round_up(firmware_size, ZX_PAGE_SIZE), 0, &firmware_vmo_));
  ASSERT_OK(WriteFirmwareData({0x00, 0x00, 0x07, 0xfa, 0x02, 0x99}, 0));
  ASSERT_OK(WriteFirmwareData({0x03}, 27));
  ASSERT_OK(WriteFirmwareData({0x01, 0x00, 0x00, 0x01, 0x00, 0xab, 0xcd}, 32));
  ASSERT_OK(WriteFirmwareData({0x02, 0x00, 0x00, 0x01, 0x00, 0x12, 0x34}, 40));
  ASSERT_OK(WriteFirmwareData({0x03, 0x00, 0x00, 0x01, 0x00, 0x56, 0x78}, 48));

  EXPECT_NOT_OK(Init());
}

TEST_F(Gt6853Test, FirmwareDownloadNoIspEntry) {
  firmware_size = 2048;
  ASSERT_OK(zx::vmo::create(fbl::round_up(firmware_size, ZX_PAGE_SIZE), 0, &firmware_vmo_));
  ASSERT_OK(WriteFirmwareData({0x00, 0x00, 0x07, 0xfa, 0x00, 0x00}, 0));
  ASSERT_OK(WriteFirmwareData({0x00}, 27));

  EXPECT_NOT_OK(Init());
}

TEST_F(Gt6853Test, LatencyMeasurements) {
  AddDefaultConfig();
  ASSERT_OK(Init());

  fidl::WireSyncClient client(GetInputDeviceClient());

  auto reader_endpoints = fidl::CreateEndpoints<fuchsia_input_report::InputReportsReader>();
  ASSERT_TRUE(reader_endpoints.is_ok());
  auto [reader_client, reader_server] = std::move(reader_endpoints.value());
  // TODO(fxbug.dev/97955) Consider handling the error instead of ignoring it.
  (void)client->GetInputReportsReader(std::move(reader_server));
  fidl::WireSyncClient<fuchsia_input_report::InputReportsReader> reader(std::move(reader_client));
  WaitForNextReader();

  for (int i = 0; i < 5; i++) {
    EXPECT_OK(gpio_interrupt_.trigger(0, zx::clock::get_monotonic()));
    fake_i2c_.WaitForTouchDataRead();
  }

  for (size_t reports = 0; reports < 5;) {
    const auto response = reader->ReadInputReports();
    if (response.ok() && response->is_ok()) {
      reports += response->value()->reports.count();
    }
  }

  const zx::vmo& inspect_vmo = device_->GetInspectVmo();
  ASSERT_TRUE(inspect_vmo.is_valid());

  inspect::InspectTestHelper inspector;
  inspector.ReadInspect(inspect_vmo);

  const inspect::Hierarchy* root = inspector.hierarchy().GetByPath({"hid-input-report-touch"});
  ASSERT_NOT_NULL(root);

  const auto* average_latency =
      root->node().get_property<inspect::UintPropertyValue>("average_latency_usecs");
  ASSERT_NOT_NULL(average_latency);

  const auto* max_latency =
      root->node().get_property<inspect::UintPropertyValue>("max_latency_usecs");
  ASSERT_NOT_NULL(max_latency);

  EXPECT_GE(max_latency->value(), average_latency->value());
}

}  // namespace touch
