/**
 * Copyright © 2019 IBM Corporation
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#include "registry.hpp"

#include "json_utils.hpp"
#include "pel_types.hpp"
#include "pel_values.hpp"

#include <phosphor-logging/log.hpp>

#include <fstream>

namespace openpower
{
namespace pels
{
namespace message
{

namespace pv = pel_values;
namespace fs = std::filesystem;
using namespace phosphor::logging;

constexpr auto debugFilePath = "/etc/phosphor-logging/";

namespace helper
{

uint8_t getSubsystem(const std::string& subsystemName)
{
    // Get the actual value to use in the PEL for the string name
    auto ss = pv::findByName(subsystemName, pv::subsystemValues);
    if (ss == pv::subsystemValues.end())
    {
        // Schema validation should be catching this.
        log<level::ERR>("Invalid subsystem name used in message registry",
                        entry("SUBSYSTEM=%s", subsystemName.c_str()));

        throw std::runtime_error("Invalid subsystem used in message registry");
    }

    return std::get<pv::fieldValuePos>(*ss);
}

uint8_t getSeverity(const std::string& severityName)
{
    auto s = pv::findByName(severityName, pv::severityValues);
    if (s == pv::severityValues.end())
    {
        // Schema validation should be catching this.
        log<level::ERR>("Invalid severity name used in message registry",
                        entry("SEVERITY=%s", severityName.c_str()));

        throw std::runtime_error("Invalid severity used in message registry");
    }

    return std::get<pv::fieldValuePos>(*s);
}

std::vector<RegistrySeverity> getSeverities(const nlohmann::json& severity)
{
    std::vector<RegistrySeverity> severities;

    // The plain string value, like "unrecoverable"
    if (severity.is_string())
    {
        RegistrySeverity s;
        s.severity = getSeverity(severity.get<std::string>());
        severities.push_back(std::move(s));
    }
    else
    {
        // An array, with an element like:
        // {
        //    "SevValue": "unrecoverable",
        //    "System", "systemA"
        // }
        for (const auto& sev : severity)
        {
            RegistrySeverity s;
            s.severity = getSeverity(sev["SevValue"].get<std::string>());

            if (sev.contains("System"))
            {
                s.system = sev["System"].get<std::string>();
            }

            severities.push_back(std::move(s));
        }
    }

    return severities;
}

uint16_t getActionFlags(const std::vector<std::string>& flags)
{
    uint16_t actionFlags = 0;

    // Make the bitmask based on the array of flag names
    for (const auto& flag : flags)
    {
        auto s = pv::findByName(flag, pv::actionFlagsValues);
        if (s == pv::actionFlagsValues.end())
        {
            // Schema validation should be catching this.
            log<level::ERR>("Invalid action flag name used in message registry",
                            entry("FLAG=%s", flag.c_str()));

            throw std::runtime_error(
                "Invalid action flag used in message registry");
        }

        actionFlags |= std::get<pv::fieldValuePos>(*s);
    }

    return actionFlags;
}

uint8_t getEventType(const std::string& eventTypeName)
{
    auto t = pv::findByName(eventTypeName, pv::eventTypeValues);
    if (t == pv::eventTypeValues.end())
    {
        log<level::ERR>("Invalid event type used in message registry",
                        entry("EVENT_TYPE=%s", eventTypeName.c_str()));

        throw std::runtime_error("Invalid event type used in message registry");
    }
    return std::get<pv::fieldValuePos>(*t);
}

uint8_t getEventScope(const std::string& eventScopeName)
{
    auto s = pv::findByName(eventScopeName, pv::eventScopeValues);
    if (s == pv::eventScopeValues.end())
    {
        log<level::ERR>("Invalid event scope used in registry",
                        entry("EVENT_SCOPE=%s", eventScopeName.c_str()));

        throw std::runtime_error(
            "Invalid event scope used in message registry");
    }
    return std::get<pv::fieldValuePos>(*s);
}

uint16_t getSRCReasonCode(const nlohmann::json& src, const std::string& name)
{
    std::string rc = src["ReasonCode"];
    uint16_t reasonCode = strtoul(rc.c_str(), nullptr, 16);
    if (reasonCode == 0)
    {
        log<phosphor::logging::level::ERR>(
            "Invalid reason code in message registry",
            entry("ERROR_NAME=%s", name.c_str()),
            entry("REASON_CODE=%s", rc.c_str()));

        throw std::runtime_error("Invalid reason code in message registry");
    }
    return reasonCode;
}

uint8_t getSRCType(const nlohmann::json& src, const std::string& name)
{
    // Looks like: "22"
    std::string srcType = src["Type"];
    size_t type = strtoul(srcType.c_str(), nullptr, 16);
    if ((type == 0) || (srcType.size() != 2)) // 1 hex byte
    {
        log<phosphor::logging::level::ERR>(
            "Invalid SRC Type in message registry",
            entry("ERROR_NAME=%s", name.c_str()),
            entry("SRC_TYPE=%s", srcType.c_str()));

        throw std::runtime_error("Invalid SRC Type in message registry");
    }

    return type;
}

bool getSRCDeconfigFlag(const nlohmann::json& src)
{
    return src["DeconfigFlag"].get<bool>();
}

bool getSRCCheckstopFlag(const nlohmann::json& src)
{
    return src["CheckstopFlag"].get<bool>();
}

std::optional<std::map<SRC::WordNum, SRC::AdditionalDataField>>
    getSRCHexwordFields(const nlohmann::json& src, const std::string& name)
{
    std::map<SRC::WordNum, SRC::AdditionalDataField> hexwordFields;

    // Build the map of which AdditionalData fields to use for which SRC words

    // Like:
    // {
    //   "8":
    //   {
    //     "AdditionalDataPropSource": "TEST"
    //   }
    //
    // }

    for (const auto& word : src["Words6To9"].items())
    {
        std::string num = word.key();
        size_t wordNum = std::strtoul(num.c_str(), nullptr, 10);

        if (wordNum == 0)
        {
            log<phosphor::logging::level::ERR>(
                "Invalid SRC word number in message registry",
                entry("ERROR_NAME=%s", name.c_str()),
                entry("SRC_WORD_NUM=%s", num.c_str()));

            throw std::runtime_error("Invalid SRC word in message registry");
        }

        auto attributes = word.value();

        // Use an empty string for the description if it does not exist.
        auto itr = attributes.find("Description");
        std::string desc = (attributes.end() != itr) ? *itr : "";

        std::tuple<std::string, std::string> adPropSourceDesc(
            attributes["AdditionalDataPropSource"], desc);
        hexwordFields[wordNum] = std::move(adPropSourceDesc);
    }

    if (!hexwordFields.empty())
    {
        return hexwordFields;
    }

    return std::nullopt;
}
std::optional<std::vector<SRC::WordNum>>
    getSRCSymptomIDFields(const nlohmann::json& src, const std::string& name)
{
    std::vector<SRC::WordNum> symptomIDFields;

    // Looks like:
    // "SymptomIDFields": ["SRCWord3", "SRCWord6"],

    for (const std::string field : src["SymptomIDFields"])
    {
        // Just need the last digit off the end, e.g. SRCWord6.
        // The schema enforces the format of these.
        auto srcWordNum = field.substr(field.size() - 1);
        size_t num = std::strtoul(srcWordNum.c_str(), nullptr, 10);
        if (num == 0)
        {
            log<phosphor::logging::level::ERR>(
                "Invalid symptom ID field in message registry",
                entry("ERROR_NAME=%s", name.c_str()),
                entry("FIELD_NAME=%s", srcWordNum.c_str()));

            throw std::runtime_error("Invalid symptom ID in message registry");
        }
        symptomIDFields.push_back(num);
    }
    if (!symptomIDFields.empty())
    {
        return symptomIDFields;
    }

    return std::nullopt;
}

uint16_t getComponentID(uint8_t srcType, uint16_t reasonCode,
                        const nlohmann::json& pelEntry, const std::string& name)
{
    uint16_t id = 0;

    // If the ComponentID field is there, use that.  Otherwise, if it's a
    // 0xBD BMC error SRC, use the reasoncode.
    if (pelEntry.contains("ComponentID"))
    {
        std::string componentID = pelEntry["ComponentID"];
        id = strtoul(componentID.c_str(), nullptr, 16);
    }
    else
    {
        // On BMC error SRCs (BD), can just get the component ID from
        // the first byte of the reason code.
        if (srcType == static_cast<uint8_t>(SRCType::bmcError))
        {
            id = reasonCode & 0xFF00;
        }
        else
        {
            log<level::ERR>("Missing component ID field in message registry",
                            entry("ERROR_NAME=%s", name.c_str()));

            throw std::runtime_error(
                "Missing component ID field in message registry");
        }
    }

    return id;
}

/**
 * @brief Says if the JSON is the format that contains AdditionalData keys
 *        as in index into them.
 *
 * @param[in] json - The highest level callout JSON
 *
 * @return bool - If it is the AdditionalData format or not
 */
