// SPDX-License-Identifier: Apache-2.0
// SPDX-FileCopyrightText: Copyright 2018 Intel Corporation

#pragma once
#include "fru_reader.hpp"

#include <boost/container/flat_map.hpp>
#include <sdbusplus/asio/object_server.hpp>

#include <cstdint>
#include <cstdio>
#include <functional>
#include <regex>
#include <string>
#include <utility>
#include <vector>
extern "C"
{
// Include for I2C_SMBUS_BLOCK_MAX
#include <linux/i2c.h>
}

constexpr size_t fruBlockSize = 8;

using DeviceMap = boost::container::flat_map<int, std::vector<uint8_t>>;
using BusMap = boost::container::flat_map<int, std::shared_ptr<DeviceMap>>;

// NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables)
inline BusMap busMap;

enum class DecodeState
{
    ok,
    end,
    err,
};

enum class resCodes
{
    resOK,
    resWarn,
    resErr
};

enum class fruAreas
{
    fruAreaInternal = 0,
    fruAreaChassis,
    fruAreaBoard,
    fruAreaProduct,
    fruAreaMultirecord
};

struct FruArea
{
    size_t start;          // Fru Area Start offset
    size_t size;           // Fru Area Size
    size_t end;            // Fru Area end offset
    size_t updateFieldLoc; // Fru Area update Field Location
    size_t restFieldsLoc;  // Starting location of restFRUArea data
    size_t restFieldsEnd;  // Ending location of restFRUArea data
};

const std::vector<std::string> fruAreaNames = {"INTERNAL", "CHASSIS", "BOARD",
                                               "PRODUCT", "MULTIRECORD"};
const std::regex nonAsciiRegex("[^\x01-\x7f]");

const std::vector<std::string> chassisFruAreas = {"PART_NUMBER",
                                                  "SERIAL_NUMBER"};

const std::vector<std::string> boardFruAreas = {
    "MANUFACTURER", "PRODUCT_NAME", "SERIAL_NUMBER", "PART_NUMBER",
    "FRU_VERSION_ID"};

const std::vector<std::string> productFruAreas = {
    "MANUFACTURER",  "PRODUCT_NAME", "PART_NUMBER",   "VERSION",
    "SERIAL_NUMBER", "ASSET_TAG",    "FRU_VERSION_ID"};

const std::string fruCustomFieldName = "INFO_AM";

inline fruAreas operator++(fruAreas& x)
{
    return x = static_cast<fruAreas>(
               std::underlying_type<fruAreas>::type(x) + 1);
}

inline const std::string& getFruAreaName(fruAreas area)
{
    return fruAreaNames[static_cast<unsigned int>(area)];
}

std::tm intelEpoch();

char sixBitToChar(uint8_t val);

/* 0xd - 0xf are reserved values, but not fatal; use a placeholder char. */
constexpr std::array<char, 6> bcdHighChars = {
    ' ', '-', '.', 'X', 'X', 'X',
};

char bcdPlusToChar(uint8_t val);

bool verifyOffset(std::span<const uint8_t> fruBytes, fruAreas currentArea,
                  uint8_t len);

std::pair<DecodeState, std::string> decodeFRUData(
    std::span<const uint8_t>::const_iterator& iter,
    std::span<const uint8_t>::const_iterator& end, bool isLangEng);

bool checkLangEng(uint8_t lang);

resCodes formatIPMIFRU(
    std::span<const uint8_t> fruBytes,
    boost::container::flat_map<std::string, std::string>& result);

std::vector<uint8_t>& getFRUInfo(const uint16_t& bus, const uint8_t& address);

uint8_t calculateChecksum(std::span<const uint8_t>::const_iterator iter,
                          std::span<const uint8_t>::const_iterator end);

uint8_t calculateChecksum(std::span<const uint8_t> fruAreaData);

