#include "impl.hpp"

#include "const.hpp"
#include "defines.hpp"
#include "ibm_vpd_utils.hpp"
#include "types.hpp"
#include "vpd_exceptions.hpp"

#include <algorithm>
#include <exception>
#include <iomanip>
#include <iostream>
#include <iterator>
#include <sstream>
#include <tuple>
#include <unordered_map>

#include "vpdecc/vpdecc.h"

namespace openpower
{
namespace vpd
{
namespace parser
{
using namespace openpower::vpd::constants;
using namespace openpower::vpd::exceptions;

static const std::unordered_map<std::string, Record> supportedRecords = {
    {"VINI", Record::VINI}, {"OPFR", Record::OPFR}, {"OSYS", Record::OSYS}};

static const std::unordered_map<std::string, internal::KeywordInfo>
    supportedKeywords = {
        {"DR", std::make_tuple(record::Keyword::DR, keyword::Encoding::ASCII)},
        {"PN", std::make_tuple(record::Keyword::PN, keyword::Encoding::ASCII)},
        {"SN", std::make_tuple(record::Keyword::SN, keyword::Encoding::ASCII)},
        {"CC", std::make_tuple(record::Keyword::CC, keyword::Encoding::ASCII)},
        {"HW", std::make_tuple(record::Keyword::HW, keyword::Encoding::RAW)},
        {"B1", std::make_tuple(record::Keyword::B1, keyword::Encoding::B1)},
        {"VN", std::make_tuple(record::Keyword::VN, keyword::Encoding::ASCII)},
        {"MB", std::make_tuple(record::Keyword::MB, keyword::Encoding::MB)},
        {"MM", std::make_tuple(record::Keyword::MM, keyword::Encoding::ASCII)},
        {"UD", std::make_tuple(record::Keyword::UD, keyword::Encoding::UD)},
        {"VP", std::make_tuple(record::Keyword::VP, keyword::Encoding::ASCII)},
        {"VS", std::make_tuple(record::Keyword::VS, keyword::Encoding::ASCII)},
};

namespace
{
constexpr auto toHex(size_t c)
{
    constexpr auto map = "0123456789abcdef";
    return map[c];
}
} // namespace

/*readUInt16LE: Read 2 bytes LE data*/
static LE2ByteData readUInt16LE(Binary::const_iterator iterator)
{
    LE2ByteData lowByte = *iterator;
    LE2ByteData highByte = *(iterator + 1);
    lowByte |= (highByte << 8);
    return lowByte;
}

RecordOffset Impl::getVtocOffset() const
{
    auto vpdPtr = vpd.cbegin();
    std::advance(vpdPtr, offsets::VTOC_PTR);
    // Get VTOC Offset
    auto vtocOffset = readUInt16LE(vpdPtr);

    return vtocOffset;
}

#ifdef IPZ_PARSER
int Impl::vhdrEccCheck() const
{
    int rc = eccStatus::SUCCESS;
    auto vpdPtr = vpd.cbegin();

    auto l_status =
        vpdecc_check_data(const_cast<uint8_t*>(&vpdPtr[offsets::VHDR_RECORD]),
                          lengths::VHDR_RECORD_LENGTH,
                          const_cast<uint8_t*>(&vpdPtr[offsets::VHDR_ECC]),
                          lengths::VHDR_ECC_LENGTH);

    if (l_status != VPD_ECC_OK)
    {
        rc = eccStatus::FAILED;
    }

    return rc;
}

int Impl::vtocEccCheck() const
{
    int rc = eccStatus::SUCCESS;
    // Use another pointer to get ECC information from VHDR,
    // actual pointer is pointing to VTOC data

    auto vpdPtr = vpd.cbegin();

    // Get VTOC Offset
    auto vtocOffset = getVtocOffset();

    // Get the VTOC Length
    std::advance(vpdPtr, offsets::VTOC_PTR + sizeof(RecordOffset));
    auto vtocLength = readUInt16LE(vpdPtr);

    // Get the ECC Offset
    std::advance(vpdPtr, sizeof(RecordLength));
    auto vtocECCOffset = readUInt16LE(vpdPtr);

    // Get the ECC length
    std::advance(vpdPtr, sizeof(ECCOffset));
    auto vtocECCLength = readUInt16LE(vpdPtr);

    // Reset pointer to start of the vpd,
    // so that Offset will point to correct address
    vpdPtr = vpd.cbegin();
    auto l_status = vpdecc_check_data(
        const_cast<uint8_t*>(&vpdPtr[vtocOffset]), vtocLength,
        const_cast<uint8_t*>(&vpdPtr[vtocECCOffset]), vtocECCLength);

    if (l_status != VPD_ECC_OK)
    {
        rc = eccStatus::FAILED;
    }

    return rc;
}

int Impl::recordEccCheck(Binary::const_iterator iterator) const
{
    int rc = eccStatus::SUCCESS;

    auto recordOffset = readUInt16LE(iterator);

    std::advance(iterator, sizeof(RecordOffset));
    auto recordLength = readUInt16LE(iterator);

    std::advance(iterator, sizeof(RecordLength));
    auto eccOffset = readUInt16LE(iterator);

    std::advance(iterator, sizeof(ECCOffset));
    auto eccLength = readUInt16LE(iterator);

    if (eccLength == 0 || eccOffset == 0)
    {
        throw(VpdEccException(
            "Could not find ECC's offset or Length for Record:"));
    }

    if (recordOffset == 0 || recordLength == 0)
    {
        throw(VpdDataException("Could not find VPD record offset or VPD record "
                               "length for Record:"));
    }

    auto vpdPtr = vpd.cbegin();

    auto l_status = vpdecc_check_data(
        const_cast<uint8_t*>(&vpdPtr[recordOffset]), recordLength,
        const_cast<uint8_t*>(&vpdPtr[eccOffset]), eccLength);
    if (l_status != VPD_ECC_OK)
    {
        rc = eccStatus::FAILED;
    }

    return rc;
}
#endif

void Impl::checkHeader() const
{
    if (vpd.empty() || (lengths::RECORD_MIN > vpd.size()))
    {
        throw(VpdDataException("Malformed VPD"));
    }
    else
    {
        auto iterator = vpd.cbegin();
        std::advance(iterator, offsets::VHDR);
        auto stop = std::next(iterator, lengths::RECORD_NAME);
        std::string record(iterator, stop);
        if ("VHDR" != record)
        {
            throw(VpdDataException("VHDR record not found"));
        }

#ifdef IPZ_PARSER
        // Check ECC
        int rc = eccStatus::FAILED;
        rc = vhdrEccCheck();
        if (rc != eccStatus::SUCCESS)
        {
            throw(VpdEccException("ERROR: VHDR ECC check Failed"));
        }
#endif
    }
}

std::size_t Impl::readTOC(Binary::const_iterator& iterator) const
{
    // The offset to VTOC could be 1 or 2 bytes long
    RecordOffset vtocOffset = getVtocOffset();

    // Got the offset to VTOC, skip past record header and keyword header
    // to get to the record name.
    std::advance(iterator, vtocOffset + sizeof(RecordId) + sizeof(RecordSize) +
                               // Skip past the RT keyword, which contains
                               // the record name.
                               lengths::KW_NAME + sizeof(KwSize));

    auto stop = std::next(iterator, lengths::RECORD_NAME);
    std::string record(iterator, stop);
    if ("VTOC" != record)
    {
        throw(VpdDataException("VTOC record not found"));
    }

#ifdef IPZ_PARSER
    // Check ECC
    int rc = eccStatus::FAILED;
    rc = vtocEccCheck();
    if (rc != eccStatus::SUCCESS)
    {
        throw(VpdEccException("ERROR: VTOC ECC check Failed"));
    }
#endif
    // VTOC record name is good, now read through the TOC, stored in the PT
    // PT keyword; vpdBuffer is now pointing at the first character of the
    // name 'VTOC', jump to PT data.
    // Skip past record name and KW name, 'PT'
    std::advance(iterator, lengths::RECORD_NAME + lengths::KW_NAME);
    // Note size of PT
    std::size_t ptLen = *iterator;
    // Skip past PT size
    std::advance(iterator, sizeof(KwSize));

    // length of PT keyword
    return ptLen;
}

internal::OffsetList Impl::readPT(Binary::const_iterator iterator,
                                  std::size_t ptLength) const
{
    internal::OffsetList offsets{};

    auto end = iterator;
    std::advance(end, ptLength);

    // Look at each entry in the PT keyword. In the entry,
    // we care only about the record offset information.
    while (iterator < end)
    {
#ifdef IPZ_PARSER
        auto iteratorToRecName = iterator;
#endif
        // Skip record name and record type
        std::advance(iterator, lengths::RECORD_NAME + sizeof(RecordType));

        // Get record offset
        auto offset = readUInt16LE(iterator);
        offsets.push_back(offset);

#ifdef IPZ_PARSER
        std::string recordName(iteratorToRecName,
                               iteratorToRecName + lengths::RECORD_NAME);

        try
        {
            // Verify the ECC for this Record
            int rc = recordEccCheck(iterator);

            if (rc != eccStatus::SUCCESS)
            {
                std::string errorMsg =
                    std::string("ERROR: ECC check did not pass for the "
                                "Record:");
                throw(VpdEccException(errorMsg));
            }
        }
        catch (const VpdEccException& ex)
        {
            inventory::PelAdditionalData additionalData{};
            additionalData.emplace("DESCRIPTION",
                                   std::string{ex.what()} + recordName);
            additionalData.emplace("CALLOUT_INVENTORY_PATH", inventoryPath);
            createPEL(additionalData, PelSeverity::WARNING,
                      errIntfForEccCheckFail, nullptr);
        }
        catch (const VpdDataException& ex)
        {
            inventory::PelAdditionalData additionalData{};
            additionalData.emplace("DESCRIPTION",
                                   std::string{ex.what()} + recordName);
            additionalData.emplace("CALLOUT_INVENTORY_PATH", inventoryPath);
            createPEL(additionalData, PelSeverity::WARNING,
                      errIntfForInvalidVPD, nullptr);
        }

#endif

        // Jump record size, record length, ECC offset and ECC length
        std::advance(iterator, sizeof(RecordOffset) + sizeof(RecordLength) +
                                   sizeof(ECCOffset) + sizeof(ECCLength));
    }

    return offsets;
}

void Impl::processRecord(std::size_t recordOffset)
{
    // Jump to record name
    auto nameOffset = recordOffset + sizeof(RecordId) + sizeof(RecordSize) +
                      // Skip past the RT keyword, which contains
                      // the record name.
                      lengths::KW_NAME + sizeof(KwSize);
    // Get record name
    auto iterator = vpd.cbegin();
    std::advance(iterator, nameOffset);

    std::string name(iterator, iterator + lengths::RECORD_NAME);

#ifndef IPZ_PARSER
    if (supportedRecords.end() != supportedRecords.find(name))
    {
#endif
        // If it's a record we're interested in, proceed to find
        // contained keywords and their values.
        std::advance(iterator, lengths::RECORD_NAME);

#ifdef IPZ_PARSER

        // Reverse back to RT Kw, in ipz vpd, to Read RT KW & value
        std::advance(iterator, -(lengths::KW_NAME + sizeof(KwSize) +
                                 lengths::RECORD_NAME));
#endif
        auto kwMap = readKeywords(iterator);
        // Add entry for this record (and contained keyword:value pairs)
        // to the parsed vpd output.
        out.emplace(std::move(name), std::move(kwMap));

#ifndef IPZ_PARSER
    }
#endif
}

std::string Impl::readKwData(const internal::KeywordInfo& keyword,
                             std::size_t dataLength,
                             Binary::const_iterator iterator)
{
    using namespace openpower::vpd;
    switch (std::get<keyword::Encoding>(keyword))
    {
        case keyword::Encoding::ASCII:
        {
            auto stop = std::next(iterator, dataLength);
            return std::string(iterator, stop);
        }

        case keyword::Encoding::RAW:
        {
            auto stop = std::next(iterator, dataLength);
            std::string data(iterator, stop);
            std::string result{};
            std::for_each(data.cbegin(), data.cend(), [&result](size_t c) {
                result += toHex(c >> 4);
                result += toHex(c & 0x0F);
            });
            return result;
        }

        case keyword::Encoding::MB:
        {
            // MB is BuildDate, represent as
            // 1997-01-01-08:30:00
            // <year>-<month>-<day>-<hour>:<min>:<sec>
            auto stop = std::next(iterator, MB_LEN_BYTES);
            std::string data(iterator, stop);
            std::string result;
            result.reserve(MB_LEN_BYTES);
            auto strItr = data.cbegin();
            std::advance(strItr, 1);
            std::for_each(strItr, data.cend(), [&result](size_t c) {
                result += toHex(c >> 4);
                result += toHex(c & 0x0F);
            });

            result.insert(MB_YEAR_END, 1, '-');
            result.insert(MB_MONTH_END, 1, '-');
            result.insert(MB_DAY_END, 1, '-');
            result.insert(MB_HOUR_END, 1, ':');
            result.insert(MB_MIN_END, 1, ':');

            return result;
        }

        case keyword::Encoding::B1:
        {
            // B1 is MAC address, represent as AA:BB:CC:DD:EE:FF
            auto stop = std::next(iterator, MAC_ADDRESS_LEN_BYTES);
            std::string data(iterator, stop);
            std::string result{};
            auto strItr = data.cbegin();
            size_t firstDigit = *strItr;
            result += toHex(firstDigit >> 4);
            result += toHex(firstDigit & 0x0F);
            std::advance(strItr, 1);
            std::for_each(strItr, data.cend(), [&result](size_t c) {
                result += ":";
                result += toHex(c >> 4);
                result += toHex(c & 0x0F);
            });
            return result;
        }

        case keyword::Encoding::UD:
        {
            // UD, the UUID info, represented as
            // 123e4567-e89b-12d3-a456-426655440000
            //<time_low>-<time_mid>-<time hi and version>
            //-<clock_seq_hi_and_res clock_seq_low>-<48 bits node id>
            auto stop = std::next(iterator, UUID_LEN_BYTES);
            std::string data(iterator, stop);
            std::string result{};
            std::for_each(data.cbegin(), data.cend(), [&result](size_t c) {
                result += toHex(c >> 4);
                result += toHex(c & 0x0F);
            });
            result.insert(UUID_TIME_LOW_END, 1, '-');
            result.insert(UUID_TIME_MID_END, 1, '-');
            result.insert(UUID_TIME_HIGH_END, 1, '-');
            result.insert(UUID_CLK_SEQ_END, 1, '-');

            return result;
        }
        default:
            break;
    }

    return {};
}

internal::KeywordMap Impl::readKeywords(Binary::const_iterator iterator)
{
    internal::KeywordMap map{};
    while (true)
    {
        // Note keyword name
        std::string kw(iterator, iterator + lengths::KW_NAME);
        if (LAST_KW == kw)
        {
            // We're done
            break;
        }
        // Check if the Keyword is '#kw'
        char kwNameStart = *iterator;

        // Jump past keyword name
        std::advance(iterator, lengths::KW_NAME);

        std::size_t length;
        std::size_t lengthHighByte;
        if (POUND_KW == kwNameStart)
        {
            // Note keyword data length
            length = *iterator;
            lengthHighByte = *(iterator + 1);
            length |= (lengthHighByte << 8);

            // Jump past 2Byte keyword length
            std::advance(iterator, sizeof(PoundKwSize));
        }
        else
        {
            // Note keyword data length
            length = *iterator;

            // Jump past keyword length
            std::advance(iterator, sizeof(KwSize));
        }

        // Pointing to keyword data now
#ifndef IPZ_PARSER
        if (supportedKeywords.end() != supportedKeywords.find(kw))
        {
            // Keyword is of interest to us
            std::string data = readKwData((supportedKeywords.find(kw))->second,
                                          length, iterator);
            map.emplace(std::move(kw), std::move(data));
        }

#else
        // support all the Keywords
        auto stop = std::next(iterator, length);
        std::string kwdata(iterator, stop);
        map.emplace(std::move(kw), std::move(kwdata));

#endif
        // Jump past keyword data length
        std::advance(iterator, length);
    }

    return map;
}

Store Impl::run()
{
    // Check if the VHDR record is present
    checkHeader();

    auto iterator = vpd.cbegin();

    // Read the table of contents record
    std::size_t ptLen = readTOC(iterator);

    // Read the table of contents record, to get offsets
    // to other records.
    auto offsets = readPT(iterator, ptLen);
    for (const auto& offset : offsets)
    {
        processRecord(offset);
    }
    // Return a Store object, which has interfaces to
    // access parsed VPD by record:keyword
    return Store(std::move(out));
}

void Impl::checkVPDHeader()
{
    // Check if the VHDR record is present and is valid
    checkHeader();
}

std::string Impl::readKwFromHw(const std::string& record,
                               const std::string& keyword)
{
    // Check if the VHDR record is present
    checkHeader();

    auto iterator = vpd.cbegin();

    // Read the table of contents record
    std::size_t ptLen = readTOC(iterator);

    // Read the table of contents record, to get offsets
    // to other records.
    auto offsets = readPT(iterator, ptLen);
    for (const auto& offset : offsets)
    {
        // Jump to record name
        auto nameOffset = offset + sizeof(RecordId) + sizeof(RecordSize) +
                          // Skip past the RT keyword, which contains
                          // the record name.
                          lengths::KW_NAME + sizeof(KwSize);
        // Get record name
        auto iterator = vpd.cbegin();
        std::advance(iterator, nameOffset);

        std::string name(iterator, iterator + lengths::RECORD_NAME);
        if (name != record)
        {
            continue;
        }
        else
        {
            processRecord(offset);
            const auto& itr = out.find(record);
            if (itr != out.end())
            {
                const auto& kwValItr = (itr->second).find(keyword);
                if (kwValItr != (itr->second).end())
                {
                    return kwValItr->second;
                }
                else
                {
                    return "";
                }
            }
        }
    }
    return "";
}

} // namespace parser
} // namespace vpd
} // namespace openpower