bool calloutUsesAdditionalData(const nlohmann::json& json)
{
    return (json.contains("ADName") &&
            json.contains("CalloutsWithTheirADValues"));
}

/**
 * @brief Finds the callouts to use when there is no AdditionalData,
 *        but the system type may be used as a key.
 *
 * One entry in the array looks like the following.  The System key
 * is optional and if not present it means that entry applies to
 * every configuration that doesn't have another entry with a matching
 * System key.
 *
 *    {
 *        "System": "system1",
 *        "CalloutList":
 *        [
 *            {
 *                "Priority": "high",
 *                "LocCode": "P1-C1"
 *            },
 *            {
 *                "Priority": "low",
 *                "LocCode": "P1"
 *            }
 *        ]
 *    }
 */
const nlohmann::json&
    findCalloutList(const nlohmann::json& json,
                    const std::vector<std::string>& systemNames)
{
    const nlohmann::json* callouts = nullptr;

    if (!json.is_array())
    {
        throw std::runtime_error{"findCalloutList was not passed a JSON array"};
    }

    // The entry with the system type match will take precedence over the entry
    // without any "System" field in it at all, which will match all other
    // cases.
    for (const auto& calloutList : json)
    {
        if (calloutList.contains("System"))
        {
            if (std::find(systemNames.begin(), systemNames.end(),
                          calloutList["System"].get<std::string>()) !=
                systemNames.end())
            {
                callouts = &calloutList["CalloutList"];
                break;
            }
        }
        else
        {
            // Any entry with no System key
            callouts = &calloutList["CalloutList"];
        }
    }

    if (!callouts)
    {
        std::string types;
        std::for_each(systemNames.begin(), systemNames.end(),
                      [&types](const auto& t) { types += t + '|'; });
        log<level::WARNING>(
            "No matching system name entry or default system name entry "
            " for PEL callout list",
            entry("SYSTEMNAMES=%s", types.c_str()));

        throw std::runtime_error{
            "Could not find a CalloutList JSON for this error and system name"};
    }

    return *callouts;
}

