#pragma once
#include "additional_data.hpp"

#include <nlohmann/json.hpp>

#include <filesystem>
#include <optional>
#include <string>
#include <variant>
#include <vector>

namespace openpower
{
namespace pels
{
namespace message
{

constexpr auto registryFileName = "message_registry.json";
enum class LookupType
{
    name = 0,
    reasonCode = 1
};

/**
 * @brief A possible severity/system type combination
 *
 * If there is no system type defined for this entry,
 * then the system field will be empty.
 */
struct RegistrySeverity
{
    std::string system;
    uint8_t severity;
};

/**
 * @brief Represents the Documentation related fields in the message registry.
 *        It is part of the 'Entry' structure that will be filled in when
 *        an error is looked up in the registry.
 *
 * If a field is wrapped by std::optional, it means the field is
 * optional in the JSON and higher level code knows how to handle it.
 */
struct DOC
{
    /**
     * @brief Description of error
     */
    std::string description;

    /**
     * @brief Error message field
     */
    std::string message;

    /**
     * @brief An optional vector of SRC word 6-9 to use as the source of the
     *        numeric arguments that will be substituted into any placeholder
     *        in the Message field.
     */
    std::optional<std::vector<std::string>> messageArgSources;
};

/**
 * @brief Represents the SRC related fields in the message registry.
 *        It is part of the 'Entry' structure that will be filled in when
 *        an error is looked up in the registry.
 *
 * If a field is wrapped by std::optional, it means the field is
 * optional in the JSON and higher level code knows how to handle it.
 */
struct SRC
{
    /**
     * @brief SRC type - The first byte of the ASCII string
     */
    uint8_t type;

    /**
     * @brief The SRC reason code (2nd half of 4B 'ASCII string' word)
     */
    uint16_t reasonCode;

    /**
     * @brief An optional vector of SRC hexword numbers that should be used
     *        along with the SRC ASCII string to build the Symptom ID, which
     *        is a field in the Extended Header section.
     */
    using WordNum = size_t;
    std::optional<std::vector<WordNum>> symptomID;

    /**
     * @brief Which AdditionalData fields to use to fill in the user defined
     *        SRC hexwords.
     *
     * For example, if the AdditionalData event log property contained
     * "CHIPNUM=42" and this map contained {6, {"CHIPNUM", "DESC"}}, then the
     * code would put 42 into SRC hexword 6.
     *
     * AdditionalDataField specifies two fields from the SRC entry in the
     * message registry: "AdditionalDataPropSource" and "Description"
     */
    using AdditionalDataField = std::tuple<std::string, std::string>;
    std::optional<std::map<WordNum, AdditionalDataField>> hexwordADFields;

    /**
     * @brief If the Deconfigured flag should be set in hex word 5
     */
    bool deconfigFlag;

    /**
     * @brief If the checkstop flag should be set in hex word 5
     */
    bool checkstopFlag;

    SRC() : type(0), reasonCode(0), deconfigFlag(false), checkstopFlag(false) {}
};

struct AppCapture
{
    std::string syslogID;
    size_t numLines;
};

// Can specify either the syslog IDs to capture along with how many
// entries of each, or just how many entries to get the full journal.
using AppCaptureList = std::vector<AppCapture>;
using JournalCapture = std::variant<size_t, AppCaptureList>;

/**
 * @brief Represents a message registry entry, which is used for creating a
 *        PEL from an OpenBMC event log.
 */
struct Entry
{
    /**
     * @brief The error name, like "xyz.openbmc_project.Error.Foo".
     */
    std::string name;

    /**
     * @brief The component ID of the PEL creator.
     */
    uint16_t componentID;

    /**
     * @brief The PEL subsystem field.
     */
    std::optional<uint8_t> subsystem;

    /**
     * @brief The optional PEL severity field.  If not specified, the PEL
     *        will use the severity of the OpenBMC event log.
     *
     * If the system type is specified in any of the entries in the vector,
     * then the system type will be needed to find the actual severity.
     */
    std::optional<std::vector<RegistrySeverity>> severity;

    /**
     * @brief The optional severity field to use when in manufacturing tolerance
     *        mode.  It behaves like the severity field above.
     */
    std::optional<std::vector<RegistrySeverity>> mfgSeverity;

    /**
     * @brief The PEL action flags field.
     */
    std::optional<uint16_t> actionFlags;

    /**
     * @brief  The optional action flags to use instead when in manufacturing
     * tolerance mode.
     */
    std::optional<uint16_t> mfgActionFlags;

    /**
     * @brief The PEL event type field.  If not specified, higher level code
     *        will decide the value.
     */
    std::optional<uint8_t> eventType;

