// Copyright 2024 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.

#ifndef LIB_DRIVER_FAKE_MMIO_REG_CPP_FAKE_MMIO_REG_H_
#define LIB_DRIVER_FAKE_MMIO_REG_CPP_FAKE_MMIO_REG_H_

#include <lib/fit/function.h>
#include <lib/mmio-ptr/fake.h>
#include <lib/mmio/mmio.h>

#include <vector>

namespace fake_mmio {

// Fakes a single MMIO register. This class is intended to be used with a fdf::MmioBuffer;
// operations on an instance of that class will be directed to the fake if the fake-mmio-reg library
// is a dependency of the test.
class FakeMmioReg {
 public:
  // Reads from the faked register. Returns the value set by the next expectation, or the default
  // value. The default is initially zero and can be set by calling ReadReturns() or Write(). This
  // method is expected to be called (indirectly) by the code under test.
  FakeMmioReg() {
    read_ = []() { return 0; };
    write_ = [](uint64_t value) {};
  }

  // Ses the read callback function. The function is invoked every time the faked register is read.
  void SetReadCallback(fit::function<uint64_t()> read) { read_ = std::move(read); }

  // Sets the write callback function. The function is invoked every time the faked register is
  // written.
  void SetWriteCallback(fit::function<void(uint64_t)> write) { write_ = std::move(write); }

  // Reads the faked register by calling the read callback and returning its value.
  uint64_t Read() { return read_(); }

  // Writes to the faked register. This method is expected to be called (indirectly) by the code
  // under test.
  void Write(uint64_t value) { write_(value); }

 private:
  // Callback functions for read and write operations.
  fit::function<void(uint64_t value)> write_;
  fit::function<uint64_t()> read_;
};

// Represents a region of fake MMIO registers. Each register is backed by a FakeMmioReg instance.
//
// Example:
// fake_mmio::FakeMmioRegRegion fake_registers(register_size, number_of_registers);
// fdf::MmioBuffer mmio_buffer(fake_registers.GetMmioBuffer());
// fake_registers[0].SetReadCallback(read_fn);
// fake_registers[0].SetWriteCallback(write_fn);
// SomeDriver dut(mmio_buffer);
//
// dut.DoSomeWork(); // backed by mmio_buffer.
class FakeMmioRegRegion {
 public:
  // Constructs a FakeMmioRegRegion backed by the given array. reg_size is the size of each
  // register in bytes, and reg_count is the total number of registers.
  FakeMmioRegRegion(size_t reg_size, size_t reg_count)
      : reg_size_(reg_size), reg_count_(reg_count) {
    ZX_ASSERT(reg_size_ > 0);
    regs_.resize(reg_count_);
  }

  // Accesses the FakeMmioReg at the given offset. Note that this is the byte offset of the region
  // of MMIO registers, not the index. The accessed FakeMmioReg will be at the index calculated by
  // |offset| / |reg_size_|
  const FakeMmioReg& operator[](size_t offset) const {
    ZX_ASSERT(offset / reg_size_ < reg_count_);
    return regs_[offset / reg_size_];
  }

  // Accesses the FakeMmioReg at the given offset. Note that this is the byte offset of the region
  // of MMIO registers, not the index. The accessed FakeMmioReg will be at the index calculated by
  // |offset| / |reg_size_|
  FakeMmioReg& operator[](size_t offset) {
    ZX_ASSERT(offset / reg_size_ < reg_count_);
    return regs_[offset / reg_size_];
  }

  // Constructs and returns a MmioBuffer object with a size that matches the FakeMmioReg.
  fdf::MmioBuffer GetMmioBuffer();

 private:
  static uint8_t Read8(const void* ctx, const mmio_buffer_t& mmio, zx_off_t offs);
  static uint16_t Read16(const void* ctx, const mmio_buffer_t& mmio, zx_off_t offs);
  static uint32_t Read32(const void* ctx, const mmio_buffer_t& mmio, zx_off_t offs);
  static uint64_t Read64(const void* ctx, const mmio_buffer_t& mmio, zx_off_t offs);

  static void Write8(const void* ctx, const mmio_buffer_t& mmio, uint8_t val, zx_off_t offs);
  static void Write16(const void* ctx, const mmio_buffer_t& mmio, uint16_t val, zx_off_t offs);
  static void Write32(const void* ctx, const mmio_buffer_t& mmio, uint32_t val, zx_off_t offs);
  static void Write64(const void* ctx, const mmio_buffer_t& mmio, uint64_t val, zx_off_t offs);

  std::vector<FakeMmioReg> regs_;
  const size_t reg_size_;
  const size_t reg_count_;
};

}  // namespace fake_mmio

#endif  // LIB_DRIVER_FAKE_MMIO_REG_CPP_FAKE_MMIO_REG_H_