/**
 * @brief Creates a RegistryCallout based on the input JSON.
 *
 * The JSON looks like:
 *     {
 *          "Priority": "high",
 *          "LocCode": "E1"
 *          ...
 *     }
 *
 * Schema validation enforces what keys are present.
 *
 * @param[in] json - The JSON dictionary entry for a callout
 *
 * @return RegistryCallout - A filled in RegistryCallout
 */
RegistryCallout makeRegistryCallout(const nlohmann::json& json)
{
    RegistryCallout callout;

    callout.priority = "high";
    callout.useInventoryLocCode = false;

    if (json.contains("Priority"))
    {
        callout.priority = json["Priority"].get<std::string>();
    }

    if (json.contains("LocCode"))
    {
        callout.locCode = json["LocCode"].get<std::string>();
    }

    if (json.contains("Procedure"))
    {
        callout.procedure = json["Procedure"].get<std::string>();
    }
    else if (json.contains("SymbolicFRU"))
    {
        callout.symbolicFRU = json["SymbolicFRU"].get<std::string>();
    }
    else if (json.contains("SymbolicFRUTrusted"))
    {
        callout.symbolicFRUTrusted =
            json["SymbolicFRUTrusted"].get<std::string>();
    }

    if (json.contains("UseInventoryLocCode"))
    {
        callout.useInventoryLocCode = json["UseInventoryLocCode"].get<bool>();
    }

    return callout;
}

