#pragma once

#include "additional_data.hpp"
#include "data_interface.hpp"
#include "journal.hpp"
#include "private_header.hpp"
#include "registry.hpp"
#include "src.hpp"
#include "user_data.hpp"
#include "user_data_formats.hpp"
#include "user_header.hpp"

#include <memory>
#include <vector>

namespace openpower
{
namespace pels
{

/**
 * @brief Contains information about an FFDC file.
 */
struct PelFFDCfile
{
    UserDataFormat format;
    uint8_t subType;
    uint8_t version;
    int fd;
};

using PelFFDC = std::vector<PelFFDCfile>;

constexpr uint8_t jsonCalloutSubtype = 0xCA;

/** @class PEL
 *
 * @brief This class represents a specific event log format referred to as a
 * Platform Event Log.
 *
 * Every field in a PEL are in structures call sections, of which there are
 * several types.  Some sections are required, and some are optional.  In some
 * cases there may be more than one instance of a section type.
 *
 * The only two required sections for every type of PEL are the Private Header
 * section and User Header section, which must be in the first and second
 * positions, respectively.
 *
 * Every section starts with an 8 byte section header, which has the section
 * size and type, among other things.
 *
 * This class represents all sections with objects.
 *
 * The class can be constructed:
 * - From a full formed flattened PEL.
 * - From scratch based on an OpenBMC event and its corresponding PEL message
 *   registry entry.
 *
 * The data() method allows one to retrieve the PEL as a vector<uint8_t>.  This
 * is the format in which it is stored and transmitted.
 */
class PEL
{
  public:
    PEL() = delete;
    ~PEL() = default;
    PEL(const PEL&) = delete;
    PEL& operator=(const PEL&) = delete;
    PEL(PEL&&) = delete;
    PEL& operator=(PEL&&) = delete;

    /**
     * @brief Constructor
     *
     * Build a PEL from raw data.
     *
     * Note: Neither this nor the following constructor can take a const vector&
     * because the Stream class that is used to read from the vector cannot take
     * a const.  The alternative is to make a copy of the data, but as PELs can
     * be up to 16KB that is undesireable.
     *
     * @param[in] data - The PEL data
     */
    explicit PEL(std::vector<uint8_t>& data);

    /**
     * @brief Constructor
     *
     * Build a PEL from the raw data.
     *
     * @param[in] data - the PEL data
     * @param[in] obmcLogID - the corresponding OpenBMC event log ID
     */
    PEL(std::vector<uint8_t>& data, uint32_t obmcLogID);

    /**
     * @brief Constructor
     *
     * Creates a PEL from an OpenBMC event log and its message
     * registry entry.
     *
     * @param[in] entry - The message registry entry for this error
     * @param[in] obmcLogID - ID of corresponding OpenBMC event log
     * @param[in] timestamp - Timestamp from the event log
     * @param[in] severity - Severity from the event log
     * @param[in] additionalData - The AdditionalData contents
     * @param[in] ffdcFiles - FFCD files that go into UserData sections
     * @param[in] dataIface - The data interface object
     * @param[in] journal - The journal object
     */
    PEL(const openpower::pels::message::Entry& entry, uint32_t obmcLogID,
        uint64_t timestamp, phosphor::logging::Entry::Level severity,
        const AdditionalData& additionalData, const PelFFDC& ffdcFiles,
        const DataInterfaceBase& dataIface, const JournalBase& journal);

    /**
     * @brief Convenience function to return the log ID field from the
     *        Private Header section.
     *
     * @return uint32_t - the ID
     */
    uint32_t id() const
    {
        return _ph->id();
    }

    /**
     * @brief Convenience function to return the PLID field from the
     *        Private Header section.
     *
     * @return uint32_t - the PLID
     */
    uint32_t plid() const
    {
        return _ph->plid();
    }

    /**
     * @brief Convenience function to return the OpenBMC event log ID field
     * from the Private Header section.
     *
     * @return uint32_t - the OpenBMC event log ID
     */
    uint32_t obmcLogID() const
    {
        return _ph->obmcLogID();
    }

    /**
     * @brief Convenience function to return the commit time field from
     *        the Private Header section.
     *
     * @return BCDTime - the timestamp
     */
    BCDTime commitTime() const
    {
        return _ph->commitTimestamp();
    }

    /**
     * @brief Convenience function to return the create time field from
     *        the Private Header section.
     *
     * @return BCDTime - the timestamp
     */
    BCDTime createTime() const
    {
        return _ph->createTimestamp();
    }

    /**
     * @brief Gives access to the Private Header section class
     *
     * @return const PrivateHeader& - the private header
     */
    const PrivateHeader& privateHeader() const
    {
        return *_ph;
    }

