// Copyright 2021 The Pigweed Authors
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not
// use this file except in compliance with the License. You may obtain a copy of
// the License at
//
//     https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations under
// the License.
#include "pw_i2c/register_device.h"

#include "gtest/gtest.h"
#include "pw_assert/check.h"
#include "pw_bytes/byte_builder.h"

namespace pw {
namespace i2c {
namespace {

using ::pw::Status;
using namespace std::literals::chrono_literals;

constexpr uint8_t kErrorValue = 0x11;
constexpr Address kDummyDeviceAddress = Address::SevenBit<0x3F>();

constexpr chrono::SystemClock::duration kTimeout =
    std::chrono::duration_cast<chrono::SystemClock::duration>(100ms);

// Default test object. Mimics closely to I2c devices.
class TestInitiator : public Initiator {
 public:
  explicit TestInitiator() {}

  ByteBuilder& GetWriteBuffer() { return write_buffer_; }

  void SetReadData(ByteSpan read_data) {
    read_buffer_.append(read_data.data(), read_data.size());
  }

 private:
  Status DoWriteReadFor(Address,
                        ConstByteSpan tx_data,
                        ByteSpan rx_data,
                        chrono::SystemClock::duration) override {
    // Write
    if (tx_data.size() > 0) {
      write_buffer_.append(tx_data.data(), tx_data.size());
    }

    // Read
    if (rx_data.size() > 0) {
      PW_CHECK_UINT_EQ(
          read_buffer_.size(), rx_data.size(), "Buffer to read is too big");
      for (uint32_t i = 0; i < rx_data.size(); i++) {
        rx_data[i] = read_buffer_.data()[i];
      }
    }

    return OkStatus();
  }

