// 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 <gtest/gtest.h>

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

using hps::DevInterface;

namespace {

static int const kRetry = 5;
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) {}
  virtual ~DevInterfaceFake() {}
  bool Read(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 Write(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;
  int d = dev_.ReadReg(0);
  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(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(0, 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(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 a Read will fail once the retries are exceeded.
 */
TEST_F(DevInterfaceTest, ReadFail) {
  dev_.fails_ = kRetry;
  int d = dev_.ReadReg(0);
  EXPECT_EQ(d, -1);
  EXPECT_EQ(dev_.reads_, kRetry);
}

/*
 * Verify that a Write will fail once the retries are exceeded.
 */
TEST_F(DevInterfaceTest, WriteFail) {
  dev_.fails_ = kRetry;
  EXPECT_FALSE(dev_.WriteReg(0, 0x1234));
  EXPECT_EQ(dev_.writes_, kRetry);
}

/*
 * Verify that a failed Read will be retried and succeed with
 * the second attempt.
 */
TEST_F(DevInterfaceTest, ReadRetry) {
  dev_.fails_ = 1;
  dev_.data_[0] = 0x12;
  dev_.data_[1] = 0x34;
  int d = dev_.ReadReg(0);
  EXPECT_EQ(d, 0x1234);
  // One failed read, one success.
  EXPECT_EQ(dev_.reads_, 2);
}

/*
 * Verify that a failed Write will be retried and succeed with
 * the second attempt.
 */
TEST_F(DevInterfaceTest, WriteRetry) {
  dev_.fails_ = 1;
  EXPECT_TRUE(dev_.WriteReg(0, 0x1234));
  // One failed write, one success.
  EXPECT_EQ(dev_.writes_, 2);
}

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

}  //  namespace