    /**
     * @brief Gives access to the User Header section class
     *
     * @return const UserHeader& - the user header
     */
    const UserHeader& userHeader() const
    {
        return *_uh;
    }

    /**
     * @brief Gives access to the primary SRC's section class
     *
     * This is technically an optional section, so the return
     * value is an std::optional<SRC*>.
     *
     * @return std::optional<SRC*> - the SRC section object
     */
    std::optional<SRC*> primarySRC() const;

    /**
     * @brief Returns the optional sections, which is everything but
     *        the Private and User Headers.
     *
     * @return const std::vector<std::unique_ptr<Section>>&
     */
    const std::vector<std::unique_ptr<Section>>& optionalSections() const
    {
        return _optionalSections;
    }

    /**
     * @brief Returns the PEL data.
     *
     * @return std::vector<uint8_t> - the raw PEL data
     */
    std::vector<uint8_t> data() const;

    /**
     * @brief Returns the size of the PEL
     *
     * @return size_t The PEL size in bytes
     */
    size_t size() const;

    /**
     * @brief Says if the PEL is valid (the sections are all valid)
     *
     * @return bool - if the PEL is valid
     */
    bool valid() const;

    /**
     * @brief Sets the commit timestamp to the current time
     */
    void setCommitTime();

    /**
     * @brief Sets the error log ID field to a unique ID.
     */
    void assignID();

    /**
     * @brief Output a PEL in JSON.
     * @param[in] registry - Registry object reference
     * @param[in] plugins - Vector of strings of plugins found in filesystem
     */
    void toJSON(message::Registry& registry,
                const std::vector<std::string>& plugins) const;

    /**
     * @brief Sets the host transmission state in the User Header
     *
     * @param[in] state - The state value
     */
    void setHostTransmissionState(TransmissionState state)
    {
        _uh->setHostTransmissionState(static_cast<uint8_t>(state));
    }

    /**
     * @brief Returns the host transmission state
     *
     * @return HostTransmissionState - The state
     */
    TransmissionState hostTransmissionState() const
    {
        return static_cast<TransmissionState>(_uh->hostTransmissionState());
    }

    /**
     * @brief Sets the HMC transmission state in the User Header
     *
     * @param[in] state - The state value
     */
    void setHMCTransmissionState(TransmissionState state)
    {
        _uh->setHMCTransmissionState(static_cast<uint8_t>(state));
    }

    /**
     * @brief Returns the HMC transmission state
     *
     * @return HMCTransmissionState - The state
     */
    TransmissionState hmcTransmissionState() const
    {
        return static_cast<TransmissionState>(_uh->hmcTransmissionState());
    }

    /**
     * @brief Returns true if a hardware callout is present in the primary SRC
     *
     * @return true if hardware callout present, false otherwise
     */
    bool isHwCalloutPresent() const;

    /**
     * @brief Updates the system info data into HB extended user
     *        data section to this PEL object
     *
     * @param[in] dataIface - The data interface object
     */
    void updateSysInfoInExtendedUserDataSection(
        const DataInterfaceBase& dataIface);

    /**
     * @brief Return the deconfig flag from hex data word 5 of BMC and
     *        hostboot PELs.
     *
     * This only applies to BMC and hostboot PELs because only those
     * SRC formats have this flag defined.
     *
     * @return bool - If the 'one or more resources are deconfigured'
     *                flag is set.
     */
    bool getDeconfigFlag() const;

    /**
     * @brief Return the guard flag from hex data word 5 of BMC and
     *        hostboot PELs.
     *
     * This only applies to BMC and hostboot PELs because only those
     * SRC formats have this flag defined.
     *
     * @return bool - If the 'one or more resources are guarded'
     *                flag is set.
     */
    bool getGuardFlag() const;

  private:
    /**
     * @brief Builds the section objects from a PEL data buffer
     *
     * Note: The data parameter cannot be const for the same reasons
     * as listed in the constructor.
     *
     * @param[in] data - The PEL data
     * @param[in] obmcLogID - The OpenBMC event log ID to use for that
     *                        field in the Private Header.
     */
    void populateFromRawData(std::vector<uint8_t>& data, uint32_t obmcLogID);

    /**
     * @brief Flattens the PEL objects into the buffer
     *
     * @param[out] pelBuffer - What the data will be written to
     */
    void flatten(std::vector<uint8_t>& pelBuffer) const;

    /**
     * @brief Check that the PEL fields that need to be in agreement
     *        with each other are, and fix them up if necessary.
     */
    void checkRulesAndFix();

