#include "tlbmc/utils/fram_utils.h"

#include <cstdint>
#include <memory>
#include <string>
#include <vector>

#include "absl/log/log.h"
#include "absl/status/status.h"
#include "absl/status/statusor.h"
#include "absl/strings/ascii.h"
#include "absl/strings/match.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/str_split.h"
#include "absl/strings/string_view.h"
#include "tlbmc/hal/fru_scanner.h"
#include "fru.pb.h"

namespace milotic_tlbmc {
namespace {

// Struct to hold the data extracted from the FRAM.
struct FramData {
  std::string board_info;
  std::string board_product_name;
  std::string board_serial_number;
};

constexpr absl::string_view kBoardSerialNumberKey = "Board Serial Number:";
constexpr absl::string_view kBoardInfoKey = "Board Information:";

// Parses the raw byte data read from the FRAM.
// The FRAM contains text logs, not a standard IPMI FRU format.
// This function filters out non-printable characters and then parses
// lines starting with "INFO:" to extract key information.
//
// Example FRAM data:
// INFO:1003913708:Linux:Board Serial Number: 6.0G2337-VPM018009
// INFO:2143122215:Bootloader:Board Information: EBB6100 board rev 1
// INFO:1003913708:Linux:Firmware Version: CNN35XX-1.0.0
//
// Args:
//   data: The raw byte data read from the FRAM.
//
// Returns:
//   A FramData struct containing the extracted key-value pairs.
FramData ParseFramData(const std::vector<uint8_t>& data) {
  FramData parsed_data = {};
  if (data.empty()) {
    return parsed_data;  // Return empty struct if no data.
  }

  std::string content;
  content.reserve(data.size());
  for (uint8_t byte : data) {
    if (absl::ascii_isprint(static_cast<char>(byte)) || byte == '\n') {
      content += static_cast<char>(byte);
    }
  }

  // Split the content into lines.
  std::vector<absl::string_view> lines = absl::StrSplit(content, '\n');

  // Iterate through each line to find relevant information.
  for (const auto& line : lines) {
    absl::string_view trimmed_line = absl::StripAsciiWhitespace(line);
    // We only care about lines that start with "INFO:".
    if (!absl::StartsWith(trimmed_line, "INFO:")) {
      continue;
    }

    // Split the line by colons. Expected format: INFO:<ts>:<Module>:<Message>
    std::vector<absl::string_view> parts =
        absl::StrSplit(trimmed_line, absl::MaxSplits(':', 3));
    if (parts.size() < 4) {
      continue;  // Skip lines not matching the format.
    }

    // Extract Module and Message parts.
    absl::string_view module = absl::StripAsciiWhitespace(parts[2]);
    absl::string_view message = absl::StripAsciiWhitespace(parts[3]);

    if (module == "Linux") {
      // Handle Linux:Board Serial Number: <value>
      if (absl::StartsWith(message, kBoardSerialNumberKey)) {
        parsed_data.board_serial_number =
            std::string(absl::StripAsciiWhitespace(
                message.substr(kBoardSerialNumberKey.length())));
      }
      continue;
    }

    if (module == "Bootloader") {
      // Handle Bootloader:Board Information: <value>
      if (absl::StartsWith(message, kBoardInfoKey)) {
        parsed_data.board_info = std::string(
            absl::StripAsciiWhitespace(message.substr(kBoardInfoKey.length())));
        // Attempt to extract the product name from the Board Information.
        // This assumes the product name is the first word in the Board
        // Information string. This is based on the observed format:
        // "<ProductName> board revision major:X, minor:Y ..."
        // Therefore, splitting by space and taking the 0th index should give
        // the product name.
        // Example: "EBB6100 board revision major:1, minor:0, serial #: unknown"
        // Here, "EBB6100" is the product name.
        std::vector<std::string> board_parts =
            absl::StrSplit(parsed_data.board_info, ' ');
        if (!board_parts.empty()) {
          parsed_data.board_product_name = board_parts[0];
        }
      }
      continue;
    }
  }
  return parsed_data;  // Return the struct of extracted key-value pairs.
}

}  // namespace

// Creates a RawFru proto from the data read from the FRAM.
// It uses ParseFramData to get the key-value pairs and then populates
// the RawFru proto fields.
absl::StatusOr<RawFru> CreateRawFruFromFramData(
    const std::unique_ptr<I2cFruInfo>& i2c_fru) {
  // Parse the raw FRAM data to extract information.
  FramData parsed_data = ParseFramData(i2c_fru->data);

  if (parsed_data.board_serial_number.empty() ||
      parsed_data.board_info.empty() ||
      parsed_data.board_product_name.empty()) {
    return absl::InvalidArgumentError("Incomplete data parsed from FRAM");
  }

  // Initialize the RawFru proto.
  RawFru fru;
  fru.set_key(absl::StrCat(i2c_fru->bus, ":", i2c_fru->address));
  fru.mutable_i2c_info()->set_bus(i2c_fru->bus);
  fru.mutable_i2c_info()->set_address(i2c_fru->address);

  FruData* fru_data = fru.mutable_data();

  // Populate FRU fields from the parsed data.
  if (!parsed_data.board_serial_number.empty()) {
    fru_data->mutable_fru_info()->set_board_serial_number(
        parsed_data.board_serial_number);
    (*fru_data->mutable_fields())["BOARD_SERIAL_NUMBER"] =
        parsed_data.board_serial_number;
  }
  if (!parsed_data.board_product_name.empty()) {
    fru_data->mutable_fru_info()->set_board_product_name(
        parsed_data.board_product_name);
    (*fru_data->mutable_fields())["BOARD_PRODUCT_NAME"] =
        parsed_data.board_product_name;
  }
  if (!parsed_data.board_info.empty()) {
    (*fru_data->mutable_fields())["BOARD_INFO"] = parsed_data.board_info;
  }

  return fru;
}

}  // namespace milotic_tlbmc
