#pragma once

#include "additional_data.hpp"
#include "ascii_string.hpp"
#include "callouts.hpp"
#include "data_interface.hpp"
#include "pel_types.hpp"
#include "registry.hpp"
#include "section.hpp"
#include "stream.hpp"

namespace openpower
{
namespace pels
{

constexpr uint8_t srcSectionVersion = 0x01;
constexpr uint8_t srcSectionSubtype = 0x01;
constexpr size_t numSRCHexDataWords = 8;
constexpr uint8_t srcVersion = 0x02;
constexpr uint8_t bmcSRCFormat = 0x55;
constexpr uint8_t primaryBMCPosition = 0x10;
constexpr size_t baseSRCSize = 72;

enum class DetailLevel
{
    message = 0x01,
    json = 0x02
};
/**
 * @class SRC
 *
 * SRC stands for System Reference Code.
 *
 * This class represents the SRC sections in the PEL, of which there are 2:
 * primary SRC and secondary SRC.  These are the same structurally, the
 * difference is that the primary SRC must be the 3rd section in the PEL if
 * present and there is only one of them, and the secondary SRC sections are
 * optional and there can be more than one (by definition, for there to be a
 * secondary SRC, a primary SRC must also exist).
 *
 * This section consists of:
 * - An 8B header (Has the version, flags, hexdata word count, and size fields)
 * - 8 4B words of hex data
 * - An ASCII character string
 * - An optional subsection for Callouts
 */
class SRC : public Section
{
  public:
    enum HeaderFlags
    {
        additionalSections = 0x01,
        powerFaultEvent = 0x02,
        hypDumpInit = 0x04,
        postOPPanel = 0x08,
        i5OSServiceEventBit = 0x10,
        virtualProgressSRC = 0x80
    };

    /**
     * @brief Enums for the error status bits in hex word 5
     *        of BMC SRCs.
     */
    enum class ErrorStatusFlags
    {
        terminateFwErr = 0x20000000,
        deconfigured = 0x02000000,
        guarded = 0x01000000
    };

    SRC() = delete;
    ~SRC() = default;
    SRC(const SRC&) = delete;
    SRC& operator=(const SRC&) = delete;
    SRC(SRC&&) = delete;
    SRC& operator=(SRC&&) = delete;

    /**
     * @brief Constructor
     *
     * Fills in this class's data fields from the stream.
     *
     * @param[in] pel - the PEL data stream
     */
    explicit SRC(Stream& pel);

    /**
     * @brief Constructor
     *
     * Creates the section with data from the PEL message registry entry for
     * this error, along with the AdditionalData property contents from the
     * corresponding event log.
     *
     * @param[in] regEntry - The message registry entry for this event log
     * @param[in] additionalData - The AdditionalData properties in this event
     *                             log
     * @param[in] dataIface - The DataInterface object
     */
    SRC(const message::Entry& regEntry, const AdditionalData& additionalData,
        const DataInterfaceBase& dataIface) :
        SRC(regEntry, additionalData, nlohmann::json{}, dataIface)
    {}

    /**
     * @brief Constructor
     *
     * Creates the section with data from the PEL message registry entry for
     * this error, along with the AdditionalData property contents from the
     * corresponding event log, and a JSON array of callouts to add.
     *
     * @param[in] regEntry - The message registry entry for this event log
     * @param[in] additionalData - The AdditionalData properties in this event
     *                             log
     * @param[in] jsonCallouts - The array of JSON callouts, or an empty object.
     * @param[in] dataIface - The DataInterface object
     */
    SRC(const message::Entry& regEntry, const AdditionalData& additionalData,
        const nlohmann::json& jsonCallouts, const DataInterfaceBase& dataIface);

    /**
     * @brief Flatten the section into the stream
     *
     * @param[in] stream - The stream to write to
     */
    void flatten(Stream& stream) const override;

    /**
     * @brief Returns the SRC version, which is a different field
     *        than the version byte in the section header.
     *
     * @return uint8_t
     */
    uint8_t version() const
    {
        return _version;
    }

    /**
     * @brief Returns the flags byte
     *
     * @return uint8_t
     */
    uint8_t flags() const
    {
        return _flags;
    }

    /**
     * @brief Returns the hex data word count.
     *
     * Even though there always 8 words, this returns 9 due to previous
     * SRC version formats.
     *
     * @return uint8_t
     */
    uint8_t hexWordCount() const
    {
        return _wordCount;
    }

    /**
     * @brief Returns the size of the SRC section, not including the header.
     *
     * @return uint16_t
     */
    uint16_t size() const
    {
        return _size;
    }

