#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/numbers.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;
  std::string board_part_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;
    }
  }

  // Determine part number based on serial number, mimicking gsys
  // CaviumPartInfo::GetPartInfo
  parsed_data.board_part_number = "CNL3560-NFBE-2.0-G";
  if (!parsed_data.board_serial_number.empty()) {
    size_t g_pos = parsed_data.board_serial_number.find('G');
    if (g_pos != std::string::npos && g_pos > 0) {
      double version_num = 0.0;
      if (absl::SimpleAtod(parsed_data.board_serial_number.substr(0, g_pos),
                           &version_num) &&
          version_num >= 6.0) {
        parsed_data.board_part_number = "CNL3560-NFBE-3.0-G";
      }
    }
  }

  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;
  }
  if (!parsed_data.board_part_number.empty()) {
    fru_data->mutable_fru_info()->set_board_part_number(
        parsed_data.board_part_number);
    (*fru_data->mutable_fields())["BOARD_PART_NUMBER"] =
        parsed_data.board_part_number;
  }

  return fru;
}

}  // namespace milotic_tlbmc
