/*
{{copyright}} 
*/

/*
{{version}} 
*/

/*
{{license}} 
*/

#pragma once

#include <cstdint>
#include <span>

namespace sdi_uToolBox::generic
{
//--------------------------------------------------------------
class II2CBus
{
  public:
  enum class I2CStatus
  {
    Ok,
    Timeout,
    Error,
    Busy,
  };

  public:
  II2CBus()                                    = default;     // Constructor
  virtual ~II2CBus()                           = default;     // Destructor
  II2CBus(const II2CBus &other)                = delete;      // Copy constructor
  II2CBus(II2CBus &&other) noexcept            = delete;      // Move constructor
  II2CBus &operator=(const II2CBus &other)     = delete;      // Copy assignment
  II2CBus &operator=(II2CBus &&other) noexcept = delete;      // Move assignment

  virtual I2CStatus read(const uint8_t chipAddress, const std::span<uint8_t> &buffer) = 0;            // Read data from I2C device
  I2CStatus         read(const uint8_t chipAddress, uint8_t &value);                                  // Read data from I2C device
  virtual I2CStatus write(const uint8_t chipAddress, const std::span<const uint8_t> &buffer) = 0;     // Write data to I2C device
  I2CStatus         write(const uint8_t chipAddress, const uint8_t &value);                           // Write data to I2C device

  // virtual I2CStatus readEeprom(const uint8_t chipAddress, const uint32_t memoryAddress, const std::span<uint8_t> &buffer)        = 0;     // Read data from I2C memory device
  // virtual I2CStatus writeEeprom(const uint8_t chipAddress, const uint32_t memoryAddress, const std::span<const uint8_t> &buffer) = 0;     // Write data to I2C memory device

  virtual I2CStatus isDeviceReady(const uint8_t chipAddress) = 0;     // Check device readiness
};
//--------------------------------------------------------------

//--------------------------------------------------------------
inline II2CBus::I2CStatus II2CBus::read(const uint8_t chipAddress, uint8_t &value)
{
  // Create a std::span pointing to the single byte 'value'
  std::span<uint8_t, 1> single_byte_span{ &value, 1 };

  return read(chipAddress, single_byte_span);
}
//--------------------------------------------------------------
inline II2CBus::I2CStatus II2CBus::write(const uint8_t chipAddress, const uint8_t &value)
{
  // Create a std::span pointing to the single byte 'value'
  std::span<const uint8_t, 1> single_byte_span{ &value, 1 };

  return write(chipAddress, single_byte_span);
}
//--------------------------------------------------------------
}     // namespace sdi_uToolBox::generic