    /**
     * @brief Returns the 8 hex data words.
     *
     * @return const std::array<uint32_t, numSRCHexDataWords>&
     */
    const std::array<uint32_t, numSRCHexDataWords>& hexwordData() const
    {
        return _hexData;
    }

    /**
     * @brief Returns the ASCII string
     *
     * @return std::string
     */
    std::string asciiString() const
    {
        return _asciiString->get();
    }

    /**
     * @brief Returns the callouts subsection
     *
     * If no callouts, this unique_ptr will be empty
     *
     * @return  const std::unique_ptr<src::Callouts>&
     */
    const std::unique_ptr<src::Callouts>& callouts() const
    {
        return _callouts;
    }

    /**
     * @brief Returns the size of this section when flattened into a PEL
     *
     * @return size_t - the size of the section
     */
    size_t flattenedSize() const
    {
        return _header.size;
    }

    /**
     * @brief Says if this SRC has additional subsections in it
     *
     * Note: The callouts section is the only possible subsection.
     *
     * @return bool
     */
    inline bool hasAdditionalSections() const
    {
        return _flags & additionalSections;
    }

    /**
     * @brief Indicates if this event log is for a power fault.
     *
     * This comes from a field in the message registry for BMC
     * generated PELs.
     *
     * @return bool
     */
    inline bool isPowerFaultEvent() const
    {
        return _flags & powerFaultEvent;
    }

    /**
     * @brief Get the _hexData[] index to use based on the corresponding
     *        SRC word number.
     *
     * Converts the specification nomenclature to this data structure.
     * See the _hexData documentation below for more information.
     *
     * @param[in] wordNum - The SRC word number, as defined by the spec.
     *
     * @return size_t The corresponding index into _hexData.
     */
    inline size_t getWordIndexFromWordNum(size_t wordNum) const
    {
        assert(wordNum >= 2 && wordNum <= 9);
        return wordNum - 2;
    }

    /**
     * @brief Get section in JSON.
     * @param[in] registry - Registry object reference
     * @param[in] plugins - Vector of strings of plugins found in filesystem
     * @param[in] creatorID - Creator Subsystem ID from Private Header
     * @return std::optional<std::string> - SRC section's JSON
     */
    std::optional<std::string> getJSON(message::Registry& registry,
                                       const std::vector<std::string>& plugins,
                                       uint8_t creatorID) const override;

    /**
     * @brief Get error details based on refcode and hexwords
     * @param[in] registry - Registry object
     * @param[in] type - detail level enum value : single message or full json
     * @param[in] toCache - boolean to cache registry in memory, default=false
     * @return std::optional<std::string> - Error details
     */
    std::optional<std::string> getErrorDetails(message::Registry& registry,
                                               DetailLevel type,
                                               bool toCache = false) const;

    /**
     * @brief Says if this SRC was created by the BMC (i.e. this code).
     *
     * @return bool - If created by the BMC or not
     */
    bool isBMCSRC() const;

    /**
     * @brief Set the terminate bit in hex data word 3.
     */
    void setTerminateBit()
    {
        setErrorStatusFlag(ErrorStatusFlags::terminateFwErr);
    }

    /**
     * @brief Get the SRC structure to pass on to the boot progress dbus
     * interface.
     *
     * @return std::vector<uint8_t> - SRC struct data
     */
    std::vector<uint8_t> getSrcStruct();

    /**
     * @brief Extracts the first 8 characters of the ASCII String field
     *        from the raw progress SRC and converts it to a uint32_t.
     *
     * @param[in] rawProgressSRC - The progress SRC bytes
     *
     * @return uint32_t - The code, like 0xCC0099EE from "CC0099EE"
     */
    static uint32_t getProgressCode(std::vector<uint8_t>& rawProgressSRC);

    /**
     * @brief Return the value of the passed in error status flag.
     *
     * @param[in] flag - The flag
     *
     * @return bool - If the flag is set.
     */
    bool getErrorStatusFlag(ErrorStatusFlags flag) const
    {
        return _hexData[3] & static_cast<uint32_t>(flag);
    }

  private:
    /**
     * @brief Fills in the user defined hex words from the
     *        AdditionalData fields.
     *
     * When creating this section from a message registry entry,
     * that entry has a field that says which AdditionalData property
     * fields to use to fill in the user defined hex data words 6-9
     * (which correspond to hexData words 4-7).
     *
     * For example, given that AdditionalData is a map of string keys
     * to string values, find the AdditionalData value for AdditionalData
     * key X, convert it to a uint32_t, and save it in user data word Y.
     *
     * @param[in] regEntry - The message registry entry for the error
     * @param[in] additionalData - The AdditionalData map
     */
    void setUserDefinedHexWords(const message::Entry& regEntry,
                                const AdditionalData& additionalData);
    /**
     * @brief Fills in the object from the stream data
     *
     * @param[in] stream - The stream to read from
     */
    void unflatten(Stream& stream);