/**
 * @brief Returns the callouts to use when an AdditionalData key is
 *        required to find the correct entries.
 *
 *       The System property is used to find which CalloutList to use.
 *       If System is missing, then that CalloutList is valid for
 *       everything.
 *
 * The JSON looks like:
 *    [
 *        {
 *            "System": "systemA",
 *            "CalloutList":
 *            [
 *                {
 *                    "Priority": "high",
 *                    "LocCode": "P1-C5"
 *                }
 *            ]
 *         }
 *    ]
 *
 * @param[in] json - The callout JSON
 * @param[in] systemNames - List of compatible system type names
 *
 * @return std::vector<RegistryCallout> - The callouts to use
 */
std::vector<RegistryCallout>
    getCalloutsWithoutAD(const nlohmann::json& json,
                         const std::vector<std::string>& systemNames)
{
    std::vector<RegistryCallout> calloutEntries;

    // Find the CalloutList to use based on the system type
    const auto& calloutList = findCalloutList(json, systemNames);

    // We finally found the callouts, make the objects.
    for (const auto& callout : calloutList)
    {
        calloutEntries.push_back(std::move(makeRegistryCallout(callout)));
    }

    return calloutEntries;
}

/**
 * @brief Returns the callouts to use when an AdditionalData key is
 *        required to find the correct entries.
 *
 * The JSON looks like:
 *    {
 *        "ADName": "PROC_NUM",
 *        "CalloutsWithTheirADValues":
 *        [
 *            {
 *                "ADValue": "0",
 *                "Callouts":
 *                [
 *                    {
 *                        "CalloutList":
 *                        [
 *                            {
 *                                "Priority": "high",
 *                                "LocCode": "P1-C5"
 *                            }
 *                        ]
 *                    }
 *                ]
 *            }
 *        ]
 *     }
 *
 * Note that the "Callouts" entry above is the same as the top level
 * entry used when there is no AdditionalData key.
 *
 * @param[in] json - The callout JSON
 * @param[in] systemNames - List of compatible system type names
 * @param[in] additionalData - The AdditionalData property
 *
 * @return std::vector<RegistryCallout> - The callouts to use
 */
