#include "trigger_actions.hpp"

#include "messages/update_report_ind.hpp"
#include "types/trigger_types.hpp"
#include "utils/clock.hpp"
#include "utils/messanger.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 '" + thresholdName + "' of trigger '" +
                      triggerId + "' is crossed on sensor " + sensorName +
                      ", recorded value: " + std::to_string(value) +
                      ", crossing direction: " + direction +
                      ", timestamp: " + timestampToString(timestamp);

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

const char* LogToRedfishEventLog::getRedfishMessageId() const
{
    switch (type)
    {
        case ::numeric::Type::upperCritical:
            return redfish_message_ids::TriggerNumericCritical;
        case ::numeric::Type::lowerCritical:
            return redfish_message_ids::TriggerNumericCritical;
        case ::numeric::Type::upperWarning:
            return redfish_message_ids::TriggerNumericWarning;
        case ::numeric::Type::lowerWarning:
            return redfish_message_ids::TriggerNumericWarning;
    }
    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);
    std::string thresholdName = ::numeric::typeToString(type);
    auto direction = getDirection(value, threshold);
    auto timestampStr = timestampToString(timestamp);

    phosphor::logging::log<phosphor::logging::level::INFO>(
        "Logging numeric trigger action to Redfish Event Log.",
        phosphor::logging::entry("REDFISH_MESSAGE_ID=%s",
                                 getRedfishMessageId()),
        phosphor::logging::entry("REDFISH_MESSAGE_ARGS=%s,%s,%s,%f,%s,%s",
                                 thresholdName.c_str(), triggerId.c_str(),
                                 sensorName.c_str(), value, direction,
                                 timestampStr.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: " + ::discrete::severityToString(severity) +
                      ", timestamp: " + timestampToString(timestamp);

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

const char* LogToRedfishEventLog::getRedfishMessageId() const
{
    switch (severity)
    {
        case ::discrete::Severity::ok:
            return redfish_message_ids::TriggerDiscreteOK;
        case ::discrete::Severity::warning:
            return redfish_message_ids::TriggerDiscreteWarning;
        case ::discrete::Severity::critical:
            return redfish_message_ids::TriggerDiscreteCritical;
    }
    throw std::runtime_error("Invalid severity");
}

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);
    auto timestampStr = timestampToString(timestamp);

    phosphor::logging::log<phosphor::logging::level::INFO>(
        "Logging discrete trigger action to Redfish Event Log.",
        phosphor::logging::entry("REDFISH_MESSAGE_ID=%s",
                                 getRedfishMessageId()),
        phosphor::logging::entry("REDFISH_MESSAGE_ARGS=%s,%s,%s,%s,%s",
                                 thresholdNameIn->get().c_str(),
                                 triggerId.c_str(), sensorName.c_str(),
                                 value.c_str(), timestampStr.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>(severity));
                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);
    auto timestampStr = timestampToString(timestamp);

    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::TriggerDiscreteOK),
        phosphor::logging::entry("REDFISH_MESSAGE_ARGS=%s,%s,%s,%s,%s",
                                 "OnChange", triggerId.c_str(),
                                 sensorName.c_str(), value.c_str(),
                                 timestampStr.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