    /**
     * @brief The PEL event scope field.  If not specified, higher level code
     *        will decide the value.
     */
    std::optional<uint8_t> eventScope;

    /**
     * The SRC related fields.
     */
    SRC src;

    /**
     * The Documentation related fields.
     */
    DOC doc;

    /**
     * @brief The callout JSON, if the entry has callouts.
     */
    std::optional<nlohmann::json> callouts;

    /**
     * @brief The journal capture instructions, if present.
     */
    std::optional<JournalCapture> journalCapture;
};

/**
 * @brief Holds callout information pulled out of the JSON.
 */
struct RegistryCallout
{
    std::string priority;
    std::string locCode;
    std::string procedure;
    std::string symbolicFRU;
    std::string symbolicFRUTrusted;
    bool useInventoryLocCode;
};

/**
 * @class Registry
 *
 * This class wraps the message registry JSON data and allows one to find
 * the message registry entry pertaining to the error name.
 *
 * So that new registry files can easily be tested, the code will look for
 * /etc/phosphor-logging/message_registry.json before looking for the real
 * path.
 */
class Registry
{
  public:
    Registry() = delete;
    ~Registry() = default;
    Registry(const Registry&) = default;
    Registry& operator=(const Registry&) = default;
    Registry(Registry&&) = default;
    Registry& operator=(Registry&&) = default;

    /**
     * @brief Constructor
     *
     * Will load the callout JSON.
     *
     * @param[in] registryFile - The path to the file.
     */
    explicit Registry(const std::filesystem::path& registryFile) :
        Registry(registryFile, true)
    {}

    /**
     * @brief Constructor
     *
     * This version contains a parameter that allows the callout JSON
     * to be saved in the Entry struct or not, as it isn't needed at
     * all in some cases.
     *
     * @param[in] registryFile - The path to the file.
     * @param[in] loadCallouts - If the callout JSON should be saved.
     */
    explicit Registry(const std::filesystem::path& registryFile,
                      bool loadCallouts) :
        _registryFile(registryFile), _loadCallouts(loadCallouts)
    {}

    /**
     * @brief Find a registry entry based on its error name or reason code.
     *
     * This function does do some basic sanity checking on the JSON contents,
     * but there is also an external program that enforces a schema on the
     * registry JSON that should catch all of these problems ahead of time.
     *
     * @param[in] name - The error name, like xyz.openbmc_project.Error.Foo
     *                 - OR
     *                 - The reason code, like 0x1001
     * @param[in] type - LookupType enum value
     * @param[in] toCache - boolean to cache registry in memory
     * @return optional<Entry> A filled in message registry structure if
     *                         found, otherwise an empty optional object.
     */
    std::optional<Entry> lookup(const std::string& name, LookupType type,
                                bool toCache = false);

    /**
     * @brief Find the callouts to put into the PEL based on the calloutJSON
     *        data.
     *
     * The system type and AdditionalData are used to index into the correct
     * callout table.
     *
     * Throws exceptions on failures.
     *
     * @param[in] calloutJSON - Where to look up the  callouts
     * @param[in] systemNames - List of compatible system type names
     * @param[in] additionalData - The AdditionalData property
     *
     * @return std::vector<RegistryCallout> - The callouts to use
     */
    static std::vector<RegistryCallout>
        getCallouts(const nlohmann::json& calloutJSON,
                    const std::vector<std::string>& systemNames,
                    const AdditionalData& additionalData);

  private:
    /**
     * @brief Parse message registry file using nlohmann::json
     * @param[in] registryFile - The message registry JSON file
     * @return optional<nlohmann::json> The full message registry object or an
     *                                  empty optional object upon failure.
     */
    std::optional<nlohmann::json>
        readRegistry(const std::filesystem::path& registryFile);

    /**
     * @brief The path to the registry JSON file.
     */
    std::filesystem::path _registryFile;

    /**
     * @brief The full message registry object.
     */
    std::optional<nlohmann::json> _registry;