unsigned int updateFRUAreaLenAndChecksum(
    std::vector<uint8_t>& fruData, size_t fruAreaStart,
    size_t fruAreaEndOfFieldsOffset, size_t fruAreaEndOffset);

ssize_t getFieldLength(uint8_t fruFieldTypeLenValue);

/// \brief Find a FRU header.
/// \param reader the FRUReader to read via
/// \param errorHelp and a helper string for failures
/// \param blockData buffer to return the last read block
/// \param baseOffset the offset to start the search at;
///        set to 0 to perform search;
///        returns the offset at which a header was found
/// \return whether a header was found
bool findFRUHeader(FRUReader& reader, const std::string& errorHelp,
                   std::array<uint8_t, I2C_SMBUS_BLOCK_MAX>& blockData,
                   off_t& baseOffset);

/// \brief Read and validate FRU contents.
/// \param reader the FRUReader to read via
/// \param errorHelp and a helper string for failures
/// \return the FRU contents from the file and bool indicating if the FRU Header
/// was found
std::pair<std::vector<uint8_t>, bool> readFRUContents(
    FRUReader& reader, const std::string& errorHelp);

/// \brief Validate an IPMI FRU common header
/// \param blockData the bytes comprising the common header
/// \return true if valid
bool validateHeader(const std::array<uint8_t, I2C_SMBUS_BLOCK_MAX>& blockData);

/// \brief Get offset for a common header area
/// \param area - the area
/// \return the field offset
unsigned int getHeaderAreaFieldOffset(fruAreas area);

/// \brief Iterate fruArea Names and find offset/location and fields and size of
/// properties
/// \param fruData - vector to store fru data
/// \param propertyName - fru property Name
/// \param fruAreaParams - struct to have fru Area parameters like length,
/// size.
/// \return true if fru field is found, fruAreaParams like updateFieldLoc,
/// Start, Size, End are updated with fruArea and field info.
bool findFruAreaLocationAndField(std::vector<uint8_t>& fruData,
                                 const std::string& propertyName,
                                 struct FruArea& fruAreaParams);

/// \brief Copy the fru Area fields and properties into restFRUAreaFieldsData.
/// restFRUAreaField is the rest of the fields in FRU area after the field that
/// is being updated.
/// \param fruData - vector to store fru data
/// \param propertyName - fru property Name
/// \param fruAreaParams - struct to have fru Area parameters like length
/// \param restFRUAreaFieldsData - vector to store fru Area Fields and
/// properties.
/// \return true on success false on failure. restFieldLoc and restFieldEnd
/// are updated.

bool copyRestFRUArea(std::vector<uint8_t>& fruData,
                     const std::string& propertyName,
                     struct FruArea& fruAreaParams,
                     std::vector<uint8_t>& restFRUAreaFieldsData);

/// \brief Get all device dbus path and match path with product name using
/// regular expression and find the device index for all devices.
/// \param dbusInterfaceMap - Map to store fru device dbus path and interface
/// \param productName - fru device product name.
/// \return optional<int> highest index for fru device on success, return
/// nullopt on failure.
std::optional<int> findIndexForFRU(
    boost::container::flat_map<
        std::pair<size_t, size_t>,
        std::shared_ptr<sdbusplus::asio::dbus_interface>>& dbusInterfaceMap,
    std::string& productName);

/// \brief It does format fru data and find productName in the formatted
/// fru data and return productName.
/// \param device - vector that contains device list
/// \param formattedFRU - map that contains formatted FRU data
/// \param bus - bus number of the device
/// \param address - address of the device
/// \param unknownBusObjectCount - Unknown Bus object counter variable
/// \return optional string. it returns productName or NULL

std::optional<std::string> getProductName(
    std::vector<uint8_t>& device,
    boost::container::flat_map<std::string, std::string>& formattedFRU,
    uint32_t bus, uint32_t address, size_t& unknownBusObjectCount);

bool getFruData(std::vector<uint8_t>& fruData, uint32_t bus, uint32_t address);
