/**
 * Copyright © 2018 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 "policy_find.hpp"

#include <phosphor-logging/log.hpp>

#include <sstream>

namespace ibm
{
namespace logging
{
namespace policy
{

static constexpr auto HOST_EVENT = "org.open_power.Host.Error.Event";

/**
 * Returns a property value from a map of properties.
 *
 * @tparam - T the property data type
 * @param[in] properties - the property map
 * @param[in] name - the property name
 *
 * @return optional<T> - the property value
 */
template <typename T>
std::optional<T> getProperty(const DbusPropertyMap& properties,
                             const std::string& name)
{
    auto prop = properties.find(name);

    if (prop != properties.end())
    {
        return std::get<T>(prop->second);
    }

    return {};
}

/**
 * Finds a value in the AdditionalData property, which is
 * an array of strings in the form of:
 *
 *    NAME=VALUE
 *
 * @param[in] additionalData - the AdditionalData property contents
 * @param[in] name - the name of the value to find
 *
 * @return optional<std::string> - the data value. Will not be empty if found.
 */
std::optional<std::string>
    getAdditionalDataItem(const std::vector<std::string>& additionalData,
                          const std::string& name)
{
    std::string value;

    for (const auto& item : additionalData)
    {
        if (item.find(name + "=") != std::string::npos)
        {
            value = item.substr(item.find('=') + 1);
            if (!item.empty())
            {
                return value;
            }
        }
    }

    return {};
}

/**
 * Returns a string version of the severity from the PEL
 * log in the extended SEL data from the host, where a PEL stands
 * for 'Platform Event Log' and is an IBM standard for error logging
 * that OpenPower host firmware uses.
 *
 * The severity is the 11th byte in the 'User Header' section in a PEL
 * that starts at byte 48.  We only need the first nibble, which signifies
 * the type - 'Recovered', 'Predictive', 'Critical', etc.
 *
 *  type value   |   type     |  returned severity string
 *  ------------------------------------
 *  1                Recovered   Informational
 *  2                Predictive  Warning
 *  everything else  na          Critical
 *
 * @param[in] data - the PEL string in the form of "00 11 22 33 4e ff"
 *
 * @return optional<std::string> - the severity string as listed above
 */
std::optional<std::string> getESELSeverity(const std::string& data)
{
    // The User Header section starts at byte 48, and take into account
    // the input data is a space separated string representation of HEX data.
    static constexpr auto UH_OFFSET = 48 * 4;

    // The eye catcher is "UH"
    static constexpr auto UH_EYECATCHER = "55 48";

    // The severity is the 11th byte in the section, and take into
    // account a byte is "BB "
    static constexpr auto UH_SEV_OFFSET = 10 * 3;

    std::string severity = "Critical";

    // The only values that don't map to "Critical"
    const std::map<std::string, std::string> sevTypes{{"1", "Informational"},
                                                      {"2", "Warning"}};
    if (data.size() <= (UH_OFFSET + UH_SEV_OFFSET))
    {
        return {};
    }

    // Sanity check that the User Header section is there.
    auto userHeader = data.substr(UH_OFFSET, 5);
    if (userHeader.compare(UH_EYECATCHER))
    {
        return {};
    }

    // The severity type nibble is a full byte in the string.
    auto sevType = data.substr(UH_OFFSET + UH_SEV_OFFSET, 1);

    auto sev = sevTypes.find(sevType);
    if (sev != sevTypes.end())
    {
        severity = sev->second;
    };

    return severity;
}

/**
 * Returns the search modifier to use, but if it isn't found
 * in the table then code should then call getSearchModifier()
 * and try again.
 *
 * This is to be tolerant of the policy table not having
 * entries for every device path or FRU callout, and trying
 * again gives code a chance to find the more generic entries
 * for those classes of errors rather than not being found
 * at all.
 *
 * e.g. If the device path is missing in the table, then it
 * can still find the generic "Failed to read from an I2C
 * device" entry.
 *
 * @param[in] message- the error message, like xyz.A.Error.B
 * @param[in] properties - the property map for the error
 *
 * @return string - the search modifier
 *                  may be empty if none found
 */