    /**
     * @brief If the callout JSON should be saved in the Entry on lookup.
     */
    bool _loadCallouts;
};

namespace helper
{

/**
 * @brief A helper function to get the PEL subsystem value based on
 *        the registry subsystem name.
 *
 * @param[in] subsystemName - The registry name for the subsystem
 *
 * @return uint8_t The PEL subsystem value
 */
uint8_t getSubsystem(const std::string& subsystemName);

/**
 * @brief A helper function to get the PEL severity value based on
 *        the registry severity name.
 *
 * @param[in] severityName - The registry name for the severity
 *
 * @return uint8_t The PEL severity value
 */
uint8_t getSeverity(const std::string& severityName);

/**
 * @brief Returns all of the system type/severity values found
 * in the severity JSON passed in.
 *
 * The JSON is either a simple string, like:
 *     "unrecoverable"
 * or an array of system type/severity pairs, like:
 *     [
 *        {
 *            "System": "1",
 *            "SevValue": "predictive"
 *        },
 *        {
 *            "System": "2",
 *            "SevValue": "recovered"
 *        }
 *     ]
 *
 * @param[in] severity - The severity JSON
 * @return The list of severity/system combinations.  If the System key
 *         wasn't used, then that field will be empty in the structure.
 */
std::vector<RegistrySeverity> getSeverities(const nlohmann::json& severity);

/**
 * @brief A helper function to get the action flags value based on
 *        the action flag names used in the registry.
 *
 * @param[in] flags - The list of flag names from the registry.
 *
 * @return uint16_t - The bitfield of flags used in the PEL.
 */
uint16_t getActionFlags(const std::vector<std::string>& flags);

/**
 * @brief A helper function to get the PEL event type value based on
 *        the registry event type name.
 *
 * @param[in] eventTypeName - The registry name for the event type
 *
 * @return uint8_t The PEL event type value
 */
uint8_t getEventType(const std::string& eventTypeName);

/**
 * @brief A helper function to get the PEL event scope value based on
 *        the registry event scope name.
 *
 * @param[in] eventScopeName - The registry name for the event scope
 *
 * @return uint8_t The PEL event scope value
 */
uint8_t getEventScope(const std::string& eventScopeName);

/**
 * @brief Reads the "ReasonCode" field out of JSON and converts the string value
 *        such as "0x5555" to a uint16 like 0x5555.
 *
 * @param[in] src - The message registry SRC dictionary to read from
 * @param[in] name - The error name, to use in a trace if things go awry.
 *
 * @return uint16_t - The reason code
 */
uint16_t getSRCReasonCode(const nlohmann::json& src, const std::string& name);

/**
 * @brief Reads the "Type" field out of JSON and converts it to the SRC::Type
 *        value.
 *
 * @param[in] src - The message registry SRC dictionary to read from
 * @param[in] name - The error name, to use in a trace if things go awry.
 *
 * @return uint8_t - The SRC type value, like 0x11
 */
uint8_t getSRCType(const nlohmann::json& src, const std::string& name);

/**
 * @brief Reads the "Words6To9" field out of JSON and converts it to a map
 *        of the SRC word number to the AdditionalData property field used
 *        to fill it in with.
 *
 * @param[in] src - The message registry SRC dictionary to read from
 * @param[in] name - The error name, to use in a trace if things go awry.
 *
 * @return std::optional<std::map<SRC::WordNum, SRC::AdditionalDataField>>
 */
std::optional<std::map<SRC::WordNum, SRC::AdditionalDataField>>
    getSRCHexwordFields(const nlohmann::json& src, const std::string& name);

/**
 * @brief Reads the "SymptomIDFields" field out of JSON and converts it to
 *        a vector of SRC word numbers.
 *
 * @param[in] src - The message registry SRC dictionary to read from
 * @param[in] name - The error name, to use in a trace if things go awry.
 *
 * @return std::optional<std::vector<SRC::WordNum>>
 */
std::optional<std::vector<SRC::WordNum>>
    getSRCSymptomIDFields(const nlohmann::json& src, const std::string& name);

/**
 * @brief Returns the value of the 'DeconfigFlag' field.
 *
 * @param[in] src - The message registry SRC dictionary to read from
 *
 * @return bool - The field value
 */
bool getSRCDeconfigFlag(const nlohmann::json& src);

/**
 * @brief Reads the "ComponentID" field out of JSON and converts it to a
 *        uint16_t like 0xFF00.
 *
 * The ComponentID JSON field is only required if the SRC type isn't a BD
 * BMC SRC, because for those SRCs it can be inferred from the upper byte
 * of the SRC reasoncode.
 *
 * @param[in] srcType - The SRC type
 * @param[in] reasonCode - The SRC reason code
 * @param[in] pelEntry - The PEL entry JSON
 * @param[in] name - The error name, to use in a trace if things go awry.
 *
 * @return uin16_t - The component ID, like 0xFF00
 */
uint16_t getComponentID(uint8_t srcType, uint16_t reasonCode,
                        const nlohmann::json& pelEntry,
                        const std::string& name);

} // namespace helper

} // namespace message

} // namespace pels
} // namespace openpower