    /**
     * @brief Says if the word number is in the range of user defined words.
     *
     * This is only used for BMC generated SRCs, where words 6 - 9 are the
     * user defined ones, meaning that setUserDefinedHexWords() will be
     * used to fill them in based on the contents of the OpenBMC event log.
     *
     * @param[in] wordNum - The SRC word number, as defined by the spec.
     *
     * @return bool - If this word number can be filled in by the creator.
     */
    inline bool isUserDefinedWord(size_t wordNum) const
    {
        return (wordNum >= 6) && (wordNum <= 9);
    }

    /**
     * @brief Sets the SRC format byte in the hex word data.
     */
    inline void setBMCFormat()
    {
        _hexData[0] |= bmcSRCFormat;
    }

    /**
     * @brief Sets the hex word field that specifies which BMC
     *        (primary vs backup) created the error.
     *
     * Can be hardcoded until there are systems with redundant BMCs.
     */
    inline void setBMCPosition()
    {
        _hexData[1] |= primaryBMCPosition;
    }

    /**
     * @brief Sets the motherboard CCIN hex word field
     *
     * @param[in] dataIface - The DataInterface object
     */
    void setMotherboardCCIN(const DataInterfaceBase& dataIface);

    /**
     * @brief Sets the progress code hex word field
     *
     * @param[in] dataIface - The DataInterface object
     */
    void setProgressCode(const DataInterfaceBase& dataIface);

    /**
     * @brief Sets an error status bit in the SRC.
     *
     * @param[in] flag - The flag to set
     */
    void setErrorStatusFlag(ErrorStatusFlags flag)
    {
        _hexData[3] |= static_cast<uint32_t>(flag);
    }

    /**
     * @brief Validates the section contents
     *
     * Updates _valid (in Section) with the results.
     */
    void validate() override;

    /**
     * @brief Get error description from message registry
     * @param[in] regEntry - The message registry entry for the error
     * @return std::optional<std::string> - Error message
     */
    std::optional<std::string>
        getErrorMessage(const message::Entry& regEntry) const;

    /**
     * @brief Get Callout info in JSON
     * @return std::optional<std::string> - Callout details
     */
    std::optional<std::string> getCallouts() const;

    /**
     * @brief Checks the AdditionalData property and the message registry
     *        JSON and adds any necessary callouts.
     *
     * The callout sources are the AdditionalData event log property
     * and the message registry JSON.
     *
     * @param[in] regEntry - The message registry entry for the error
     * @param[in] additionalData - The AdditionalData values
     * @param[in] jsonCallouts - The array of JSON callouts, or an empty object
     * @param[in] dataIface - The DataInterface object
     */
    void addCallouts(const message::Entry& regEntry,
                     const AdditionalData& additionalData,
                     const nlohmann::json& jsonCallouts,
                     const DataInterfaceBase& dataIface);

    /**
     * @brief Adds a FRU callout based on an inventory path
     *
     * @param[in] inventoryPath - The inventory item to call out
     * @param[in] priority - An optional priority (uses high if nullopt)
     * @param[in] locationCode - The expanded location code (or look it up)
     * @param[in] dataIface - The DataInterface object
     * @param[in] mrus - The MRUs to add to the callout
     */
    void
        addInventoryCallout(const std::string& inventoryPath,
                            const std::optional<CalloutPriority>& priority,
                            const std::optional<std::string>& locationCode,
                            const DataInterfaceBase& dataIface,
                            const std::vector<src::MRU::MRUCallout>& mrus = {});

    /**
     * @brief Returns the callouts to use from the registry entry.
     *
     * @param[in] regEntry - The message registry entry for the error
     * @param[in] additionalData - The AdditionalData property
     * @param[in] dataIface - The DataInterface object
     */
    std::vector<message::RegistryCallout>
        getRegistryCallouts(const message::Entry& regEntry,
                            const AdditionalData& additionalData,
                            const DataInterfaceBase& dataIface);

