#pragma once

#include "parser_interface.hpp"
#include "types.hpp"

#include <string_view>

namespace vpd
{
/**
 * @brief Concrete class to implement JEDEC SPD parsing.
 *
 * The class inherits ParserInterface interface class and overrides the parser
 * functionality to implement parsing logic for JEDEC SPD format.
 */
class JedecSpdParser : public ParserInterface
{
  public:
    // Deleted API's
    JedecSpdParser() = delete;
    JedecSpdParser(const JedecSpdParser&) = delete;
    JedecSpdParser& operator=(const JedecSpdParser&) = delete;
    JedecSpdParser(JedecSpdParser&&) = delete;
    JedecSpdParser& operator=(JedecSpdParser&&) = delete;
    ~JedecSpdParser() = default;

    /**
     * @brief Constructor
     *
     * @param[in] i_spdVector - JEDEC SPD data.
     */
    explicit JedecSpdParser(const types::BinaryVector& i_spdVector) :
        m_memSpd(i_spdVector)
    {}

    /**
     * @brief Parse the memory SPD binary data.
     *
     * Collects and emplace the keyword-value pairs in map.
     *
     * @return map of keyword:value
     */
    types::VPDMapVariant parse();

  private:
    /**
     * @brief An API to read keywords.
     *
     * @param[in] i_iterator - iterator to buffer containing SPD
     * @return- map of kwd:value
     */
    types::JedecSpdMap
        readKeywords(types::BinaryVector::const_iterator& i_iterator);

    /**
     * @brief This function calculates DIMM size from DDR4 SPD
     *
     * @param[in] i_iterator - iterator to buffer containing SPD
     * @return calculated size or 0 in case of any error.
     */
    auto getDDR4DimmCapacity(types::BinaryVector::const_iterator& i_iterator);

    /**
     * @brief This function calculates part number from DDR4 SPD
     *
     * @param[in] i_iterator - iterator to buffer containing SPD
     * @return calculated part number or a default value.
     */
    std::string_view
        getDDR4PartNumber(types::BinaryVector::const_iterator& i_iterator);

    /**
     * @brief This function calculates serial number from DDR4 SPD
     *
     * @param[in] i_iterator - iterator to buffer containing SPD
     * @return calculated serial number or a default value.
     */
    std::string
        getDDR4SerialNumber(types::BinaryVector::const_iterator& i_iterator);

    /**
     * @brief This function allocates FRU number based on part number
     *
     * Mappings for FRU number from calculated part number is used
     * for DDR4 ISDIMM.
     *
     * @param[in] i_partNumber - part number of the DIMM
     * @param[in] i_iterator - iterator to buffer containing SPD
     * @return allocated FRU number or a default value
     */
    std::string_view
        getDDR4FruNumber(const std::string& i_partNumber,
                         types::BinaryVector::const_iterator& i_iterator);

    /**
     * @brief This function allocates CCIN based on part number for DDR4 SPD
     *
     * @param[in] i_partNumber - part number of the DIMM
     * @return allocated CCIN or a default value.
     */
    std::string_view getDDR4CCIN(const std::string& i_partNumber);

    /**
     * @brief This function calculates DIMM size from DDR5 SPD
     *
     * @param[in] i_iterator - iterator to buffer containing SPD
     * @return calculated size or 0 in case of any error.
     */
    auto getDDR5DimmCapacity(types::BinaryVector::const_iterator& i_iterator);

    /**
     * @brief This function calculates part number from DDR5 SPD
     *
     * @param[in] i_iterator - iterator to buffer containing SPD
     * @return calculated part number or a default value.
     */
    auto getDDR5PartNumber(types::BinaryVector::const_iterator& i_iterator);

    /**
     * @brief This function calculates serial number from DDR5 SPD
     *
     * @param[in] i_iterator - iterator to buffer containing SPD
     * @return calculated serial number.
     */
    auto getDDR5SerialNumber(types::BinaryVector::const_iterator& i_iterator);

    /**
     * @brief This function allocates FRU number based on part number
     *
     * Mappings for FRU number from calculated part number is used
     * for DDR5 ISDIMM.
     *
     * @param[in] i_partNumber - part number of the DIMM
     * @return allocated FRU number.
     */
    auto getDDR5FruNumber(const std::string& i_partNumber);

    /**
     * @brief This function allocates CCIN based on part number for DDR5 SPD
     *
     * @param[in] i_partNumber - part number of the DIMM
     * @return allocated CCIN.
     */
    auto getDDR5CCIN(const std::string& i_partNumber);

    // SPD file to be parsed
    const types::BinaryVector& m_memSpd;
};

} // namespace vpd