std::vector<RegistryCallout>
    getCalloutsUsingAD(const nlohmann::json& json,
                       const std::vector<std::string>& systemNames,
                       const AdditionalData& additionalData)
{
    // This indicates which AD field we'll be using
    auto keyName = json["ADName"].get<std::string>();

    // Get the actual value from the AD data
    auto adValue = additionalData.getValue(keyName);

    if (!adValue)
    {
        // The AdditionalData did not contain the necessary key
        log<level::WARNING>(
            "The PEL message registry callouts JSON "
            "said to use an AdditionalData key that isn't in the "
            "AdditionalData event log property",
            entry("ADNAME=%s\n", keyName.c_str()));
        throw std::runtime_error{
            "Missing AdditionalData entry for this callout"};
    }

    const auto& callouts = json["CalloutsWithTheirADValues"];

    // find the entry with that AD value
    auto it = std::find_if(callouts.begin(), callouts.end(),
                           [adValue](const nlohmann::json& j) {
        return *adValue == j["ADValue"].get<std::string>();
    });

    if (it == callouts.end())
    {
        // This can happen if not all possible values were in the
        // message registry and that's fine.  There may be a
        // "CalloutsWhenNoADMatch" section that contains callouts
        // to use in this case.
        if (json.contains("CalloutsWhenNoADMatch"))
        {
            return getCalloutsWithoutAD(json["CalloutsWhenNoADMatch"],
                                        systemNames);
        }
        return std::vector<RegistryCallout>{};
    }

    // Proceed to find the callouts possibly based on system type.
    return getCalloutsWithoutAD((*it)["Callouts"], systemNames);
}

/**
 * @brief Returns the journal capture information
 *
 *  The JSON looks like:
 *    "JournalCapture": {
 *        "NumLines": 30
 *    }
 *
 *    "JournalCapture":
 *    {
 *        "Sections": [
 *            {
 *                "SyslogID": "phosphor-log-manager",
 *                "NumLines": 20
 *            }
 *        ]
 *    }
 *
 * @param json - The journal capture JSON
 * @return JournalCapture - The filled in variant
 */
JournalCapture getJournalCapture(const nlohmann::json& json)
{
    JournalCapture capt;

    // Primary key is either NumLines or Sections.
    if (json.contains("NumLines"))
    {
        capt = json.at("NumLines").get<size_t>();
    }
    else if (json.contains("Sections"))
    {
        AppCaptureList captures;
        for (const auto& capture : json.at("Sections"))
        {
            AppCapture ac;
            ac.syslogID = capture.at("SyslogID").get<std::string>();
            ac.numLines = capture.at("NumLines").get<size_t>();
            captures.push_back(std::move(ac));
        }

        capt = captures;
    }
    else
    {
        log<level::ERR>("JournalCapture section not the right format");
        throw std::runtime_error{"JournalCapture section not the right format"};
    }

    return capt;
}

} // namespace helper

