#include "tlbmc/hal/fru_scanner_fram.h"

#include <cstdint>
#include <memory>
#include <optional>
#include <utility>
#include <vector>

#include "absl/log/log.h"
#include "absl/memory/memory.h"
#include "absl/status/status.h"
#include "absl/status/statusor.h"
#include "absl/strings/str_cat.h"
#include "absl/time/time.h"
#include "io/smbus/smbus.h"
#include "time/clock.h"
#include "tlbmc/hal/fru_scanner.h"
#include "fru.pb.h"
#include "tlbmc/utils/fram_utils.h"

namespace milotic_tlbmc {

using SmbusLocation = ecclesia::SmbusLocation;
using SmbusBus = ecclesia::SmbusBus;
using SmbusAddress = ecclesia::SmbusAddress;

std::unique_ptr<FruScannerFram> FruScannerFram::Create(const Options& options) {
  return absl::WrapUnique(new FruScannerFram(options));
}

FruScannerFram::~FruScannerFram() = default;

absl::StatusOr<std::unique_ptr<I2cFruInfo>>
FruScannerFram::GetI2cFruInfoFromBus(int bus, int address,
                                     absl::Duration delay_between_reads) const {
  if (options_.fram_size == 0) {
    return absl::InvalidArgumentError(
        absl::StrCat("Invalid FRAM size: ", options_.fram_size));
  }

  LOG(INFO) << "Attempting to read FRAM at bus " << bus << " address "
            << address << " with size " << options_.fram_size << " bytes.";

  // Create a new I2cFruInfo object to store the data read from the FRAM.
  auto i2c_fru_info = std::make_unique<I2cFruInfo>();
  i2c_fru_info->bus = bus;
  i2c_fru_info->address = address;

  // Create an SmbusLocation object for the FRAM device.
  std::optional<SmbusLocation> location = SmbusLocation::TryMake(bus, address);
  if (!location.has_value()) {
    LOG(ERROR) << "Failed to create SmbusLocation for bus=" << bus
               << ", address=" << address;
    return absl::InvalidArgumentError(absl::StrCat(
        "Invalid bus or address for FRAM: bus=", bus, ", address=", address));
  }

  // Check if the device is present on the I2C bus.
  absl::Status probe_status = smbus_access_->ProbeDevice(*location);
  if (!probe_status.ok()) {
    LOG(ERROR) << "ProbeDevice failed at bus: " << bus
               << " address: " << address << " with status: " << probe_status;
    return absl::InternalError(
        absl::StrCat("No device found at bus: ", bus, " address: ", address,
                     " status: ", probe_status.ToString()));
  }
  LOG(INFO) << "ProbeDevice succeeded. Starting read of up to "
            << options_.fram_size << " bytes.";

  // Read bytes from the FRAM device.
  i2c_fru_info->data.reserve(options_.fram_size);

  // Set the initial offset by reading the first byte using Read8; this is to
  // set the initial offset for the subsequent ReceiveByte calls. FRAM has
  // auto-incrementing internal address pointer.
  uint8_t byte;
  absl::Status status = smbus_access_->Read8(*location, 0, &byte);
  if (!status.ok()) {
    LOG(ERROR) << "Failed to read first byte at offset 0: " << status;
    return status;  // Propagate the error
  }
  i2c_fru_info->data.push_back(byte);

  // Attempt to read subsequent bytes using ReceiveByte
  for (int offset = 1; offset < options_.fram_size; ++offset) {
    SleepIfNeeded(delay_between_reads);
    uint8_t received_byte;
    status = smbus_access_->ReceiveByte(*location, &received_byte);
    if (!status.ok()) {
      LOG(WARNING) << "ReceiveByte at offset " << offset
                   << " failed with status: " << status
                   << ". Skipping this byte and continuing.";
      continue;
    }
    i2c_fru_info->data.push_back(received_byte);
  }

  LOG(INFO) << "Finished reading " << i2c_fru_info->data.size() << " bytes.";

  // Check that what we read is potential Cavium HSM FRAM data. This is to
  // ensure that this FRAM scanner is only used for Cavium HSM FRAMs.
  absl::StatusOr<RawFru> fru = CreateRawFruFromFramData(i2c_fru_info);
  if (!fru.ok()) {
    LOG(WARNING) << "Failed to detect FRAM data at bus " << bus << " address "
                 << address << ": " << fru.status();
    return fru.status();
  }

  // Return the I2cFruInfo object containing the data read from the FRAM.
  return i2c_fru_info;
}

absl::StatusOr<std::vector<std::unique_ptr<I2cFruInfo>>>
FruScannerFram::ScanAllI2cFrus() const {
  std::vector<std::unique_ptr<I2cFruInfo>> frus;
  auto fru_info = GetI2cFruInfoFromBus(options_.bus, options_.address,
                                       absl::ZeroDuration());
  // Return empty vector considering that scanAllI2cFrus is supposed to scan
  // for different bus and addresses, and one failure should not block the
  // other bus and addresses. Additionally, not all platforms have FRAMs, so
  // this is not an error condition.
  if (!fru_info.ok()) {
    LOG(ERROR) << "Failed to read FRAM at bus " << options_.bus << " address "
               << options_.address << " with status: " << fru_info.status();
    return frus;
  }
  frus.push_back(std::move(*fru_info));

  return frus;
}

void FruScannerFram::SleepIfNeeded(absl::Duration delay) const {
  if (delay > absl::ZeroDuration()) {
    clock_->Sleep(delay);
  }
}

}  // namespace milotic_tlbmc
