// 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 "i2c-child.h"

#include <lib/fake_ddk/fake_ddk.h>

#include <zxtest/zxtest.h>

#include "i2c-bus.h"

namespace i2c {

constexpr uint8_t kTestWrite0 = 0x99;
constexpr uint8_t kTestWrite1 = 0x88;
constexpr uint8_t kTestWrite2 = 0x77;
constexpr uint8_t kTestRead0 = 0x12;
constexpr uint8_t kTestRead1 = 0x34;
constexpr uint8_t kTestRead2 = 0x56;

class I2cChildTest : public I2cChild {
 public:
  I2cChildTest(zx_device_t* parent, fbl::RefPtr<I2cBus> bus, uint16_t address)
      : I2cChild(parent, std::move(bus), address) {
    ddk_proto_id_ = ZX_PROTOCOL_I2C;
    ZX_ASSERT(DdkAdd("Test-device") == ZX_OK);
  }
};

TEST(I2cChildTest, Write3BytesOnce) {
  fake_ddk::Bind tester;
  class I2cBusTest : public I2cBus {
   public:
    explicit I2cBusTest(ddk::I2cImplProtocolClient i2c, uint32_t bus_id)
        : I2cBus(fake_ddk::kFakeParent, i2c, bus_id) {}
    void Transact(uint16_t address, const i2c_op_t* op_list, size_t op_count,
                  i2c_transact_callback callback, void* cookie) override {
      if (op_count != 1) {
        callback(cookie, ZX_ERR_INTERNAL, nullptr, 0);
        return;
      }
      auto p0 = op_list[0].data_buffer;
      if (p0[0] != kTestWrite0 || p0[1] != kTestWrite1 || p0[2] != kTestWrite2 ||
          op_list[0].data_size != 3 || op_list[0].is_read != false || op_list[0].stop != true) {
        callback(cookie, ZX_ERR_INTERNAL, nullptr, 0);
        return;
      }
      callback(cookie, ZX_OK, nullptr, 0);
    }
  };
  ddk::I2cImplProtocolClient i2c = {};
  I2cChildTest server(fake_ddk::kFakeParent, fbl::AdoptRef<I2cBus>(new I2cBusTest(i2c, 0)), 0);
  fidl::WireSyncClient<fuchsia_hardware_i2c::Device2> client_wrap(std::move(tester.FidlClient()));

  bool is_write[] = {true};  // 1 write segment.
  auto segments_is_write = fidl::VectorView<bool>::FromExternal(is_write);

  // 3 bytes in 1 write segment.
  size_t n_write_bytes = 3;
  auto write_buffer = std::make_unique<uint8_t[]>(n_write_bytes);
  write_buffer[0] = kTestWrite0;
  write_buffer[1] = kTestWrite1;
  write_buffer[2] = kTestWrite2;
  auto write_segment = fidl::VectorView<uint8_t>::FromExternal(write_buffer.get(), n_write_bytes);

  auto read = client_wrap.Transfer(std::move(segments_is_write),
                                   fidl::VectorView<fidl::VectorView<uint8_t>>::FromExternal(
                                       &write_segment, 1),        // 1 write segment.
                                   fidl::VectorView<uint8_t>());  // No reads.
  ASSERT_OK(read.status());
  ASSERT_FALSE(read->result.is_err());
}

TEST(I2cChildTest, Read3BytesOnce) {
  fake_ddk::Bind tester;
  class I2cBusTest : public I2cBus {
   public:
    explicit I2cBusTest(ddk::I2cImplProtocolClient i2c, uint32_t bus_id)
        : I2cBus(fake_ddk::kFakeParent, i2c, bus_id) {}
    void Transact(uint16_t address, const i2c_op_t* op_list, size_t op_count,
                  i2c_transact_callback callback, void* cookie) override {
      if (op_count != 1) {
        callback(cookie, ZX_ERR_INTERNAL, nullptr, 0);
        return;
      }
      if (op_list[0].data_size != 3 || op_list[0].is_read != true || op_list[0].stop != true) {
        callback(cookie, ZX_ERR_INTERNAL, nullptr, 0);
        return;
      }
      uint8_t reply0 = kTestRead0;
      uint8_t reply1 = kTestRead1;
      uint8_t reply2 = kTestRead2;
      i2c_op_t replies[3] = {
          {&reply0, 1, true, false},
          {&reply1, 1, true, false},
          {&reply2, 1, true, false},
      };
      callback(cookie, ZX_OK, replies, countof(replies));
    }
  };
  ddk::I2cImplProtocolClient i2c = {};
  I2cChildTest server(fake_ddk::kFakeParent, fbl::AdoptRef<I2cBus>(new I2cBusTest(i2c, 0)), 0);
  fidl::WireSyncClient<fuchsia_hardware_i2c::Device2> client_wrap(std::move(tester.FidlClient()));

  bool is_write[] = {false};  // 1 read segment.
  auto segments_is_write = fidl::VectorView<bool>::FromExternal(is_write);

  // 1 read segment expecting 3 bytes.
  constexpr size_t n_reads = 1;
  auto read_lengths = std::make_unique<uint8_t[]>(n_reads);
  read_lengths[0] = 3;  // 3 bytes to read in 1 segment.

  auto read =
      client_wrap.Transfer(std::move(segments_is_write),
                           fidl::VectorView<fidl::VectorView<uint8_t>>(),  // No writes.
                           fidl::VectorView<uint8_t>::FromExternal(read_lengths.get(),
                                                                   n_reads));  // 1 read segment.
  ASSERT_OK(read.status());
  ASSERT_FALSE(read->result.is_err());

  auto& read_data = read->result.response().read_segments_data;
  ASSERT_EQ(read_data[0].data()[0], kTestRead0);
  ASSERT_EQ(read_data[1].data()[0], kTestRead1);
  ASSERT_EQ(read_data[2].data()[0], kTestRead2);
}

TEST(I2cChildTest, Write1ByteOnceRead1Byte3Times) {
  fake_ddk::Bind tester;
  class I2cBusTest : public I2cBus {
   public:
    explicit I2cBusTest(ddk::I2cImplProtocolClient i2c, uint32_t bus_id)
        : I2cBus(fake_ddk::kFakeParent, i2c, bus_id) {}
    void Transact(uint16_t address, const i2c_op_t* op_list, size_t op_count,
                  i2c_transact_callback callback, void* cookie) override {
      if (op_count != 4) {
        callback(cookie, ZX_ERR_INTERNAL, nullptr, 0);
        return;
      }
      auto p0 = op_list[0].data_buffer;
      if (p0[0] != kTestWrite0 || op_list[0].data_size != 1 || op_list[0].is_read != false ||
          op_list[0].stop != false || op_list[1].data_size != 1 || op_list[1].is_read != true ||
          op_list[1].stop != false || op_list[2].data_size != 1 || op_list[2].is_read != true ||
          op_list[2].stop != false || op_list[3].data_size != 1 || op_list[3].is_read != true ||
          op_list[3].stop != true) {
        callback(cookie, ZX_ERR_INTERNAL, nullptr, 0);
        return;
      }
      uint8_t reply0 = kTestRead0;
      uint8_t reply1 = kTestRead1;
      uint8_t reply2 = kTestRead2;
      i2c_op_t replies[3] = {
          {&reply0, 1, true, false},
          {&reply1, 1, true, false},
          {&reply2, 1, true, false},
      };
      callback(cookie, ZX_OK, replies, countof(replies));
    }
  };
  ddk::I2cImplProtocolClient i2c = {};
  I2cChildTest server(fake_ddk::kFakeParent, fbl::AdoptRef<I2cBus>(new I2cBusTest(i2c, 0)), 0);
  fidl::WireSyncClient<fuchsia_hardware_i2c::Device2> client_wrap(std::move(tester.FidlClient()));

  bool is_write[] = {true, false, false, false};  // 1 write, 3 reads.
  auto segments_is_write = fidl::VectorView<bool>::FromExternal(is_write);

  // 1 byte in 1 write segment.
  size_t n_write_bytes = 1;
  auto write_buffer = std::make_unique<uint8_t[]>(n_write_bytes);
  write_buffer[0] = kTestWrite0;
  auto write_segment = fidl::VectorView<uint8_t>::FromExternal(write_buffer.get(), n_write_bytes);

  // 3 read segments expecting 1 byte each.
  constexpr size_t n_reads = 3;
  auto read_lengths = std::make_unique<uint8_t[]>(n_reads);
  read_lengths[0] = 1;
  read_lengths[1] = 1;
  read_lengths[2] = 1;

  auto read = client_wrap.Transfer(
      std::move(segments_is_write),
      fidl::VectorView<fidl::VectorView<uint8_t>>::FromExternal(&write_segment,
                                                                1),  // 1 write segment.
      fidl::VectorView<uint8_t>::FromExternal(read_lengths.get(),
                                              n_reads));  // 3 read segmenets.
  ASSERT_OK(read.status());
  ASSERT_FALSE(read->result.is_err());

  auto& read_data = read->result.response().read_segments_data;
  ASSERT_EQ(read_data[0].data()[0], kTestRead0);
  ASSERT_EQ(read_data[1].data()[0], kTestRead1);
  ASSERT_EQ(read_data[2].data()[0], kTestRead2);
}

TEST(I2cChildTest, BadTransfers) {
  fake_ddk::Bind tester;
  ddk::I2cImplProtocolClient i2c = {};
  I2cChildTest server(fake_ddk::kFakeParent,
                      fbl::AdoptRef<I2cBus>(new I2cBus(fake_ddk::kFakeParent, i2c, 0)), 0);
  fidl::WireSyncClient<fuchsia_hardware_i2c::Device2> client_wrap(std::move(tester.FidlClient()));

  {
    // 2 write segments, inconsistent with 1 segment write below.
    bool is_write[] = {true, true};
    auto segments_is_write = fidl::VectorView<bool>::FromExternal(is_write);
    size_t n_write_bytes = 1;
    auto write_buffer = std::make_unique<uint8_t[]>(n_write_bytes);
    write_buffer[0] = kTestWrite0;
    auto write_segment = fidl::VectorView<uint8_t>::FromExternal(write_buffer.get(), n_write_bytes);

    auto read = client_wrap.Transfer(
        std::move(segments_is_write),
        // 1 segment write (incosistent with the 2 segments_is_write above).
        fidl::VectorView<fidl::VectorView<uint8_t>>::FromExternal(&write_segment, 1),
        fidl::VectorView<uint8_t>());  // No reads.
    ASSERT_OK(read.status());
    ASSERT_TRUE(read->result.is_err());
  }

  {
    bool is_write[] = {true};  // 1 write segment, inconsistent with segments below.
    auto segments_is_write = fidl::VectorView<bool>::FromExternal(is_write, countof(is_write));

    // 1 byte in 2 write segments.
    size_t n_write_bytes = 1;
    auto write_buffer = std::make_unique<uint8_t[]>(n_write_bytes);
    write_buffer[0] = kTestWrite0;
    fidl::VectorView<uint8_t> write_segments[2];
    write_segments[0] = fidl::VectorView<uint8_t>::FromExternal(write_buffer.get(), n_write_bytes);
    write_segments[1] = fidl::VectorView<uint8_t>::FromExternal(write_buffer.get(), n_write_bytes);

    auto read = client_wrap.Transfer(std::move(segments_is_write),
                                     fidl::VectorView<fidl::VectorView<uint8_t>>::FromExternal(
                                         write_segments, 2),        // 2 write segments.
                                     fidl::VectorView<uint8_t>());  // No reads.
    ASSERT_OK(read.status());
    ASSERT_TRUE(read->result.is_err());
  }

  {
    bool is_write[] = {false};  // 1 read segment, inconsistent with segments below.
    auto segments_is_write = fidl::VectorView<bool>::FromExternal(is_write, countof(is_write));

    // 2 read segments expecting 2 bytes each.
    constexpr size_t n_reads = 2;
    auto read_lengths = std::make_unique<uint8_t[]>(n_reads);
    read_lengths[0] = 2;
    read_lengths[1] = 2;

    auto read =
        client_wrap.Transfer(std::move(segments_is_write),
                             fidl::VectorView<fidl::VectorView<uint8_t>>(),  // No writes.
                             fidl::VectorView<uint8_t>::FromExternal(read_lengths.get(),
                                                                     n_reads));  // 2 read segments.
    ASSERT_OK(read.status());
    ASSERT_TRUE(read->result.is_err());
  }

  {
    bool is_write[] = {false, false};  // 2 read segments, inconsistent with segments below.
    auto segments_is_write = fidl::VectorView<bool>::FromExternal(is_write);

    // 1 read segment expecting 2 bytes.
    constexpr size_t n_reads = 1;
    auto read_lengths = std::make_unique<uint8_t[]>(n_reads);
    read_lengths[0] = 2;

    auto read =
        client_wrap.Transfer(std::move(segments_is_write),
                             fidl::VectorView<fidl::VectorView<uint8_t>>(nullptr, 0),  // No writes.
                             fidl::VectorView<uint8_t>::FromExternal(read_lengths.get(),
                                                                     n_reads));  // 1 read segment.
    ASSERT_OK(read.status());
    ASSERT_TRUE(read->result.is_err());
  }
}

}  // namespace i2c