std::optional<Entry> Registry::lookup(const std::string& name, LookupType type,
                                      bool toCache)
{
    std::optional<nlohmann::json> registryTmp;
    auto& registryOpt = (_registry) ? _registry : registryTmp;
    if (!registryOpt)
    {
        registryOpt = readRegistry(_registryFile);
        if (!registryOpt)
        {
            return std::nullopt;
        }
        else if (toCache)
        {
            // Save message registry in memory for peltool
            _registry = std::move(registryTmp);
        }
    }
    auto& reg = (_registry) ? _registry : registryTmp;
    const auto& registry = reg.value();
    // Find an entry with this name in the PEL array.
    auto e = std::find_if(registry["PELs"].begin(), registry["PELs"].end(),
                          [&name, &type](const nlohmann::json& j) {
        return ((name == j.at("Name").get<std::string>() &&
                 type == LookupType::name) ||
                (name == j.at("SRC").at("ReasonCode").get<std::string>() &&
                 type == LookupType::reasonCode));
    });

    if (e != registry["PELs"].end())
    {
        // Fill in the Entry structure from the JSON.  Most, but not all, fields
        // are optional.

        try
        {
            Entry entry;
            entry.name = (*e)["Name"];

            if (e->contains("Subsystem"))
            {
                entry.subsystem = helper::getSubsystem((*e)["Subsystem"]);
            }

            if (e->contains("ActionFlags"))
            {
                entry.actionFlags = helper::getActionFlags((*e)["ActionFlags"]);
            }

            if (e->contains("MfgActionFlags"))
            {
                entry.mfgActionFlags =
                    helper::getActionFlags((*e)["MfgActionFlags"]);
            }

            if (e->contains("Severity"))
            {
                entry.severity = helper::getSeverities((*e)["Severity"]);
            }

            if (e->contains("MfgSeverity"))
            {
                entry.mfgSeverity = helper::getSeverities((*e)["MfgSeverity"]);
            }

            if (e->contains("EventType"))
            {
                entry.eventType = helper::getEventType((*e)["EventType"]);
            }

            if (e->contains("EventScope"))
            {
                entry.eventScope = helper::getEventScope((*e)["EventScope"]);
            }

            auto& src = (*e)["SRC"];
            entry.src.reasonCode = helper::getSRCReasonCode(src, name);

            if (src.contains("Type"))
            {
                entry.src.type = helper::getSRCType(src, name);
            }
            else
            {
                entry.src.type = static_cast<uint8_t>(SRCType::bmcError);
            }

            // Now that we know the SRC type and reason code,
            // we can get the component ID.
            entry.componentID = helper::getComponentID(
                entry.src.type, entry.src.reasonCode, *e, name);

            if (src.contains("Words6To9"))
            {
                entry.src.hexwordADFields = helper::getSRCHexwordFields(src,
                                                                        name);
            }

            if (src.contains("SymptomIDFields"))
            {
                entry.src.symptomID = helper::getSRCSymptomIDFields(src, name);
            }

            if (src.contains("DeconfigFlag"))
            {
                entry.src.deconfigFlag = helper::getSRCDeconfigFlag(src);
            }

            if (src.contains("CheckstopFlag"))
            {
                entry.src.checkstopFlag = helper::getSRCCheckstopFlag(src);
            }

            auto& doc = (*e)["Documentation"];
            entry.doc.message = doc["Message"];
            entry.doc.description = doc["Description"];
            if (doc.contains("MessageArgSources"))
            {
                entry.doc.messageArgSources = doc["MessageArgSources"];
            }

            // If there are callouts defined, save the JSON for later
            if (_loadCallouts)
            {
                if (e->contains("Callouts"))
                {
                    entry.callouts = (*e)["Callouts"];
                }
                else if (e->contains("CalloutsUsingAD"))
                {
                    entry.callouts = (*e)["CalloutsUsingAD"];
                }
            }

            if (e->contains("JournalCapture"))
            {
                entry.journalCapture =
                    helper::getJournalCapture((*e)["JournalCapture"]);
            }

            return entry;
        }
        catch (const std::exception& ex)
        {
            log<level::ERR>("Found invalid message registry field",
                            entry("ERROR=%s", ex.what()));
        }
    }

    return std::nullopt;
}

std::optional<nlohmann::json>
    Registry::readRegistry(const std::filesystem::path& registryFile)
{
    // Look in /etc first in case someone put a test file there
    fs::path debugFile{fs::path{debugFilePath} / registryFileName};
    nlohmann::json registry;
    std::ifstream file;

    if (fs::exists(debugFile))
    {
        log<level::INFO>("Using debug PEL message registry");
        file.open(debugFile);
    }
    else
    {
        file.open(registryFile);
    }

    try
    {
        registry = nlohmann::json::parse(file);
    }
    catch (const std::exception& e)
    {
        log<level::ERR>("Error parsing message registry JSON",
                        entry("JSON_ERROR=%s", e.what()));
        return std::nullopt;
    }
    return registry;
}

std::vector<RegistryCallout>
    Registry::getCallouts(const nlohmann::json& calloutJSON,
                          const std::vector<std::string>& systemNames,
                          const AdditionalData& additionalData)
{
    // The JSON may either use an AdditionalData key
    // as an index, or not.
    if (helper::calloutUsesAdditionalData(calloutJSON))
    {
        return helper::getCalloutsUsingAD(calloutJSON, systemNames,
                                          additionalData);
    }

    return helper::getCalloutsWithoutAD(calloutJSON, systemNames);
}

} // namespace message
} // namespace pels
} // namespace openpower
