#include "impl.hpp"

#include "vpdecc/vpdecc.h"

#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>

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()
{
    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_CORRECTABLE_DATA)
    {
        try
        {
            if (vpdFileStream.is_open())
            {
                vpdFileStream.seekp(vpdStartOffset + offsets::VHDR_RECORD,
                                    std::ios::beg);
                vpdFileStream.write(
                    reinterpret_cast<const char*>(&vpd[offsets::VHDR_RECORD]),
                    lengths::VHDR_RECORD_LENGTH);
            }
            else
            {
                std::cerr << "File not open";
                rc = eccStatus::FAILED;
            }
        }
        catch (const std::fstream::failure& e)
        {
            std::cout << "Error while operating on file with exception:"
                      << e.what();
            rc = eccStatus::FAILED;
        }
    }
    else if (l_status != VPD_ECC_OK)
    {
        rc = eccStatus::FAILED;
    }

    return rc;
}

int Impl::vtocEccCheck()
{
    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_CORRECTABLE_DATA)
    {
        try
        {
            if (vpdFileStream.is_open())
            {
                vpdFileStream.seekp(vpdStartOffset + vtocOffset, std::ios::beg);
                vpdFileStream.write(
                    reinterpret_cast<const char*>(&vpdPtr[vtocOffset]),
                    vtocLength);
            }
            else
            {
                std::cerr << "File not open";
                rc = eccStatus::FAILED;
            }
        }
        catch (const std::fstream::failure& e)
        {
            std::cout << "Error while operating on file with exception "
                      << e.what();
            rc = eccStatus::FAILED;
        }
    }
    else if (l_status != VPD_ECC_OK)
    {
        rc = eccStatus::FAILED;
    }

    return rc;
}

int Impl::recordEccCheck(Binary::const_iterator iterator)
{
    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_CORRECTABLE_DATA)
    {
        try
        {
            if (vpdFileStream.is_open())
            {
                vpdFileStream.seekp(vpdStartOffset + recordOffset,
                                    std::ios::beg);
                vpdFileStream.write(
                    reinterpret_cast<const char*>(&vpdPtr[recordOffset]),
                    recordLength);
            }
            else
            {
                std::cerr << "File not open";
                rc = eccStatus::FAILED;
            }
        }
        catch (const std::fstream::failure& e)
        {
            std::cout << "Error while operating on file with exception "
                      << e.what();
            rc = eccStatus::FAILED;
        }
    }
    else if (l_status != VPD_ECC_OK)
    {
        rc = eccStatus::FAILED;
    }

    return rc;
}
#endif

void Impl::checkHeader()
{
    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)
{
    // 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)
{
    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
