// Copyright 2021 The Chromium OS 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 <optional>

#include <gtest/gtest.h>

#include "hps/dev.h"
#include "hps/hps_reg.h"

using hps::DevInterface;

namespace {

static int const kBlockSizeBytes = 128;

// Fake that implements a DevInterface.
// Setting fails_ will fail a read or write, and then decrement the
// fail count so that multiple retries will succeed after a set count.
// The cmd and len for each read and write are saved.
class DevInterfaceFake : public DevInterface {
 public:
  DevInterfaceFake() : fails_(0), cmd_(0), len_(0), reads_(0), writes_(0) {}
  ~DevInterfaceFake() override = default;
  bool ReadDevice(uint8_t cmd, uint8_t* data, size_t len) override {
    ++reads_;
    cmd_ = cmd;
    len_ = len;
    if (fails_ > 0) {
      --fails_;
      return false;
    }
    if (len == 2) {
      data[0] = data_[0];
      data[1] = data_[1];
    }
    return true;
  }
  bool WriteDevice(uint8_t cmd, const uint8_t* data, size_t len) override {
    ++writes_;
    cmd_ = cmd;
    len_ = len;
    if (fails_ > 0) {
      --fails_;
      return false;
    }
    if (len == 2) {
      data_[0] = data[0];
      data_[1] = data[1];
    }
    return true;
  }
  size_t BlockSizeBytes() override { return kBlockSizeBytes; }

  int fails_;        // If non-zero, fail the request and decrement this count.
  uint8_t cmd_;      // Command byte of request.
  size_t len_;       // Length of request.
  uint8_t data_[2];  // Data read or written.
  int reads_;        // Count of Read calls.
  int writes_;       // Count of Write calls.
};

class DevInterfaceTest : public testing::Test {
 protected:
  DevInterfaceFake dev_;
};

/*
 * Check that a ReadReg reads the correct data.
 */
TEST_F(DevInterfaceTest, ReadReg) {
  dev_.data_[0] = 0x12;
  dev_.data_[1] = 0x34;
  std::optional<uint16_t> d = dev_.ReadReg(hps::HpsReg::kMagic);
  EXPECT_EQ(d, 0x1234);
  EXPECT_EQ(dev_.len_, 2);
  EXPECT_EQ(dev_.cmd_, 0x80);
  dev_.data_[0] = 0x89;
  dev_.data_[1] = 0xAB;
  d = dev_.ReadReg(hps::HpsReg(32));
  EXPECT_EQ(d, 0x89AB);
  EXPECT_EQ(dev_.cmd_, 0x80 | 32);
  EXPECT_EQ(dev_.len_, 2);
  EXPECT_EQ(dev_.reads_, 2);
}

/*
 * Check that a WriteReg writes the correct data.
 */
TEST_F(DevInterfaceTest, WriteReg) {
  EXPECT_TRUE(dev_.WriteReg(hps::HpsReg::kMagic, 0x1234));
  EXPECT_EQ(dev_.data_[0], 0x12);
  EXPECT_EQ(dev_.data_[1], 0x34);
  EXPECT_EQ(dev_.len_, 2);
  EXPECT_EQ(dev_.cmd_, 0x80);
  EXPECT_TRUE(dev_.WriteReg(hps::HpsReg(32), 0x89AB));
  EXPECT_EQ(dev_.data_[0], 0x89);
  EXPECT_EQ(dev_.data_[1], 0xAB);
  EXPECT_EQ(dev_.cmd_, 0x80 | 32);
  EXPECT_EQ(dev_.len_, 2);
  EXPECT_EQ(dev_.writes_, 2);
}

/*
 * Verify that the correct block size is selected.
 */
TEST_F(DevInterfaceTest, BlockSize) {
  EXPECT_EQ(dev_.BlockSizeBytes(), kBlockSizeBytes);
}

}  //  namespace