std::string getSearchModifierFirstTry(const std::string& message,
                                      const DbusPropertyMap& properties)
{
    auto data = getProperty<std::vector<std::string>>(properties,
                                                      "AdditionalData");

    if (!data)
    {
        return std::string{};
    }

    // Try the called out device path as the search modifier
    auto devPath = getAdditionalDataItem(*data, "CALLOUT_DEVICE_PATH");
    if (devPath)
    {
        return *devPath;
    }

    // For Host.Error.Event errors, try <callout>||<severity string>
    // as the search modifier.
    if (message == HOST_EVENT)
    {
        auto callout = getAdditionalDataItem(*data, "CALLOUT_INVENTORY_PATH");
        if (callout)
        {
            auto selData = getAdditionalDataItem(*data, "ESEL");
            if (selData)
            {
                auto severity = getESELSeverity(*selData);
                if (severity)
                {
                    return *callout + "||" + *severity;
                }
            }
        }
    }

    return std::string{};
}

/**
 * Returns the search modifier to use.
 *
 * The modifier is used when the error name itself isn't granular
 * enough to find a policy table entry.  The modifier is determined
 * using rules provided by the IBM service team.
 *
 * Not all errors need a modifier, so this function isn't
 * guaranteed to find one.
 *
 * @param[in] properties - the property map for the error
 *
 * @return string - the search modifier
 *                  may be empty if none found
 */
auto getSearchModifier(const DbusPropertyMap& properties)
{
    // The modifier may be one of several things within the
    // AdditionalData property.  Try them all until one
    // is found.

    auto data = getProperty<std::vector<std::string>>(properties,
                                                      "AdditionalData");

    if (!data)
    {
        return std::string{};
    }

    // AdditionalData fields where the value is the modifier
    static const std::vector<std::string> ADFields{"CALLOUT_INVENTORY_PATH",
                                                   "RAIL_NAME", "INPUT_NAME"};

    std::optional<std::string> mod;
    for (const auto& field : ADFields)
    {
        mod = getAdditionalDataItem(*data, field);
        if (mod)
        {
            return *mod;
        }
    }

    // Next are the AdditionalData fields where the value needs
    // to be massaged to get the modifier.

    // A device path, but we only care about the type
    mod = getAdditionalDataItem(*data, "CALLOUT_DEVICE_PATH");
    if (mod)
    {
        // The table only handles I2C and FSI
        if ((*mod).find("i2c") != std::string::npos)
        {
            return std::string{"I2C"};
        }
        else if ((*mod).find("fsi") != std::string::npos)
        {
            return std::string{"FSI"};
        }
    }

    // A hostboot procedure ID
    mod = getAdditionalDataItem(*data, "PROCEDURE");
    if (mod)
    {
        // Convert decimal (e.g. 109) to hex (e.g. 6D)
        std::ostringstream stream;
        try
        {
            stream << std::hex << std::stoul((*mod).c_str());
            auto value = stream.str();

            if (!value.empty())
            {
                std::transform(value.begin(), value.end(), value.begin(),
                               toupper);
                return value;
            }
        }
        catch (const std::exception& e)
        {
            using namespace phosphor::logging;
            log<level::ERR>("Invalid PROCEDURE value found",
                            entry("PROCEDURE=%s", mod->c_str()));
        }
    }

    return std::string{};
}

PolicyProps find(const policy::Table& policy,
                 const DbusPropertyMap& errorLogProperties)
{
    auto errorMsg = getProperty<std::string>(errorLogProperties,
                                             "Message"); // e.g. xyz.X.Error.Y
    if (errorMsg)
    {
        FindResult result;

        // Try with the FirstTry modifier first, and then the regular one.

        auto modifier = getSearchModifierFirstTry(*errorMsg,
                                                  errorLogProperties);

        if (!modifier.empty())
        {
            result = policy.find(*errorMsg, modifier);
        }

        if (!result)
        {
            modifier = getSearchModifier(errorLogProperties);

            result = policy.find(*errorMsg, modifier);
        }

        if (result)
        {
            return {(*result).get().ceid, (*result).get().msg};
        }
    }
    else
    {
        using namespace phosphor::logging;
        log<level::ERR>("No Message metadata found in an error");
    }

    return {policy.defaultEID(), policy.defaultMsg()};
}
} // namespace policy
} // namespace logging
} // namespace ibm
