#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;

    SRC() : type(0), reasonCode(0), deconfigFlag(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