  ByteBuffer<10> write_buffer_;
  ByteBuffer<10> read_buffer_;
};

TEST(RegisterDevice, Construction) {
  TestInitiator initiator;
  RegisterDevice device(initiator,
                        kDummyDeviceAddress,
                        std::endian::little,
                        RegisterAddressSize::k1Byte);
}

TEST(RegisterDevice, WriteRegisters8With2RegistersAnd1ByteAddress) {
  TestInitiator initiator;
  RegisterDevice device(initiator,
                        kDummyDeviceAddress,
                        std::endian::little,
                        RegisterAddressSize::k1Byte);

  std::array<std::byte, 2> register_data = {std::byte{0xCD}, std::byte{0xEF}};
  std::array<std::byte, 3> builder;
  constexpr uint32_t kRegisterAddress = 0xAB;
  EXPECT_EQ(
      device.WriteRegisters(kRegisterAddress, register_data, builder, kTimeout),
      pw::OkStatus());

  ByteBuilder& test_device_builder = initiator.GetWriteBuffer();
  EXPECT_EQ(sizeof(builder), test_device_builder.size());

  // Check address.
  EXPECT_EQ(kRegisterAddress,
            static_cast<uint32_t>(test_device_builder.data()[0]));

  // Check data.
  constexpr uint32_t kAddressSize =
      static_cast<uint32_t>(RegisterAddressSize::k1Byte);
  for (uint32_t i = 0; i < test_device_builder.size() - kAddressSize; i++) {
    EXPECT_EQ(register_data[i], test_device_builder.data()[i + kAddressSize]);
  }
}

TEST(RegisterDevice, WriteRegisters8With2RegistersAnd2ByteAddress) {
  TestInitiator initiator;
  RegisterDevice device(initiator,
                        kDummyDeviceAddress,
                        std::endian::little,
                        RegisterAddressSize::k2Bytes);

  constexpr uint32_t kRegisterAddress = 0x89AB;
  std::byte register_data[2] = {std::byte{0xCD}, std::byte{0xEF}};
  std::array<std::byte, 4> builder;
  EXPECT_EQ(
      device.WriteRegisters(kRegisterAddress, register_data, builder, kTimeout),
      pw::OkStatus());

  ByteBuilder& test_device_builder = initiator.GetWriteBuffer();
  EXPECT_EQ(sizeof(builder), test_device_builder.size());

  // Check address.
  const uint16_t kActualAddress = *(reinterpret_cast<uint16_t*>(
      const_cast<std::byte*>(test_device_builder.data())));
  EXPECT_EQ(kRegisterAddress, kActualAddress);

  // Check data.
  constexpr uint32_t kAddressSize =
      static_cast<uint32_t>(RegisterAddressSize::k2Bytes);
  for (uint32_t i = 0; i < test_device_builder.size() - kAddressSize; i++) {
    EXPECT_EQ(register_data[i], test_device_builder.data()[i + kAddressSize]);
  }
}

TEST(RegisterDevice, WriteRegisters16With2RegistersAnd2ByteAddress) {
  TestInitiator initiator;
  RegisterDevice device(initiator,
                        kDummyDeviceAddress,
                        std::endian::little,
                        RegisterAddressSize::k2Bytes);

  constexpr uint32_t kRegisterAddress = 0x89AB;
  std::array<uint16_t, 2> register_data = {0xCDEF, 0x1234};
  std::array<std::byte, 6> builder;
  EXPECT_EQ(device.WriteRegisters16(
                kRegisterAddress, register_data, builder, kTimeout),
            pw::OkStatus());

  ByteBuilder& test_device_builder = initiator.GetWriteBuffer();
  EXPECT_EQ(sizeof(builder), test_device_builder.size());

  // Check address.
  const uint16_t kActualAddress = *(reinterpret_cast<uint16_t*>(
      const_cast<std::byte*>(test_device_builder.data())));
  EXPECT_EQ(kRegisterAddress, kActualAddress);

  // Check data.
  constexpr uint32_t kAddressSize =
      static_cast<uint32_t>(RegisterAddressSize::k2Bytes);

  const uint16_t* read_pointer = reinterpret_cast<const uint16_t*>(
      test_device_builder.data() + kAddressSize);
  for (uint32_t i = 0; i < (test_device_builder.size() - kAddressSize) /
                               sizeof(register_data[0]);
       i++) {
    EXPECT_EQ(register_data[i], read_pointer[i]);
  }
}

TEST(RegisterDevice, WriteRegisters16With2RegistersAnd2ByteAddressBigEndian) {
  TestInitiator initiator;
  RegisterDevice device(initiator,
                        kDummyDeviceAddress,
                        std::endian::big,
                        RegisterAddressSize::k2Bytes);

  constexpr uint32_t kRegisterAddress = 0x89AB;
  std::array<uint16_t, 2> register_data = {0xCDEF, 0x1234};
  std::array<std::byte, 6> builder;
  EXPECT_EQ(device.WriteRegisters16(
                kRegisterAddress, register_data, builder, kTimeout),
            pw::OkStatus());

  ByteBuilder& test_device_builder = initiator.GetWriteBuffer();
  EXPECT_EQ(sizeof(builder), test_device_builder.size());

  // Check address.
  const uint16_t kActualAddress = *(reinterpret_cast<uint16_t*>(
      const_cast<std::byte*>(test_device_builder.data())));
  EXPECT_EQ(bytes::ReadInOrder<uint16_t>(std::endian::big, &kRegisterAddress),
            kActualAddress);

  // Check data.
  constexpr uint32_t kAddressSize =
      static_cast<uint32_t>(RegisterAddressSize::k2Bytes);

  const uint16_t* read_pointer = reinterpret_cast<const uint16_t*>(
      test_device_builder.data() + kAddressSize);
  for (uint32_t i = 0; i < (test_device_builder.size() - kAddressSize) /
                               sizeof(register_data[0]);
       i++) {
    EXPECT_EQ(bytes::ReadInOrder<uint16_t>(std::endian::big, &register_data[i]),
              read_pointer[i]);
  }
}

TEST(RegisterDevice, WriteRegisters8BufferTooSmall) {
  TestInitiator initiator;
  RegisterDevice device(initiator,
                        kDummyDeviceAddress,
                        std::endian::little,
                        RegisterAddressSize::k2Bytes);

  constexpr uint32_t kRegisterAddress = 0x89AB;
  std::array<std::byte, 2> register_data = {std::byte{0xCD}, std::byte{0xEF}};
  std::array<std::byte, 2> builder;
  EXPECT_EQ(
      device.WriteRegisters(kRegisterAddress, register_data, builder, kTimeout),
      pw::Status::OutOfRange());
}

TEST(RegisterDevice, WriteRegister16With1ByteAddress) {
  TestInitiator initiator;
  RegisterDevice device(initiator,
                        kDummyDeviceAddress,
                        std::endian::little,
                        RegisterAddressSize::k1Byte);

  constexpr uint32_t kRegisterAddress = 0xAB;
  constexpr uint16_t kRegisterData = 0xBCDE;
  EXPECT_EQ(device.WriteRegister16(kRegisterAddress, kRegisterData, kTimeout),
            pw::OkStatus());

  constexpr uint32_t kAddressSize =
      static_cast<uint32_t>(RegisterAddressSize::k1Byte);
  ByteBuilder& test_device_builder = initiator.GetWriteBuffer();
  EXPECT_EQ(test_device_builder.size(), kAddressSize + sizeof(kRegisterData));

  // Check address.
  EXPECT_EQ(kRegisterAddress,
            static_cast<uint32_t>(test_device_builder.data()[0]));

  // Check data.
  for (uint32_t i = 0; i < test_device_builder.size() - kAddressSize; i++) {
    EXPECT_EQ(
        (kRegisterData >> (8 * i)) & 0xFF,
        static_cast<uint16_t>(test_device_builder.data()[i + kAddressSize]));
  }
}

TEST(RegisterDevice, WriteRegister32With1ByteAddress) {
  TestInitiator initiator;
  RegisterDevice device(initiator,
                        kDummyDeviceAddress,
                        std::endian::little,
                        RegisterAddressSize::k1Byte);

  constexpr uint32_t kRegisterAddress = 0xAB;
  constexpr uint32_t kRegisterData = 0xBCCDDEEF;
  EXPECT_EQ(device.WriteRegister32(kRegisterAddress, kRegisterData, kTimeout),
            pw::OkStatus());

  constexpr uint32_t kAddressSize =
      static_cast<uint32_t>(RegisterAddressSize::k1Byte);
  ByteBuilder& test_device_builder = initiator.GetWriteBuffer();
  EXPECT_EQ(test_device_builder.size(), kAddressSize + sizeof(kRegisterData));

  // Check address.
  EXPECT_EQ(kRegisterAddress,
            static_cast<uint32_t>(test_device_builder.data()[0]));

  // Check data.
  for (uint32_t i = 0; i < test_device_builder.size() - kAddressSize; i++) {
    EXPECT_EQ(
        (kRegisterData >> (8 * i)) & 0xFF,
        static_cast<uint32_t>(test_device_builder.data()[i + kAddressSize]));
  }
}

TEST(RegisterDevice, WriteRegister16with2ByteAddress) {
  TestInitiator initiator;
  RegisterDevice device(initiator,
                        kDummyDeviceAddress,
                        std::endian::little,
                        RegisterAddressSize::k2Bytes);

  constexpr uint32_t kRegisterAddress = 0xAB23;
  constexpr uint16_t kRegisterData = 0xBCDD;
  EXPECT_EQ(device.WriteRegister16(kRegisterAddress, kRegisterData, kTimeout),
            pw::OkStatus());

  constexpr uint32_t kAddressSize =
      static_cast<uint32_t>(RegisterAddressSize::k2Bytes);
  ByteBuilder& test_device_builder = initiator.GetWriteBuffer();
  EXPECT_EQ(test_device_builder.size(), kAddressSize + sizeof(kRegisterData));

  // Check address.
  const uint16_t kActualAddress = *(reinterpret_cast<uint16_t*>(
      const_cast<std::byte*>(test_device_builder.data())));
  EXPECT_EQ(kRegisterAddress, kActualAddress);

  // Check data.
  for (uint32_t i = 0; i < test_device_builder.size() - kAddressSize; i++) {
    EXPECT_EQ(
        (kRegisterData >> (8 * i)) & 0xFF,
        static_cast<uint16_t>(test_device_builder.data()[i + kAddressSize]));
  }
}

TEST(RegisterDevice, WriteRegister16With1ByteAddressAndBigEndian) {
  TestInitiator initiator;
  RegisterDevice device(initiator,
                        kDummyDeviceAddress,
                        std::endian::big,
                        RegisterAddressSize::k1Byte);

  constexpr uint32_t kRegisterAddress = 0xAB;
  constexpr uint16_t kRegisterData = 0xBCDE;
  EXPECT_EQ(device.WriteRegister16(kRegisterAddress, kRegisterData, kTimeout),
            pw::OkStatus());

  constexpr uint32_t kAddressSize =
      static_cast<uint32_t>(RegisterAddressSize::k1Byte);
  ByteBuilder& test_device_builder = initiator.GetWriteBuffer();
  EXPECT_EQ(test_device_builder.size(), kAddressSize + sizeof(kRegisterData));

  // Check address.
  EXPECT_EQ(kRegisterAddress,
            static_cast<uint32_t>(test_device_builder.data()[0]));

  // Check data.
  for (uint32_t i = 0; i < test_device_builder.size() - kAddressSize; i++) {
    const uint32_t shift = test_device_builder.size() - kAddressSize - (i + 1);
    EXPECT_EQ(
        (kRegisterData >> (8 * shift)) & 0xFF,
        static_cast<uint16_t>(test_device_builder.data()[i + kAddressSize]));
  }
}

TEST(RegisterDevice, WriteRegister32With1ByteAddressAndBigEndian) {
  TestInitiator initiator;
  RegisterDevice device(initiator,
                        kDummyDeviceAddress,
                        std::endian::big,
                        RegisterAddressSize::k1Byte);

  constexpr uint32_t kRegisterAddress = 0xAB;
  constexpr uint32_t kRegisterData = 0xBCCDDEEF;
  EXPECT_EQ(device.WriteRegister32(kRegisterAddress, kRegisterData, kTimeout),
            pw::OkStatus());

  constexpr uint32_t kAddressSize =
      static_cast<uint32_t>(RegisterAddressSize::k1Byte);
  ByteBuilder& test_device_builder = initiator.GetWriteBuffer();
  EXPECT_EQ(test_device_builder.size(), kAddressSize + sizeof(kRegisterData));

  // Check address.
  EXPECT_EQ(kRegisterAddress,
            static_cast<uint32_t>(test_device_builder.data()[0]));

  // Check data.
  for (uint32_t i = 0; i < test_device_builder.size() - kAddressSize; i++) {
    const uint32_t shift = test_device_builder.size() - kAddressSize - (i + 1);
    EXPECT_EQ(
        (kRegisterData >> (8 * shift)) & 0xFF,
        static_cast<uint32_t>(test_device_builder.data()[i + kAddressSize]));
  }
}

TEST(RegisterDevice, WriteRegister16With2ByteAddressAndBigEndian) {
  TestInitiator initiator;
  RegisterDevice device(initiator,
                        kDummyDeviceAddress,
                        std::endian::big,
                        RegisterAddressSize::k2Bytes);

  constexpr uint32_t kRegisterAddress = 0xAB11;
  constexpr uint16_t kRegisterData = 0xBCDF;
  EXPECT_EQ(device.WriteRegister16(kRegisterAddress, kRegisterData, kTimeout),
            pw::OkStatus());

  constexpr uint32_t kAddressSize =
      static_cast<uint32_t>(RegisterAddressSize::k2Bytes);
  ByteBuilder& test_device_builder = initiator.GetWriteBuffer();
  EXPECT_EQ(test_device_builder.size(), kAddressSize + sizeof(kRegisterData));

  // Check address.
  const uint16_t kActualAddress = *(reinterpret_cast<uint16_t*>(
      const_cast<std::byte*>(test_device_builder.data())));
  EXPECT_EQ(bytes::ReadInOrder<uint16_t>(std::endian::big, &kRegisterAddress),
            kActualAddress);

  // Check data.
  for (uint32_t i = 0; i < test_device_builder.size() - kAddressSize; i++) {
    const uint32_t shift = test_device_builder.size() - kAddressSize - (i + 1);
    EXPECT_EQ(
        (kRegisterData >> (8 * shift)) & 0xFF,
        static_cast<uint16_t>(test_device_builder.data()[i + kAddressSize]));
  }
}

TEST(RegisterDevice, ReadRegisters8ByteWith2RegistersAnd1ByteAddress) {
  TestInitiator initiator;
  RegisterDevice device(initiator,
                        kDummyDeviceAddress,
                        std::endian::little,
                        RegisterAddressSize::k1Byte);

  std::array<std::byte, 2> register_data = {std::byte{0xCD}, std::byte{0xEF}};
  initiator.SetReadData(register_data);

  std::array<std::byte, 2> buffer;
  constexpr uint32_t kRegisterAddress = 0xAB;
  EXPECT_EQ(device.ReadRegisters(kRegisterAddress, buffer, kTimeout),
            pw::OkStatus());

  // Check address.
  ByteBuilder& address_buffer = initiator.GetWriteBuffer();
  EXPECT_EQ(static_cast<uint32_t>(RegisterAddressSize::k1Byte),
            address_buffer.size());

  const uint8_t kActualAddress = *(reinterpret_cast<uint8_t*>(
      const_cast<std::byte*>(address_buffer.data())));
  EXPECT_EQ(kRegisterAddress, kActualAddress);

  // Check data.
  for (uint32_t i = 0; i < sizeof(buffer); i++) {
    EXPECT_EQ(buffer[i], register_data[i]);
  }
}

TEST(RegisterDevice, ReadRegisters8IntWith2RegistersAnd1ByteAddress) {
  TestInitiator initiator;
  RegisterDevice device(initiator,
                        kDummyDeviceAddress,
                        std::endian::little,
                        RegisterAddressSize::k1Byte);

  std::array<uint8_t, 2> register_data = {0xCD, 0xEF};
  initiator.SetReadData(std::as_writable_bytes(
      std::span(register_data.data(), register_data.size())));

  std::array<uint8_t, 2> buffer;
  constexpr uint32_t kRegisterAddress = 0xAB;
  EXPECT_EQ(device.ReadRegisters8(kRegisterAddress, buffer, kTimeout),
            pw::OkStatus());

  // Check address.
  ByteBuilder& address_buffer = initiator.GetWriteBuffer();
  EXPECT_EQ(static_cast<uint32_t>(RegisterAddressSize::k1Byte),
            address_buffer.size());

  const uint8_t kActualAddress = *(reinterpret_cast<uint8_t*>(
      const_cast<std::byte*>(address_buffer.data())));
  EXPECT_EQ(kRegisterAddress, kActualAddress);

  // Check data.
  for (uint32_t i = 0; i < sizeof(buffer); i++) {
    EXPECT_EQ(buffer[i], register_data[i]);
  }
}

TEST(RegisterDevice, ReadRegisters8ByteWith2RegistersAnd2ByteAddress) {
  TestInitiator initiator;
  RegisterDevice device(initiator,
                        kDummyDeviceAddress,
                        std::endian::little,
                        RegisterAddressSize::k2Bytes);

  std::array<std::byte, 2> register_data = {std::byte{0xCD}, std::byte{0xEF}};
  initiator.SetReadData(register_data);

  std::array<std::byte, 2> buffer;
  constexpr uint32_t kRegisterAddress = 0xABBA;
  EXPECT_EQ(device.ReadRegisters(kRegisterAddress, buffer, kTimeout),
            pw::OkStatus());

  // Check address.
  ByteBuilder& address_buffer = initiator.GetWriteBuffer();
  EXPECT_EQ(static_cast<uint32_t>(RegisterAddressSize::k2Bytes),
            address_buffer.size());

  const uint16_t kActualAddress = *(reinterpret_cast<uint16_t*>(
      const_cast<std::byte*>(address_buffer.data())));
  EXPECT_EQ(kRegisterAddress, kActualAddress);

  // Check data.
  for (uint32_t i = 0; i < sizeof(buffer); i++) {
    EXPECT_EQ(buffer[i], register_data[i]);
  }
}

TEST(RegisterDevice, ReadRegisters16With2RegistersAnd2ByteAddress) {
  TestInitiator initiator;
  RegisterDevice device(initiator,
                        kDummyDeviceAddress,
                        std::endian::little,
                        RegisterAddressSize::k2Bytes);

  std::array<uint16_t, 2> register_data = {0xCDEF, 0x1234};
  initiator.SetReadData(std::as_writable_bytes(
      std::span(register_data.data(), register_data.size())));

  std::array<uint16_t, 2> buffer;
  constexpr uint32_t kRegisterAddress = 0xAB;
  EXPECT_EQ(device.ReadRegisters16(kRegisterAddress, buffer, kTimeout),
            pw::OkStatus());

  // Check address.
  ByteBuilder& address_buffer = initiator.GetWriteBuffer();
  EXPECT_EQ(static_cast<uint32_t>(RegisterAddressSize::k2Bytes),
            address_buffer.size());

  const uint16_t kActualAddress = *(reinterpret_cast<uint16_t*>(
      const_cast<std::byte*>(address_buffer.data())));
  EXPECT_EQ(kRegisterAddress, kActualAddress);

  // Check data.
  for (uint32_t i = 0; i < buffer.size(); i++) {
    EXPECT_EQ(buffer[i], register_data[i]);
  }
}

TEST(RegisterDevice, ReadRegisters16With2RegistersAnd2ByteAddressBigEndian) {
  TestInitiator initiator;
  RegisterDevice device(initiator,
                        kDummyDeviceAddress,
                        std::endian::big,
                        RegisterAddressSize::k2Bytes);

  std::array<uint16_t, 2> register_data = {0xCDEF, 0x1234};
  initiator.SetReadData(std::as_writable_bytes(
      std::span(register_data.data(), register_data.size())));

  std::array<uint16_t, 2> buffer;
  constexpr uint32_t kRegisterAddress = 0xAB;
  EXPECT_EQ(device.ReadRegisters16(kRegisterAddress, buffer, kTimeout),
            pw::OkStatus());

  // Check address.
  ByteBuilder& address_buffer = initiator.GetWriteBuffer();
  EXPECT_EQ(static_cast<uint32_t>(RegisterAddressSize::k2Bytes),
            address_buffer.size());

  const uint16_t kActualAddress = *(reinterpret_cast<uint16_t*>(
      const_cast<std::byte*>(address_buffer.data())));
  EXPECT_EQ(bytes::ReadInOrder<uint16_t>(std::endian::big, &kRegisterAddress),
            kActualAddress);

  // Check data.
  for (uint32_t i = 0; i < buffer.size(); i++) {
    EXPECT_EQ(bytes::ReadInOrder<uint16_t>(std::endian::big, &register_data[i]),
              buffer[i]);
  }
}

TEST(RegisterDevice, ReadRegister16With1ByteAddress) {
  TestInitiator initiator;
  RegisterDevice device(initiator,
                        kDummyDeviceAddress,
                        std::endian::little,
                        RegisterAddressSize::k1Byte);

  std::array<std::byte, 2> register_data = {std::byte{0xCD}, std::byte{0xEF}};
  initiator.SetReadData(register_data);

  constexpr uint32_t kRegisterAddress = 0xAB;
  Result<uint16_t> result = device.ReadRegister16(kRegisterAddress, kTimeout);
  EXPECT_TRUE(result.ok());
  uint16_t read_data = result.value_or(kErrorValue);

  // Check address.
  ByteBuilder& address_buffer = initiator.GetWriteBuffer();
  EXPECT_EQ(static_cast<uint32_t>(RegisterAddressSize::k1Byte),
            address_buffer.size());

  const uint8_t kActualAddress = *(reinterpret_cast<uint8_t*>(
      const_cast<std::byte*>(address_buffer.data())));
  EXPECT_EQ(kRegisterAddress, kActualAddress);

  // Check data.
  uint8_t* read_pointer = reinterpret_cast<uint8_t*>(&read_data);
  for (uint32_t i = 0; i < sizeof(read_data); i++) {
    EXPECT_EQ(read_pointer[i], static_cast<uint8_t>(register_data[i]));
  }
}

TEST(RegisterDevice, ReadRegister32With1ByteAddress) {
  TestInitiator initiator;
  RegisterDevice device(initiator,
                        kDummyDeviceAddress,
                        std::endian::little,
                        RegisterAddressSize::k1Byte);

  std::array<std::byte, 4> register_data = {
      std::byte{0x98}, std::byte{0x76}, std::byte{0x54}, std::byte{0x32}};
  initiator.SetReadData(register_data);

  constexpr uint32_t kRegisterAddress = 0xAB;
  Result<uint32_t> result = device.ReadRegister32(kRegisterAddress, kTimeout);
  EXPECT_TRUE(result.ok());
  uint32_t read_data = result.value_or(kErrorValue);

  // Check address.
  ByteBuilder& address_buffer = initiator.GetWriteBuffer();
  EXPECT_EQ(static_cast<uint32_t>(RegisterAddressSize::k1Byte),
            address_buffer.size());

  const uint8_t kActualAddress = *(reinterpret_cast<uint8_t*>(
      const_cast<std::byte*>(address_buffer.data())));
  EXPECT_EQ(kRegisterAddress, kActualAddress);

  // Check data.
  uint8_t* read_pointer = reinterpret_cast<uint8_t*>(&read_data);
  for (uint32_t i = 0; i < sizeof(read_data); i++) {
    EXPECT_EQ(read_pointer[i], static_cast<uint8_t>(register_data[i]));
  }
}

TEST(RegisterDevice, ReadRegister16With2ByteAddress) {
  TestInitiator initiator;
  RegisterDevice device(initiator,
                        kDummyDeviceAddress,
                        std::endian::little,
                        RegisterAddressSize::k2Bytes);

  std::array<std::byte, 2> register_data = {std::byte{0x98}, std::byte{0x76}};
  initiator.SetReadData(register_data);

  constexpr uint32_t kRegisterAddress = 0xA4AB;
  Result<uint16_t> result = device.ReadRegister16(kRegisterAddress, kTimeout);
  EXPECT_TRUE(result.ok());
  uint16_t read_data = result.value_or(kErrorValue);

  // Check address.
  ByteBuilder& address_buffer = initiator.GetWriteBuffer();
  EXPECT_EQ(static_cast<uint32_t>(RegisterAddressSize::k2Bytes),
            address_buffer.size());

  const uint16_t kActualAddress = *(reinterpret_cast<uint16_t*>(
      const_cast<std::byte*>(address_buffer.data())));
  EXPECT_EQ(kRegisterAddress, kActualAddress);

  // Check data.
  uint8_t* read_pointer = reinterpret_cast<uint8_t*>(&read_data);
  for (uint32_t i = 0; i < sizeof(read_data); i++) {
    EXPECT_EQ(read_pointer[i], static_cast<uint8_t>(register_data[i]));
  }
}

TEST(RegisterDevice, ReadRegister16With1ByteAddressAndBigEndian) {
  TestInitiator initiator;
  RegisterDevice device(initiator,
                        kDummyDeviceAddress,
                        std::endian::big,
                        RegisterAddressSize::k1Byte);

  std::array<std::byte, 2> register_data = {std::byte{0x98}, std::byte{0x76}};
  initiator.SetReadData(register_data);

  constexpr uint32_t kRegisterAddress = 0xAB;
  Result<uint16_t> result = device.ReadRegister16(kRegisterAddress, kTimeout);
  EXPECT_TRUE(result.ok());
  uint16_t read_data = result.value_or(kErrorValue);

  // Check address.
  ByteBuilder& address_buffer = initiator.GetWriteBuffer();
  EXPECT_EQ(static_cast<uint32_t>(RegisterAddressSize::k1Byte),
            address_buffer.size());

  const uint8_t kActualAddress = *(reinterpret_cast<uint8_t*>(
      const_cast<std::byte*>(address_buffer.data())));
  EXPECT_EQ(kRegisterAddress, kActualAddress);

  // Check data.
  uint8_t* read_pointer = reinterpret_cast<uint8_t*>(&read_data);
  for (uint32_t i = 0; i < sizeof(read_data); i++) {
    const uint32_t kReadPointerIndex = sizeof(read_data) - 1 - i;
    EXPECT_EQ(read_pointer[kReadPointerIndex],
              static_cast<uint8_t>(register_data[i]));
  }
}

TEST(RegisterDevice, ReadRegister32With1ByteAddressAndBigEndian) {
  TestInitiator initiator;
  RegisterDevice device(initiator,
                        kDummyDeviceAddress,
                        std::endian::big,
                        RegisterAddressSize::k1Byte);

  std::array<std::byte, 4> register_data = {
      std::byte{0x98}, std::byte{0x76}, std::byte{0x54}, std::byte{0x32}};
  initiator.SetReadData(register_data);

  constexpr uint32_t kRegisterAddress = 0xAB;
  Result<uint32_t> result = device.ReadRegister32(kRegisterAddress, kTimeout);
  EXPECT_TRUE(result.ok());
  uint32_t read_data = result.value_or(kErrorValue);

  // Check address.
  ByteBuilder& address_buffer = initiator.GetWriteBuffer();
  EXPECT_EQ(static_cast<uint32_t>(RegisterAddressSize::k1Byte),
            address_buffer.size());

  const uint8_t kActualAddress = *(reinterpret_cast<uint8_t*>(
      const_cast<std::byte*>(address_buffer.data())));
  EXPECT_EQ(kRegisterAddress, kActualAddress);

  // Check data.
  uint8_t* read_pointer = reinterpret_cast<uint8_t*>(&read_data);
  for (uint32_t i = 0; i < sizeof(read_data); i++) {
    const uint32_t kReadPointerIndex = sizeof(read_data) - 1 - i;
    EXPECT_EQ(read_pointer[kReadPointerIndex],
              static_cast<uint8_t>(register_data[i]));
  }
}

TEST(RegisterDevice, ReadRegister16With2ByteAddressAndBigEndian) {
  TestInitiator initiator;
  RegisterDevice device(initiator,
                        kDummyDeviceAddress,
                        std::endian::big,
                        RegisterAddressSize::k2Bytes);

  std::array<std::byte, 2> register_data = {std::byte{0x98}, std::byte{0x76}};
  initiator.SetReadData(register_data);

  constexpr uint32_t kRegisterAddress = 0xABEF;
  Result<uint16_t> result = device.ReadRegister16(kRegisterAddress, kTimeout);
  EXPECT_TRUE(result.ok());
  uint16_t read_data = result.value_or(kErrorValue);

  // Check address.
  ByteBuilder& address_buffer = initiator.GetWriteBuffer();
  EXPECT_EQ(static_cast<uint32_t>(RegisterAddressSize::k2Bytes),
            address_buffer.size());

  const uint16_t kActualAddress = *(reinterpret_cast<uint16_t*>(
      const_cast<std::byte*>(address_buffer.data())));
  EXPECT_EQ(bytes::ReadInOrder<uint16_t>(std::endian::big, &kRegisterAddress),
            kActualAddress);

  // Check data.
  uint8_t* read_pointer = reinterpret_cast<uint8_t*>(&read_data);
  for (uint32_t i = 0; i < sizeof(read_data); i++) {
    const uint32_t kReadPointerIndex = sizeof(read_data) - 1 - i;
    EXPECT_EQ(read_pointer[kReadPointerIndex],
              static_cast<uint8_t>(register_data[i]));
  }
}

}  // namespace
}  // namespace i2c
}  // namespace pw
