#include "tlbmc/utils/fram_utils.h"

#include <cstddef>
#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);
    }
  }

  const bool last_line_is_complete =
      !content.empty() && content.back() == '\n';

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

  // If the last line is not complete, it's likely truncated, so discard it.
  if (!last_line_is_complete && !lines.empty()) {
    lines.pop_back();
  }

  // Iterate through each line to find relevant information.
  for (size_t i = 0; i < lines.size(); ++i) {
    absl::string_view line = lines[i];
    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)) {
        const std::string board_serial_number =
            std::string(absl::StripAsciiWhitespace(
                message.substr(kBoardSerialNumberKey.length())));
        if (!board_serial_number.empty()) {
          parsed_data.board_serial_number = board_serial_number;
        }
      }
      continue;
    }

    if (module == "Bootloader") {
      // Handle Bootloader:Board Information: <value>
      if (absl::StartsWith(message, kBoardInfoKey)) {
        const std::string board_info_str = std::string(
            absl::StripAsciiWhitespace(message.substr(kBoardInfoKey.length())));

        if (!board_info_str.empty()) {
          parsed_data.board_info = board_info_str;
        }
        // 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, ' ', absl::SkipWhitespace());
        if (!board_parts.empty() && !board_parts[0].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