    /**
     * @brief Returns a map of the section IDs that appear more than once
     *        in the PEL.  The data value for each entry will be set to 0.
     *
     * @return std::map<uint16_t, size_t>
     */
    std::map<uint16_t, size_t> getPluralSections() const;

    /**
     * @brief Adds the UserData section to this PEL object,
     *        shrinking it if necessary
     *
     * @param[in] userData - The section to add
     *
     * @return bool - If the section was added or not.
     */
    bool addUserDataSection(std::unique_ptr<UserData> userData);

    /**
     * @brief helper function for printing PELs.
     * @param[in] Section& - section object reference
     * @param[in] std::string - PEL string
     * @param[in|out] pluralSections - Map used to track sections counts for
     *                                 when there is more than 1.
     * @param[in] registry - Registry object reference
     * @param[in] plugins - Vector of strings of plugins found in filesystem
     * @param[in] creatorID - Creator Subsystem ID (only for UserData section)
     */
    void printSectionInJSON(const Section& section, std::string& buf,
                            std::map<uint16_t, size_t>& pluralSections,
                            message::Registry& registry,
                            const std::vector<std::string>& plugins,
                            uint8_t creatorID = 0) const;

    /**
     * @brief Returns any callout JSON found in the FFDC files.
     *
     * Looks for an FFDC file that is JSON format and has the
     * sub-type value set to 0xCA and returns its data as a JSON object.
     *
     * @param[in] ffdcFiles - FFCD files that go into UserData sections
     *
     * @return json - The callout JSON, or an empty object if not found
     */
    nlohmann::json getCalloutJSON(const PelFFDC& ffdcFiles);

    /**
     * @brief Update terminate bit in primary SRC section to this PEL object is
     * severity set to 0x51 = critical error, system termination
     */
    void updateTerminateBitInSRCSection();

    /**
     * @brief Adds journal data to the PEL as UserData sections
     *        if specified to in the message registry.
     *
     * @param regEntry - The registry entry
     * @param journal - The journal object
     */
    void addJournalSections(const message::Entry& regEntry,
                            const JournalBase& journal);

    /**
     * @brief The PEL Private Header section
     */
    std::unique_ptr<PrivateHeader> _ph;

    /**
     * @brief The PEL User Header section
     */
    std::unique_ptr<UserHeader> _uh;

    /**
     * @brief Holds all sections by the PH and UH.
     */
    std::vector<std::unique_ptr<Section>> _optionalSections;

    /**
     * @brief The maximum size a PEL can be in bytes.
     */
    static constexpr size_t _maxPELSize = 16384;
};

namespace util
{

/**
 * @brief Creates a UserData section object that contains JSON.
 *
 * @param[in] json - The JSON contents
 *
 * @return std::unique_ptr<UserData> - The UserData object
 */
std::unique_ptr<UserData> makeJSONUserDataSection(const nlohmann::json& json);

/**
 * @brief Create a UserData section containing the AdditionalData
 *        contents as a JSON string.
 *
 * @param[in] ad - The AdditionalData contents
 *
 * @return std::unique_ptr<UserData> - The section
 */
std::unique_ptr<UserData> makeADUserDataSection(const AdditionalData& ad);

/**
 * @brief Create a UserData section containing various useful pieces
 *        of system information as a JSON string.
 *
 * @param[in] ad - The AdditionalData contents
 * @param[in] dataIface - The data interface object
 * @param[in] addUptime - Whether to add the uptime attribute the default is
 *                        true
 *
 * @return std::unique_ptr<UserData> - The section
 */
std::unique_ptr<UserData>
    makeSysInfoUserDataSection(const AdditionalData& ad,
                               const DataInterfaceBase& dataIface,
                               bool addUptime = true);

/**
 * @brief Reads data from an opened file descriptor.
 *
 * @param[in] fd - The FD to read from
 *
 * @return std::vector<uint8_t> - The data read
 */
std::vector<uint8_t> readFD(int fd);

/**
 * @brief Create a UserData section that contains the data in the file
 *        pointed to by the file descriptor passed in.
 *
 * @param[in] componentID - The component ID of the PEL creator
 * @param[in] file - The FFDC file information
 */
std::unique_ptr<UserData> makeFFDCuserDataSection(uint16_t componentID,
                                                  const PelFFDCfile& file);

/**
 * @brief Flattens a vector of strings into a vector of bytes suitable
 *        for storing in a PEL section.
 *
 * Adds a newline character after each string.
 *
 * @param lines - The vector of strings to convert
 *
 * @return std::vector<uint8_t> - The flattened data
 */
std::vector<uint8_t> flattenLines(const std::vector<std::string>& lines);

} // namespace util

} // namespace pels
} // namespace openpower
