#include <algorithm>
#include <map>
#include <numeric>
#include "ipmi_fru_info_area.hpp"
#include <phosphor-logging/elog.hpp>
namespace ipmi
{
namespace fru
{
using namespace phosphor::logging;

//Property variables
static constexpr auto partNumber       = "PartNumber";
static constexpr auto serialNumber     = "SerialNumber";
static constexpr auto manufacturer     = "Manufacturer";
static constexpr auto buildDate        = "BuildDate";
static constexpr auto model            = "Model";
static constexpr auto prettyName       = "PrettyName";
static constexpr auto version          = "Version";

//Board info areas
static constexpr auto board            = "Board";
static constexpr auto chassis          = "Chassis";
static constexpr auto product          = "Product";

static constexpr auto specVersion              = 0x1;
static constexpr auto recordUnitOfMeasurement   = 0x8; //size in bytes
static constexpr auto checksumSize             = 0x1; //size in bytes
static constexpr auto recordNotPresent         = 0x0;
static constexpr auto englishLanguageCode      = 0x0;
static constexpr auto typeLengthByteNull       = 0x0;
static constexpr auto endOfCustomFields        = 0xC1;
static constexpr auto commonHeaderFormatSize   = 0x8; //size in bytes
static constexpr auto manufacturingDateSize     = 0x3;
static constexpr auto areaSizeOffset           = 0x1;
static constexpr uint8_t typeASCII             = 0xC0;
static constexpr auto maxRecordAttributeValue  = 0x1F;

/**
 * @brief Format Beginning of Individual IPMI FRU Data Section
 *
 * @param[in] langCode Language code
 * @param[in/out] data FRU area data
 */
void preFormatProcessing(bool langCode, FruAreaData& data)
{
    //Add id for version of FRU Info Storage Spec used
    data.emplace_back(specVersion);

    //Add Data Size - 0 as a placeholder, can edit after the data is finalized
    data.emplace_back(typeLengthByteNull);

    if (langCode)
    {
        data.emplace_back(englishLanguageCode);
    }
}

/**
 * @brief Append checksum of the FRU area data
 *
 * @param[in/out] data FRU area data
 */
void appendDataChecksum(FruAreaData& data)
{
    uint8_t checksumVal = std::accumulate(data.begin(), data.end(), 0);
    // Push the Zero checksum as the last byte of this data
    // This appears to be a simple summation of all the bytes
    data.emplace_back(-checksumVal);
}

/**
 * @brief Append padding bytes for the FRU area data
 *
 * @param[in/out] data FRU area data
 */
void padData(FruAreaData& data)
{
    uint8_t pad = (data.size() + checksumSize) % recordUnitOfMeasurement;
    if (pad)
    {
        data.resize((data.size() + recordUnitOfMeasurement - pad));
    }
}

/**
 * @brief Format End of Individual IPMI FRU Data Section
 *
 * @param[in/out] fruAreaData FRU area info data
 */
void postFormatProcessing(FruAreaData& data)
{
    //This area needs to be padded to a multiple of 8 bytes (after checksum)
    padData(data);

    //Set size of data info area
    data.at(areaSizeOffset) = (data.size() + checksumSize) /
        (recordUnitOfMeasurement);

    //Finally add area checksum
    appendDataChecksum(data);
}

/**
 * @brief Read property value from inventory and append to the FRU area data
 *
 * @param[in] key key to search for in the property inventory data
 * @param[in] propMap map of property values
 * @param[in,out] data FRU area data to be appended
 */
void appendData(const Property& key, const PropertyMap& propMap,
                FruAreaData& data)
{
    auto iter = propMap.find(key);
    if (iter != propMap.end())
    {
        auto value = iter->second;
        //If starts with 0x or 0X remove them
        //ex: 0x123a just take 123a
        if ((value.compare(0, 2, "0x")) == 0 ||
           (value.compare(0, 2, "0X") == 0))
        {
            value.erase(0, 2);
        }

        // 5 bits for length
        // if length is greater then 31(2^5) bytes then trim the data to 31 bytess.
        auto valueLength =  (value.length() > maxRecordAttributeValue) ?
            maxRecordAttributeValue : value.length();
        // 2 bits for type
        // Set the type to ascii
        uint8_t typeLength = valueLength | ipmi::fru::typeASCII;

        data.emplace_back(typeLength);
        std::copy(value.begin(),
                  value.begin() + valueLength,
                  std::back_inserter(data));
    }
    else
    {
        //set 0 size
        data.emplace_back(typeLengthByteNull);
    }
}


/**
 * @brief Appends Build Date
 *
 * @param[in] propMap map of property values
 * @param[in/out] data FRU area to add the manfufacture date
 */
void appendMfgDate(const PropertyMap& propMap, FruAreaData& data)
{
    //MFG Date/Time
    auto iter = propMap.find(buildDate);
    if (iter != propMap.end())
    {
        auto& value = iter->second;
        if (value.length() == manufacturingDateSize)
        {
            std::copy(
                value.begin(), value.end(), std::back_inserter(data));
            return;
        }
    }
    //Blank date
    data.emplace_back(0);
    data.emplace_back(0);
    data.emplace_back(0);
}

/**
 * @brief Builds a section of the common header
 *
 * @param[in] infoAreaSize size of the FRU area to write
 * @param[in] offset Current offset for data in overall record
 * @param[in/out] data Common Header section data container
 */
void buildCommonHeaderSection(
    const uint32_t& infoAreaSize, uint16_t& offset, FruAreaData& data)
{
    //Check if data for internal use section populated
    if (infoAreaSize == 0)
    {
        //Indicate record not present
        data.emplace_back(recordNotPresent);
    }
    else
    {
        // offset should be multiple of 8.
        auto remainder = offset % recordUnitOfMeasurement;
        // add the padding bytes in the offset so that offset
        // will be multiple of 8 byte.
        offset += (remainder > 0) ? recordUnitOfMeasurement - remainder : 0;
        //Place data to define offset to area data section
        data.emplace_back(offset / recordUnitOfMeasurement);

        offset += infoAreaSize;
    }
}

/**
 * @brief Builds the Chassis info area data section
 *
 * @param[in] propMap map of properties for chassis info area
 * @return FruAreaData container with chassis info area
 */
FruAreaData buildChassisInfoArea(const PropertyMap& propMap)
{
    FruAreaData fruAreaData;
    if (!propMap.empty())
    {
        //Set formatting data that goes at the beginning of the record
        preFormatProcessing(false, fruAreaData);

        //chassis type
        fruAreaData.emplace_back(0);

        //Chasiss part number, in config.yaml it is configured as model
        appendData(model, propMap, fruAreaData);

        //Board serial number
        appendData(serialNumber, propMap, fruAreaData);

        //Indicate End of Custom Fields
        fruAreaData.emplace_back(endOfCustomFields);

        //Complete record data formatting
        postFormatProcessing(fruAreaData);
    }
    return fruAreaData;
}

/**
 * @brief Builds the Board info area data section
 *
 * @param[in] propMap map of properties for board info area
 * @return FruAreaData container with board info area
 */
FruAreaData buildBoardInfoArea(const PropertyMap& propMap)
{
    FruAreaData fruAreaData;
    if (!propMap.empty())
    {
        preFormatProcessing(true, fruAreaData);

        //Manufacturing date
        appendMfgDate(propMap, fruAreaData);

        //manufacturer
        appendData(manufacturer, propMap, fruAreaData);

        //Product name/Pretty name
        appendData(prettyName, propMap, fruAreaData);

        //Board serial number
        appendData(serialNumber, propMap, fruAreaData);

        //Board part number
        appendData(partNumber, propMap, fruAreaData);

        //FRU File ID - Empty
        fruAreaData.emplace_back(typeLengthByteNull);

        // Empty FRU File ID bytes
        fruAreaData.emplace_back(recordNotPresent);

        //End of custom fields
        fruAreaData.emplace_back(endOfCustomFields);

        postFormatProcessing(fruAreaData);
    }
    return fruAreaData;
}

/**
 * @brief Builds the Product info area data section
 *
 * @param[in] propMap map of FRU properties for Board info area
 * @return FruAreaData container with product info area data
 */
FruAreaData buildProductInfoArea(const PropertyMap& propMap)
{
    FruAreaData fruAreaData;
    if (!propMap.empty())
    {
        //Set formatting data that goes at the beginning of the record
        preFormatProcessing(true, fruAreaData);

        //manufacturer
        appendData(manufacturer, propMap, fruAreaData);

        //Product name/Pretty name
        appendData(prettyName, propMap, fruAreaData);

        //Product part/model number
        appendData(model, propMap, fruAreaData);

        //Product version
        appendData(version, propMap, fruAreaData);

        //Serial Number
        appendData(serialNumber, propMap, fruAreaData);

        //Add Asset Tag
        fruAreaData.emplace_back(recordNotPresent);

        //FRU File ID - Empty
        fruAreaData.emplace_back(typeLengthByteNull);

        // Empty FRU File ID bytes
        fruAreaData.emplace_back(recordNotPresent);

        //End of custom fields
        fruAreaData.emplace_back(endOfCustomFields);

        postFormatProcessing(fruAreaData);
    }
    return fruAreaData;
}

FruAreaData buildFruAreaData(const FruInventoryData& inventory)
{
    FruAreaData combFruArea{};
    //Now build common header with data for this FRU Inv Record
    //Use this variable to increment size of header as we go along to determine
    //offset for the subsequent area offsets
    uint16_t curDataOffset = commonHeaderFormatSize;
    //First byte is id for version of FRU Info Storage Spec used
    combFruArea.emplace_back(specVersion);

    //2nd byte is offset to internal use data
    combFruArea.emplace_back(recordNotPresent);

    //3rd byte is offset to chassis data
    FruAreaData chassisArea;
    auto chassisIt = inventory.find(chassis);
    if (chassisIt != inventory.end())
    {
        chassisArea = std::move(buildChassisInfoArea(chassisIt->second));
    }
    // update the offset to chassis data.
    buildCommonHeaderSection(chassisArea.size(), curDataOffset, combFruArea);

    //4th byte is offset to board data
    FruAreaData boardArea;
    auto boardIt = inventory.find(board);
    if (boardIt != inventory.end())
    {
        boardArea = std::move(buildBoardInfoArea(boardIt->second));
    }
    // update the offset to the board data.
    buildCommonHeaderSection(boardArea.size(), curDataOffset, combFruArea);

    //5th byte is offset to product data
    FruAreaData prodArea;
    auto prodIt = inventory.find(product);
    if (prodIt != inventory.end())
    {
        prodArea = std::move(buildProductInfoArea(prodIt->second));
    }
    // update the offset to the product data.
    buildCommonHeaderSection(prodArea.size(), curDataOffset, combFruArea);

    //6th byte is offset to multirecord data
    combFruArea.emplace_back(recordNotPresent);

    //7th byte is PAD
    combFruArea.emplace_back(recordNotPresent);

    //8th (Final byte of Header Format) is the checksum
    appendDataChecksum(combFruArea);

    //Combine everything into one full IPMI FRU specification Record
    //add chassis use area data
    combFruArea.insert(
            combFruArea.end(), chassisArea.begin(), chassisArea.end());

    //add board area data
    combFruArea.insert(combFruArea.end(), boardArea.begin(), boardArea.end());

    //add product use area data
    combFruArea.insert(combFruArea.end(), prodArea.begin(), prodArea.end());

    return combFruArea;
}

} //fru
} //ipmi
