#include "trigger_actions.hpp"

#include "messages/update_report_ind.hpp"
#include "types/trigger_types.hpp"
#include "utils/clock.hpp"
#include "utils/messanger.hpp"
#include "utils/to_short_enum.hpp"

#include <phosphor-logging/log.hpp>

#include <ctime>
#include <iomanip>
#include <sstream>

namespace action
{

namespace
{
std::string timestampToString(Milliseconds timestamp)
{
    std::time_t t = static_cast<time_t>(
        std::chrono::duration_cast<std::chrono::seconds>(timestamp).count());
    std::stringstream ss;
    ss << std::put_time(std::gmtime(&t), "%FT%T.") << std::setw(3)
       << std::setfill('0') << timestamp.count() % 1000 << 'Z';
    return ss.str();
}
} // namespace

namespace numeric
{

static const char* getDirection(double value, double threshold)
{
    if (value < threshold)
    {
        return "decreasing";
    }
    if (value > threshold)
    {
        return "increasing";
    }
    throw std::runtime_error("Invalid value");
}

void LogToJournal::commit(
    const std::string& triggerId, const ThresholdName thresholdNameInIn,
    const std::string& sensorName, const Milliseconds timestamp,
    const TriggerValue triggerValue)
{
    double value = std::get<double>(triggerValue);
    std::string thresholdName = ::numeric::typeToString(type);
    auto direction = getDirection(value, threshold);

    std::string msg =
        "Numeric threshold '" + std::string(utils::toShortEnum(thresholdName)) +
        "' of trigger '" + triggerId + "' is crossed on sensor " + sensorName +
        ", recorded value: " + std::to_string(value) +
        ", crossing direction: " + std::string(utils::toShortEnum(direction)) +
        ", timestamp: " + timestampToString(timestamp);

    phosphor::logging::log<phosphor::logging::level::INFO>(msg.c_str());
}

const char* LogToRedfishEventLog::getRedfishMessageId(const double value) const
{
    std::string direction(getDirection(value, threshold));

    if (direction == "decreasing")
    {
        switch (type)
        {
            case ::numeric::Type::upperCritical:
                return redfish_message_ids::TriggerNumericBelowUpperCritical;
            case ::numeric::Type::lowerCritical:
                return redfish_message_ids::TriggerNumericBelowLowerCritical;
            case ::numeric::Type::upperWarning:
                return redfish_message_ids::TriggerNumericReadingNormal;
            case ::numeric::Type::lowerWarning:
                return redfish_message_ids::TriggerNumericBelowLowerWarning;
        }
    }

    if (direction == "increasing")
    {
        switch (type)
        {
            case ::numeric::Type::upperCritical:
                return redfish_message_ids::TriggerNumericAboveUpperCritical;
            case ::numeric::Type::lowerCritical:
                return redfish_message_ids::TriggerNumericAboveLowerCritical;
            case ::numeric::Type::upperWarning:
                return redfish_message_ids::TriggerNumericAboveUpperWarning;
            case ::numeric::Type::lowerWarning:
                return redfish_message_ids::TriggerNumericReadingNormal;
        }
    }

    throw std::runtime_error("Invalid type");
}

void LogToRedfishEventLog::commit(
    const std::string& triggerId, const ThresholdName thresholdNameInIn,
    const std::string& sensorName, const Milliseconds timestamp,
    const TriggerValue triggerValue)
{
    double value = std::get<double>(triggerValue);
    auto messageId = getRedfishMessageId(value);

    if (messageId == redfish_message_ids::TriggerNumericReadingNormal)
    {
        phosphor::logging::log<phosphor::logging::level::INFO>(
            "Logging numeric trigger action to Redfish Event Log.",
            phosphor::logging::entry("REDFISH_MESSAGE_ID=%s", messageId),
            phosphor::logging::entry("REDFISH_MESSAGE_ARGS=%s,%f,%s",
                                     sensorName.c_str(), value,
                                     triggerId.c_str()));
    }
    else
    {
        phosphor::logging::log<phosphor::logging::level::INFO>(
            "Logging numeric trigger action to Redfish Event Log.",
            phosphor::logging::entry("REDFISH_MESSAGE_ID=%s", messageId),
            phosphor::logging::entry("REDFISH_MESSAGE_ARGS=%s,%f,%f,%s",
                                     sensorName.c_str(), value, threshold,
                                     triggerId.c_str()));
    }
}

void fillActions(
    std::vector<std::unique_ptr<interfaces::TriggerAction>>& actionsIf,
    const std::vector<TriggerAction>& ActionsEnum, ::numeric::Type type,
    double thresholdValue, boost::asio::io_context& ioc,
    const std::shared_ptr<std::vector<std::string>>& reportIds)
{
    actionsIf.reserve(ActionsEnum.size());
    for (auto actionType : ActionsEnum)
    {
        switch (actionType)
        {
            case TriggerAction::LogToJournal:
            {
                actionsIf.emplace_back(
                    std::make_unique<LogToJournal>(type, thresholdValue));
                break;
            }
            case TriggerAction::LogToRedfishEventLog:
            {
                actionsIf.emplace_back(std::make_unique<LogToRedfishEventLog>(
                    type, thresholdValue));
                break;
            }
            case TriggerAction::UpdateReport:
            {
                actionsIf.emplace_back(
                    std::make_unique<UpdateReport>(ioc, reportIds));
                break;
            }
        }
    }
}

} // namespace numeric

namespace discrete
{

void LogToJournal::commit(
    const std::string& triggerId, const ThresholdName thresholdNameIn,
    const std::string& sensorName, const Milliseconds timestamp,
    const TriggerValue triggerValue)
{
    auto value = std::get<std::string>(triggerValue);

    std::string msg =
        "Discrete condition '" + thresholdNameIn->get() + "' of trigger '" +
        triggerId + "' is met on sensor " + sensorName +
        ", recorded value: " + value + ", severity: " +
        std::string(utils::toShortEnum(utils::enumToString(severity))) +
        ", timestamp: " + timestampToString(timestamp);

    phosphor::logging::log<phosphor::logging::level::INFO>(msg.c_str());
}

void LogToRedfishEventLog::commit(
    const std::string& triggerId, const ThresholdName thresholdNameIn,
    const std::string& sensorName, const Milliseconds timestamp,
    const TriggerValue triggerValue)
{
    auto value = std::get<std::string>(triggerValue);

    phosphor::logging::log<phosphor::logging::level::INFO>(
        "Logging discrete trigger action to Redfish Event Log.",
        phosphor::logging::entry(
            "REDFISH_MESSAGE_ID=%s",
            redfish_message_ids::TriggerDiscreteConditionMet),
        phosphor::logging::entry("REDFISH_MESSAGE_ARGS=%s,%s,%s",
                                 sensorName.c_str(), value.c_str(),
                                 triggerId.c_str()));
}

void fillActions(
    std::vector<std::unique_ptr<interfaces::TriggerAction>>& actionsIf,
    const std::vector<TriggerAction>& ActionsEnum,
    ::discrete::Severity severity, boost::asio::io_context& ioc,
    const std::shared_ptr<std::vector<std::string>>& reportIds)
{
    actionsIf.reserve(ActionsEnum.size());
    for (auto actionType : ActionsEnum)
    {
        switch (actionType)
        {
            case TriggerAction::LogToJournal:
            {
                actionsIf.emplace_back(
                    std::make_unique<LogToJournal>(severity));
                break;
            }
            case TriggerAction::LogToRedfishEventLog:
            {
                actionsIf.emplace_back(
                    std::make_unique<LogToRedfishEventLog>());
                break;
            }
            case TriggerAction::UpdateReport:
            {
                actionsIf.emplace_back(
                    std::make_unique<UpdateReport>(ioc, reportIds));
                break;
            }
        }
    }
}

namespace onChange
{
void LogToJournal::commit(
    const std::string& triggerId, const ThresholdName thresholdNameIn,
    const std::string& sensorName, const Milliseconds timestamp,
    const TriggerValue triggerValue)
{
    auto value = triggerValueToString(triggerValue);
    std::string msg =
        "Discrete condition 'OnChange' of trigger '" + triggerId +
        "' is met on sensor: " + sensorName + ", recorded value: " + value +
        ", timestamp: " + timestampToString(timestamp);

    phosphor::logging::log<phosphor::logging::level::INFO>(msg.c_str());
}

void LogToRedfishEventLog::commit(
    const std::string& triggerId, const ThresholdName thresholdNameIn,
    const std::string& sensorName, const Milliseconds timestamp,
    const TriggerValue triggerValue)
{
    auto value = triggerValueToString(triggerValue);

    phosphor::logging::log<phosphor::logging::level::INFO>(
        "Logging onChange discrete trigger action to Redfish Event Log.",
        phosphor::logging::entry(
            "REDFISH_MESSAGE_ID=%s",
            redfish_message_ids::TriggerDiscreteConditionMet),
        phosphor::logging::entry("REDFISH_MESSAGE_ARGS=%s,%s,%s",
                                 sensorName.c_str(), value.c_str(),
                                 triggerId.c_str()));
}

void fillActions(
    std::vector<std::unique_ptr<interfaces::TriggerAction>>& actionsIf,
    const std::vector<TriggerAction>& ActionsEnum, boost::asio::io_context& ioc,
    const std::shared_ptr<std::vector<std::string>>& reportIds)
{
    actionsIf.reserve(ActionsEnum.size());
    for (auto actionType : ActionsEnum)
    {
        switch (actionType)
        {
            case TriggerAction::LogToJournal:
            {
                actionsIf.emplace_back(std::make_unique<LogToJournal>());
                break;
            }
            case TriggerAction::LogToRedfishEventLog:
            {
                actionsIf.emplace_back(
                    std::make_unique<LogToRedfishEventLog>());
                break;
            }
            case TriggerAction::UpdateReport:
            {
                actionsIf.emplace_back(
                    std::make_unique<UpdateReport>(ioc, reportIds));
                break;
            }
        }
    }
}
} // namespace onChange
} // namespace discrete

void UpdateReport::commit(
    const std::string& triggerId, const ThresholdName thresholdNameIn,
    const std::string& sensorName, const Milliseconds timestamp,
    const TriggerValue triggerValue)
{
    if (reportIds->empty())
    {
        return;
    }

    utils::Messanger messanger(ioc);
    messanger.send(messages::UpdateReportInd{*reportIds});
}
} // namespace action
