#pragma once

#include "const.hpp"
#include "store.hpp"

#include <cstddef>
#include <fstream>

namespace openpower
{
namespace vpd
{
namespace parser
{
namespace keyword
{
/** @brief Encoding scheme of a VPD keyword's data */
enum class Encoding
{
    ASCII, /**< data encoded in ascii */
    RAW,   /**< raw data */
    // Keywords needing custom decoding
    B1, /**< The keyword B1 needs to be decoded specially */
    MB, /**< Special decoding of MB meant for Build Date */
    UD  /**< Special decoding of UD meant for UUID */
};

} // namespace keyword

namespace internal
{

using KeywordInfo = std::tuple<record::Keyword, keyword::Encoding>;
using OffsetList = std::vector<uint32_t>;
using KeywordMap = Parsed::mapped_type;

} // namespace internal

/** @class Impl
 *  @brief Implements parser for VPD
 *
 *  An Impl object must be constructed by passing in VPD in
 *  binary format. To parse the VPD, call the run() method. The run()
 *  method returns an openpower::vpd::Store object, which contains
 *  parsed VPD, and provides access methods for the VPD.
 *
 *  Following is the algorithm used to parse IPZ/OpenPower VPD:
 *  1) Validate that the first record is VHDR, the header record.
 *  2) From the VHDR record, get the offset of the VTOC record,
 *     which is the table of contents record.
 *  3) Process the VTOC record - note offsets of supported records.
 *  4) For each supported record :
 *  4.1) Jump to record via offset. Add record name to parser output.
 *  4.2) Process record - for each contained and supported keyword:
 *  4.2.1) Note keyword name and value, associate this information to
 *         to the record noted in step 4.1).
 */
class Impl
{
  public:
    Impl() = delete;
    Impl(const Impl&) = delete;
    Impl& operator=(const Impl&) = delete;
    Impl(Impl&&) = delete;
    Impl& operator=(Impl&&) = delete;
    ~Impl() = default;

    /** @brief Construct an Impl
     *
     *  @param[in] vpdBuffer - Binary VPD
     *  @param[in] path - To call out FRU in case of any PEL.
     *  @param[in] vpdFilePath - VPD File Path
     *  @param[in] vpdStartOffset - Start offset of VPD.
     */
    Impl(const Binary& vpdBuffer, const std::string& path,
         const std::string& vpdFilePath, uint32_t vpdStartOffset) :
        vpd(vpdBuffer),
        inventoryPath(path), vpdFilePath(vpdFilePath),
        vpdStartOffset(vpdStartOffset), out{}
    {
#ifndef ManagerTest
        vpdFileStream.exceptions(std::ifstream::badbit |
                                 std::ifstream::failbit);
#endif
        try
        {
            vpdFileStream.open(vpdFilePath,
                               std::ios::in | std::ios::out | std::ios::binary);
        }
        catch (const std::fstream::failure& fail)
        {
            std::cerr << "Exception in file handling [" << vpdFilePath
                      << "] error : " << fail.what();
            throw;
        }
    }

    /** @brief Run the parser on binary VPD
     *
     *  @returns openpower::vpd::Store object
     */
    Store run();

    /** @brief check if VPD header is valid
     */
    void checkVPDHeader();

    /** @brief Read a specific VPD keyword from hardware.
     * This api is to read a specific VPD keyword directly from hardware.
     * @param[in] record - record name.
     * @param[in] keyword - keyword name.
     * @return keyword value.
     */
    std::string readKwFromHw(const std::string& record,
                             const std::string& keyword);

  private:
    /** @brief Process the table of contents record
     *
     *  @param[in] iterator - iterator to buffer containing VPD
     *  @returns Size of the PT keyword in VTOC
     */
    std::size_t readTOC(Binary::const_iterator& iterator);

    /** @brief Read the PT keyword contained in the VHDR record,
     *         to obtain offsets to other records in the VPD.
     *
     *  @param[in] iterator - iterator to buffer containing VPD
     *  @param[in] ptLength - Length of PT keyword data
     *
     *  @returns List of offsets to records in VPD
     */
    internal::OffsetList readPT(Binary::const_iterator iterator,
                                std::size_t ptLen);

    /** @brief Read VPD information contained within a record
     *
     *  @param[in] recordOffset - offset to a record location
     *      within the binary VPD
     */
    void processRecord(std::size_t recordOffset);

    /** @brief Read keyword data
     *
     *  @param[in] keyword - VPD keyword
     *  @param[in] dataLength - Length of data to be read
     *  @param[in] iterator - iterator pointing to a Keyword's data in
     *      the VPD
     *
     *  @returns keyword data as a string
     */
    std::string readKwData(const internal::KeywordInfo& keyword,
                           std::size_t dataLength,
                           Binary::const_iterator iterator);

    /** @brief While we're pointing at the keyword section of
     *     a record in the VPD, this will read all contained
     *     keywords and their values.
     *
     *  @param[in] iterator - iterator pointing to a Keyword in the VPD
     *
     *  @returns map of keyword:data
     */
    internal::KeywordMap readKeywords(Binary::const_iterator iterator);

    /** @brief Checks if the VHDR record is present in the VPD */
    void checkHeader();

    /** @brief Checks the ECC for VHDR Record.
     *  @returns Success(0) OR corrupted data(-1)
     */
    int vhdrEccCheck();

    /** @brief Checks the ECC for VTOC Record.
     *  @returns Success(0) OR corrupted data(-1)
     */
    int vtocEccCheck();

    /** @brief Checks the ECC for the given record.
     *
     * @param[in] iterator - iterator pointing to a record in the VPD
     * @returns Success(0) OR corrupted data(-1)
     */
    int recordEccCheck(Binary::const_iterator iterator);

    /** @brief This interface collects Offset of VTOC
     *  @returns VTOC Offset
     */
    openpower::vpd::constants::RecordOffset getVtocOffset() const;

    /** @brief VPD in binary format */
    const Binary& vpd;

    /** Inventory path to call out FRU if required */
    const std::string inventoryPath;

    /** Eeprom hardware path */
    inventory::Path vpdFilePath;

    /** VPD Offset **/
    uint32_t vpdStartOffset;

    /** File stream for VPD */
    std::fstream vpdFileStream;

    /** @brief parser output */
    Parsed out;
};

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