    /**
     * @brief Adds the FRU callouts from the list of registry callouts
     *        passed in to the SRC.
     *
     * The last parameter is used only in a special case when the first
     * callout is a symbolic FRU with a trusted location code.  See the
     * addRegistryCallout documentation.
     *
     * @param[in] callouts - The message registry callouts to add
     * @param[in] dataIface - The DataInterface object
     * @param[in] trustedSymbolicFRUInvPath - The optional inventory path used
     *                                        in the symbolic FRU case.
     */
    void addRegistryCallouts(
        const std::vector<message::RegistryCallout>& callouts,
        const DataInterfaceBase& dataIface,
        std::optional<std::string> trustedSymbolicFRUInvPath);

    /**
     * @brief Adds a single FRU callout from the message registry.
     *
     * If the last parameter is filled in, and the registry callout is a
     * symbolic FRU callout with a trusted location code, and it has the
     * 'useInventoryLocCode' member set to true, then the location code of
     * that inventory item will be what is used for that trusted location code.
     *
     * @param[in] callout - The registry callout structure
     * @param[in] dataIface - The DataInterface object
     * @param[in] trustedSymbolicFRUInvPath - The optional inventory path used
     *                                        in the symbolic FRU case.
     */
    void addRegistryCallout(
        const message::RegistryCallout& callout,
        const DataInterfaceBase& dataIface,
        const std::optional<std::string>& trustedSymbolicFRUInvPath);

    /**
     * @brief Creates the Callouts object _callouts
     *        so that callouts can be added to it.
     */
    void createCalloutsObject()
    {
        if (!_callouts)
        {
            _callouts = std::make_unique<src::Callouts>();
            _flags |= additionalSections;
        }
    }

    /**
     * @brief Adds any FRU callouts based on a device path in the
     *        AdditionalData parameter.
     *
     * @param[in] additionalData - The AdditionalData values
     * @param[in] dataIface - The DataInterface object
     */
    void addDevicePathCallouts(const AdditionalData& additionalData,
                               const DataInterfaceBase& dataIface);

    /**
     * @brief Adds any FRU callouts specified in the incoming JSON.
     *
     * @param[in] jsonCallouts - The JSON array of callouts
     * @param[in] dataIface - The DataInterface object
     */
    void addJSONCallouts(const nlohmann::json& jsonCallouts,
                         const DataInterfaceBase& dataIface);

    /**
     * @brief Adds a single callout based on the JSON
     *
     * @param[in] jsonCallouts - A single callout entry
     * @param[in] dataIface - The DataInterface object
     */
    void addJSONCallout(const nlohmann::json& jsonCallout,
                        const DataInterfaceBase& dataIface);

    /**
     * @brief Extracts a CalloutPriority value from the json
     *        using the 'Priority' key.
     *
     * @param[in] json - A JSON object that contains the priority key
     *
     * @return CalloutPriority - The priority value
     */
    CalloutPriority getPriorityFromJSON(const nlohmann::json& json);

    /**
     * @brief Exracts MRU values and their priorities from the
     *        input JSON array.
     *
     * @param[in] mruJSON - The JSON array
     */
    std::vector<src::MRU::MRUCallout>
        getMRUsFromJSON(const nlohmann::json& mruJSON);

    /**
     * @brief Sets the dump status
     *
     * @param[in] dataIface - The DataInterface object
     */
    void setDumpStatus(const DataInterfaceBase& dataIface);

    /**
     * @brief The SRC version field
     */
    uint8_t _version;

    /**
     * @brief The SRC flags field
     */
    uint8_t _flags;

    /**
     * @brief A byte of reserved data after the flags field
     */
    uint8_t _reserved1B;

    /**
     * @brief The hex data word count.
     *
     * To be compatible with previous versions of SRCs, this is
     * number of hex words (8) + 1 = 9.
     */
    uint8_t _wordCount;

    /**
     * @brief Two bytes of reserved data after the hex word count
     */
    uint16_t _reserved2B;

    /**
     * @brief The total size of the SRC section, not including the section
     *        header.
     */
    uint16_t _size;

    /**
     * @brief The SRC 'hex words'.
     *
     * In the spec these are referred to as SRC words 2 - 9 as words 0 and 1
     * are filled by the 8 bytes of fields from above.
     */
    std::array<uint32_t, numSRCHexDataWords> _hexData;

    /**
     * @brief The 32 byte ASCII character string of the SRC
     *
     * It is padded with spaces to fill the 32 bytes.
     * An example is:
     * "BD8D1234                        "
     *
     * That first word is what is commonly referred to as the refcode, and
     * sometimes also called an SRC.
     */
    std::unique_ptr<src::AsciiString> _asciiString;

    /**
     * @brief The callouts subsection.
     *
     * Optional and only created if there are callouts.
     */
    std::unique_ptr<src::Callouts> _callouts;
};

} // namespace pels
} // namespace openpower
