/**
 * Copyright © 2020 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 "json_parser.hpp"

#include "conditions.hpp"
#include "json_config.hpp"
#include "nonzero_speed_trust.hpp"
#include "power_interface.hpp"
#include "power_off_rule.hpp"
#include "tach_sensor.hpp"
#include "types.hpp"

#include <nlohmann/json.hpp>
#include <phosphor-logging/log.hpp>

#include <algorithm>
#include <format>
#include <map>
#include <memory>
#include <optional>
#include <vector>

namespace phosphor::fan::monitor
{

using json = nlohmann::json;
using namespace phosphor::logging;

namespace tClass
{

// Get a constructed trust group class for a non-zero speed group
CreateGroupFunction
    getNonZeroSpeed(const std::vector<trust::GroupDefinition>& group)
{
    return [group]() {
        return std::make_unique<trust::NonzeroSpeed>(std::move(group));
    };
}

} // namespace tClass

const std::map<std::string, trustHandler> trusts = {
    {"nonzerospeed", tClass::getNonZeroSpeed}};
const std::map<std::string, condHandler> conditions = {
    {"propertiesmatch", condition::getPropertiesMatch}};
const std::map<std::string, size_t> methods = {
    {"timebased", MethodMode::timebased}, {"count", MethodMode::count}};

const std::vector<CreateGroupFunction> getTrustGrps(const json& obj)
{
    std::vector<CreateGroupFunction> grpFuncs;

    if (obj.contains("sensor_trust_groups"))
    {
        for (auto& stg : obj["sensor_trust_groups"])
        {
            if (!stg.contains("class") || !stg.contains("group"))
            {
                // Log error on missing required parameters
                log<level::ERR>(
                    "Missing required fan monitor trust group parameters",
                    entry("REQUIRED_PARAMETERS=%s", "{class, group}"));
                throw std::runtime_error(
                    "Missing required fan trust group parameters");
            }
            auto tgClass = stg["class"].get<std::string>();
            std::vector<trust::GroupDefinition> group;
            for (auto& member : stg["group"])
            {
                // Construct list of group members
                if (!member.contains("name"))
                {
                    // Log error on missing required parameter
                    log<level::ERR>(
                        "Missing required fan monitor trust group member name",
                        entry("CLASS=%s", tgClass.c_str()));
                    throw std::runtime_error(
                        "Missing required fan monitor trust group member name");
                }
                auto in_trust = true;
                if (member.contains("in_trust"))
                {
                    in_trust = member["in_trust"].get<bool>();
                }
                group.emplace_back(trust::GroupDefinition{
                    member["name"].get<std::string>(), in_trust});
            }
            // The class for fan sensor trust groups
            // (Must have a supported function within the tClass namespace)
            std::transform(tgClass.begin(), tgClass.end(), tgClass.begin(),
                           tolower);
            auto handler = trusts.find(tgClass);
            if (handler != trusts.end())
            {
                // Call function for trust group class
                grpFuncs.emplace_back(handler->second(group));
            }
            else
            {
                // Log error on unsupported trust group class
                log<level::ERR>("Invalid fan monitor trust group class",
                                entry("CLASS=%s", tgClass.c_str()));
                throw std::runtime_error(
                    "Invalid fan monitor trust group class");
            }
        }
    }

    return grpFuncs;
}

const std::vector<SensorDefinition> getSensorDefs(const json& sensors)
{
    std::vector<SensorDefinition> sensorDefs;

    for (const auto& sensor : sensors)
    {
        if (!sensor.contains("name") || !sensor.contains("has_target"))
        {
            // Log error on missing required parameters
            log<level::ERR>(
                "Missing required fan sensor definition parameters",
                entry("REQUIRED_PARAMETERS=%s", "{name, has_target}"));
            throw std::runtime_error(
                "Missing required fan sensor definition parameters");
        }
        // Target interface is optional and defaults to
        // 'xyz.openbmc_project.Control.FanSpeed'
        std::string targetIntf = "xyz.openbmc_project.Control.FanSpeed";
        if (sensor.contains("target_interface"))
        {
            targetIntf = sensor["target_interface"].get<std::string>();
        }
        // Target path is optional
        std::string targetPath;
        if (sensor.contains("target_path"))
        {
            targetPath = sensor["target_path"].get<std::string>();
        }
        // Factor is optional and defaults to 1
        double factor = 1.0;
        if (sensor.contains("factor"))
        {
            factor = sensor["factor"].get<double>();
        }
        // Offset is optional and defaults to 0
        int64_t offset = 0;
        if (sensor.contains("offset"))
        {
            offset = sensor["offset"].get<int64_t>();
        }
        // Threshold is optional and defaults to 1
        size_t threshold = 1;
        if (sensor.contains("threshold"))
        {
            threshold = sensor["threshold"].get<size_t>();
        }
        // Ignore being above the allowed max is optional, defaults to not
        bool ignoreAboveMax = false;
        if (sensor.contains("ignore_above_max"))
        {
            ignoreAboveMax = sensor["ignore_above_max"].get<bool>();
        }

        SensorDefinition def{
            .name = sensor["name"].get<std::string>(),
            .hasTarget = sensor["has_target"].get<bool>(),
            .targetInterface = targetIntf,
            .targetPath = targetPath,
            .factor = factor,
            .offset = offset,
            .threshold = threshold,
            .ignoreAboveMax = ignoreAboveMax};

        sensorDefs.push_back(std::move(def));
    }

    return sensorDefs;
}

const std::vector<FanDefinition> getFanDefs(const json& obj)
{
    std::vector<FanDefinition> fanDefs;

    for (const auto& fan : obj["fans"])
    {
        if (!fan.contains("inventory") || !fan.contains("deviation") ||
            !fan.contains("sensors"))
        {
            // Log error on missing required parameters
            log<level::ERR>(
                "Missing required fan monitor definition parameters",
                entry("REQUIRED_PARAMETERS=%s",
                      "{inventory, deviation, sensors}"));
            throw std::runtime_error(
                "Missing required fan monitor definition parameters");
        }
        // Valid deviation range is 0 - 100%
        auto deviation = fan["deviation"].get<size_t>();
        if (100 < deviation)
        {
            auto msg = std::format(
                "Invalid deviation of {} found, must be between 0 and 100",
                deviation);

            log<level::ERR>(msg.c_str());
            throw std::runtime_error(msg.c_str());
        }

        // Upper deviation defaults to the deviation value and
        // can also be separately specified.
        size_t upperDeviation = deviation;
        if (fan.contains("upper_deviation"))
        {
            upperDeviation = fan["upper_deviation"].get<size_t>();
            if (100 < upperDeviation)
            {
                auto msg =
                    std::format("Invalid upper_deviation of {} found, must "
                                "be between 0 and 100",
                                upperDeviation);

                log<level::ERR>(msg.c_str());
                throw std::runtime_error(msg.c_str());
            }
        }

        // Construct the sensor definitions for this fan
        auto sensorDefs = getSensorDefs(fan["sensors"]);

        // Functional delay is optional and defaults to 0
        size_t funcDelay = 0;
        if (fan.contains("functional_delay"))
        {
            funcDelay = fan["functional_delay"].get<size_t>();
        }

        // Method is optional and defaults to time based functional
        // determination
        size_t method = MethodMode::timebased;
        size_t countInterval = 1;
        if (fan.contains("method"))
        {
            auto methodConf = fan["method"].get<std::string>();
            auto methodFunc = methods.find(methodConf);
            if (methodFunc != methods.end())
            {
                method = methodFunc->second;
            }
            else
            {
                // Log error on unsupported method parameter
                log<level::ERR>("Invalid fan method");
                throw std::runtime_error("Invalid fan method");
            }

            // Read the count interval value used with the count method.
            if (method == MethodMode::count)
            {
                if (fan.contains("count_interval"))
                {
                    countInterval = fan["count_interval"].get<size_t>();
                }
            }
        }

        // Timeout defaults to 0
        size_t timeout = 0;
        if (method == MethodMode::timebased)
        {
            if (!fan.contains("allowed_out_of_range_time"))
            {
                // Log error on missing required parameter
                log<level::ERR>(
                    "Missing required fan monitor definition parameters",
                    entry("REQUIRED_PARAMETER=%s",
                          "{allowed_out_of_range_time}"));
                throw std::runtime_error(
                    "Missing required fan monitor definition parameters");
            }
            else
            {
                timeout = fan["allowed_out_of_range_time"].get<size_t>();
            }
        }

        // Monitor start delay is optional and defaults to 0
        size_t monitorDelay = 0;
        if (fan.contains("monitor_start_delay"))
        {
            monitorDelay = fan["monitor_start_delay"].get<size_t>();
        }

        // num_sensors_nonfunc_for_fan_nonfunc is optional and defaults
        // to zero if not present, meaning the code will not set the
        // parent fan to nonfunctional based on sensors.
        size_t nonfuncSensorsCount = 0;
        if (fan.contains("num_sensors_nonfunc_for_fan_nonfunc"))
        {
            nonfuncSensorsCount =
                fan["num_sensors_nonfunc_for_fan_nonfunc"].get<size_t>();
        }

        // nonfunc_rotor_error_delay is optional, though it will
        // default to zero if 'fault_handling' is present.
        std::optional<size_t> nonfuncRotorErrorDelay;
        if (fan.contains("nonfunc_rotor_error_delay"))
        {
            nonfuncRotorErrorDelay =
                fan["nonfunc_rotor_error_delay"].get<size_t>();
        }
        else if (obj.contains("fault_handling"))
        {
            nonfuncRotorErrorDelay = 0;
        }

        // fan_missing_error_delay is optional.
        std::optional<size_t> fanMissingErrorDelay;
        if (fan.contains("fan_missing_error_delay"))
        {
            fanMissingErrorDelay =
                fan.at("fan_missing_error_delay").get<size_t>();
        }

        // Handle optional conditions
        auto cond = std::optional<Condition>();
        if (fan.contains("condition"))
        {
            if (!fan["condition"].contains("name"))
            {
                // Log error on missing required parameter
                log<level::ERR>(
                    "Missing required fan monitor condition parameter",
                    entry("REQUIRED_PARAMETER=%s", "{name}"));
                throw std::runtime_error(
                    "Missing required fan monitor condition parameter");
            }
            auto name = fan["condition"]["name"].get<std::string>();
            // The function for fan monitoring condition
            // (Must have a supported function within the condition namespace)
            std::transform(name.begin(), name.end(), name.begin(), tolower);
            auto handler = conditions.find(name);
            if (handler != conditions.end())
            {
                cond = handler->second(fan["condition"]);
            }
            else
            {
                log<level::INFO>(
                    "No handler found for configured condition",
                    entry("CONDITION_NAME=%s", name.c_str()),
                    entry("JSON_DUMP=%s", fan["condition"].dump().c_str()));
            }
        }

        // if the fan should be set to functional when plugged in
        bool setFuncOnPresent = false;
        if (fan.contains("set_func_on_present"))
        {
            setFuncOnPresent = fan["set_func_on_present"].get<bool>();
        }

        FanDefinition def{
            .name = fan["inventory"].get<std::string>(),
            .method = method,
            .funcDelay = funcDelay,
            .timeout = timeout,
            .deviation = deviation,
            .upperDeviation = upperDeviation,
            .numSensorFailsForNonfunc = nonfuncSensorsCount,
            .monitorStartDelay = monitorDelay,
            .countInterval = countInterval,
            .nonfuncRotorErrDelay = nonfuncRotorErrorDelay,
            .fanMissingErrDelay = fanMissingErrorDelay,
            .sensorList = std::move(sensorDefs),
            .condition = cond,
            .funcOnPresent = setFuncOnPresent};

        fanDefs.push_back(std::move(def));
    }

    return fanDefs;
}

PowerRuleState getPowerOffPowerRuleState(const json& powerOffConfig)
{
    // The state is optional and defaults to runtime
    PowerRuleState ruleState{PowerRuleState::runtime};

    if (powerOffConfig.contains("state"))
    {
        auto state = powerOffConfig.at("state").get<std::string>();
        if (state == "at_pgood")
        {
            ruleState = PowerRuleState::atPgood;
        }
        else if (state != "runtime")
        {
            auto msg = std::format("Invalid power off state entry {}", state);
            log<level::ERR>(msg.c_str());
            throw std::runtime_error(msg.c_str());
        }
    }

    return ruleState;
}

std::unique_ptr<PowerOffCause> getPowerOffCause(const json& powerOffConfig)
{
    std::unique_ptr<PowerOffCause> cause;

    if (!powerOffConfig.contains("count") || !powerOffConfig.contains("cause"))
    {
        const auto msg =
            "Missing 'count' or 'cause' entries in power off config";
        log<level::ERR>(msg);
        throw std::runtime_error(msg);
    }

    auto count = powerOffConfig.at("count").get<size_t>();
    auto powerOffCause = powerOffConfig.at("cause").get<std::string>();

    const std::map<std::string, std::function<std::unique_ptr<PowerOffCause>()>>
        causes{
            {"missing_fan_frus",
             [count]() { return std::make_unique<MissingFanFRUCause>(count); }},
            {"nonfunc_fan_rotors",
             [count]() {
                 return std::make_unique<NonfuncFanRotorCause>(count);
             }},
            {"fan_frus_with_nonfunc_rotors", [count]() {
                 return std::make_unique<FanFRUsWithNonfuncRotorsCause>(count);
             }}};

    auto it = causes.find(powerOffCause);
    if (it != causes.end())
    {
        cause = it->second();
    }
    else
    {
        auto msg =
            std::format("Invalid power off cause {} in power off config JSON",
                        powerOffCause);
        log<level::ERR>(msg.c_str());
        throw std::runtime_error(msg.c_str());
    }

    return cause;
}

std::unique_ptr<PowerOffAction>
    getPowerOffAction(const json& powerOffConfig,
                      std::shared_ptr<PowerInterfaceBase>& powerInterface,
                      PowerOffAction::PrePowerOffFunc& func)
{
    std::unique_ptr<PowerOffAction> action;
    if (!powerOffConfig.contains("type"))
    {
        const auto msg = "Missing 'type' entry in power off config";
        log<level::ERR>(msg);
        throw std::runtime_error(msg);
    }

    auto type = powerOffConfig.at("type").get<std::string>();

    if (((type == "hard") || (type == "soft")) &&
        !powerOffConfig.contains("delay"))
    {
        const auto msg = "Missing 'delay' entry in power off config";
        log<level::ERR>(msg);
        throw std::runtime_error(msg);
    }
    else if ((type == "epow") &&
             (!powerOffConfig.contains("service_mode_delay") ||
              !powerOffConfig.contains("meltdown_delay")))
    {
        const auto msg = "Missing 'service_mode_delay' or 'meltdown_delay' "
                         "entry in power off config";
        log<level::ERR>(msg);
        throw std::runtime_error(msg);
    }

    if (type == "hard")
    {
        action = std::make_unique<HardPowerOff>(
            powerOffConfig.at("delay").get<uint32_t>(), powerInterface, func);
    }
    else if (type == "soft")
    {
        action = std::make_unique<SoftPowerOff>(
            powerOffConfig.at("delay").get<uint32_t>(), powerInterface, func);
    }
    else if (type == "epow")
    {
        action = std::make_unique<EpowPowerOff>(
            powerOffConfig.at("service_mode_delay").get<uint32_t>(),
            powerOffConfig.at("meltdown_delay").get<uint32_t>(), powerInterface,
            func);
    }
    else
    {
        auto msg =
            std::format("Invalid 'type' entry {} in power off config", type);
        log<level::ERR>(msg.c_str());
        throw std::runtime_error(msg.c_str());
    }

    return action;
}

std::vector<std::unique_ptr<PowerOffRule>> getPowerOffRules(
    const json& obj, std::shared_ptr<PowerInterfaceBase>& powerInterface,
    PowerOffAction::PrePowerOffFunc& func)
{
    std::vector<std::unique_ptr<PowerOffRule>> rules;

    if (!(obj.contains("fault_handling") &&
          obj.at("fault_handling").contains("power_off_config")))
    {
        return rules;
    }

    for (const auto& config : obj.at("fault_handling").at("power_off_config"))
    {
        auto state = getPowerOffPowerRuleState(config);
        auto cause = getPowerOffCause(config);
        auto action = getPowerOffAction(config, powerInterface, func);

        auto rule = std::make_unique<PowerOffRule>(
            std::move(state), std::move(cause), std::move(action));
        rules.push_back(std::move(rule));
    }

    return rules;
}

std::optional<size_t> getNumNonfuncRotorsBeforeError(const json& obj)
{
    std::optional<size_t> num;

    if (obj.contains("fault_handling"))
    {
        // Defaults to 1 if not present inside of 'fault_handling'.
        num = obj.at("fault_handling")
                  .value("num_nonfunc_rotors_before_error", 1);
    }

    return num;
}

} // namespace phosphor::fan::monitor
