#include "host_monitor_app.hpp"

#include "boot_manager.hpp"
#include "dbus_handler.hpp"
#include "utils.hpp"

#include <fmt/printf.h>

#include <boost/container/flat_map.hpp>
#include <sdbusplus/bus.hpp>
#include <sdbusplus/bus/match.hpp>
#include <sdbusplus/message.hpp>

#include <memory>
#include <string>
#include <string_view>
#include <variant>

namespace boot_time_monitor
{

using BasicVariantType =
    std::variant<std::vector<std::string>, std::string, int64_t, uint64_t,
                 double, int32_t, uint32_t, int16_t, uint16_t, uint8_t, bool>;

constexpr std::string_view kHostService = "xyz.openbmc_project.State.Host";
constexpr std::string_view kHostPath = "/xyz/openbmc_project/state/host0";
constexpr std::string_view kHostIface = "xyz.openbmc_project.State.Host";
constexpr std::string_view kHostProperty = "CurrentHostState";

constexpr std::string_view kHostStateRunning =
    "xyz.openbmc_project.State.Host.HostState.Running";
constexpr std::string_view kHostStateOff =
    "xyz.openbmc_project.State.Host.HostState.Off";

constexpr std::string_view kOSStatusService =
    "xyz.openbmc_project.State.OperatingSystem";
constexpr std::string_view kOSStatusPath = "/xyz/openbmc_project/state/os";
constexpr std::string_view kOSStatusIface =
    "xyz.openbmc_project.State.OperatingSystem.Status";
constexpr std::string_view kOSStatusProperty = "OperatingSystemState";

constexpr std::string_view kOSStatusStandby = "Standby";
constexpr std::string_view kOSStatusInactivate = "Inactive";

HostMonitorApp::HostMonitorApp(sdbusplus::bus::bus& bus, uint32_t hostNum) :
    kNodeName(std::string{"host"} + std::to_string(hostNum)),
    kObjPath(std::string{"/xyz/openbmc_project/time/boot/"} + kNodeName),
    objManager(bus, kObjPath.c_str())
{
    util = std::make_shared<Util>();
    cpCSV = std::make_shared<FileUtil>(util->getCPPath(kNodeName, false));
    durCSV = std::make_shared<FileUtil>(util->getDurPath(kNodeName, false));
    bootManager = std::make_shared<BootManager>(util, cpCSV, durCSV);
    dbusHandler = std::make_shared<DbusHandler>(bus, kObjPath.data(),
                                                bootManager, util);
    // Initialize preHostState
    static std::string preHostState;
    auto method = bus.new_method_call(kHostService.data(), kHostPath.data(),
                                      "org.freedesktop.DBus.Properties", "Get");
    method.append(kHostIface.data(), kHostProperty.data());
    BasicVariantType result;
    try
    {
        bus.call(method).read(result);
        preHostState = std::get<std::string>(result);
    }
    catch (const sdbusplus::exception::SdBusError& e)
    {
        fmt::print(stderr, "[{}] Failed to get `CurrentHostState`. ERROR={}\n",
                   __FUNCTION__, e.what());
        fmt::print(
            stderr,
            "[{}] Initialized `preHostState` to empty string as default value\n",
            __FUNCTION__);
    }

    powerMatcher = std::make_unique<sdbusplus::bus::match::match>(
        bus,
        sdbusplus::bus::match::rules::propertiesChanged(kHostPath.data(),
                                                        kHostIface.data()),
        [this](sdbusplus::message::message& message) {
        constexpr std::string_view kS0 = "Off";
        constexpr std::string_view kS5 = "To_Off";

        std::string objectName;
        boost::container::flat_map<
            std::string,
            std::variant<std::string, bool, int64_t, uint64_t, double>>
            values;
        message.read(objectName, values);

        auto findState = values.find(kHostProperty.data());
        if (findState != values.end())
        {
            const std::string curHostState =
                std::get<std::string>(findState->second);
            fmt::print(
                stderr,
                "[powerMatcher] CurrentHostState has changed from {} to {}\n",
                preHostState, curHostState);
            if (preHostState == kHostStateOff &&
                curHostState == kHostStateRunning)
            {
                bootManager->setCheckpoint(kS0.data(), 0, 0);
            }
            else if (preHostState == kHostStateRunning &&
                     curHostState == kHostStateOff)
            {
                bootManager->setCheckpoint(kS5.data(), 0, 0);
            }
            preHostState = curHostState;
        }
        });

    // Initialize preOSStatus
    static std::string preOSStatus;
    method = bus.new_method_call(kOSStatusService.data(), kOSStatusPath.data(),
                                 "org.freedesktop.DBus.Properties", "Get");
    method.append(kOSStatusIface.data(), kOSStatusProperty.data());
    try
    {
        bus.call(method).read(result);
        preOSStatus = std::get<std::string>(result);
    }
    catch (const sdbusplus::exception::SdBusError& e)
    {
        fmt::print(stderr,
                   "[{}] Failed to get `OperatingSystemState`. ERROR={}\n",
                   __FUNCTION__, e.what());
        fmt::print(
            stderr,
            "[{}] Initialized `preOSStatus` to empty string as default value\n",
            __FUNCTION__);
    }

    osStatusMatcher = std::make_unique<sdbusplus::bus::match::match>(
        bus,
        sdbusplus::bus::match::rules::propertiesChanged(kOSStatusPath.data(),
                                                        kOSStatusIface.data()),
        [this](sdbusplus::message::message& message) {
        constexpr std::string_view kStandby2Inactive = "CPU_reset";
        constexpr std::string_view kInactive2Standby = "Firmware";

        std::string objectName;
        boost::container::flat_map<
            std::string,
            std::variant<std::string, bool, int64_t, uint64_t, double>>
            values;
        message.read(objectName, values);

        auto findState = values.find(kOSStatusProperty.data());
        if (findState != values.end())
        {
            const std::string curOSStatus =
                std::get<std::string>(findState->second);

            fmt::print(
                stderr,
                "[osStatusMatcher] curOSStatus has changed from {} to {}\n",
                preOSStatus, curOSStatus);
            if (preOSStatus == kOSStatusInactivate &&
                curOSStatus == kOSStatusStandby)
            {
                bootManager->setCheckpoint(kInactive2Standby.data(), 0, 0);
            }
            else if (preOSStatus == kOSStatusStandby &&
                     curOSStatus == kOSStatusInactivate)
            {
                bootManager->setCheckpoint(kStandby2Inactive.data(), 0, 0);
            }
            preOSStatus = curOSStatus;
        }
    });
}

} // namespace boot_time_monitor
