#include <iostream>
#include <map>
#include <string>
#include <config.h>
#include <systemd/sd-bus.h>
#include <sdbusplus/server.hpp>
#include <phosphor-logging/log.hpp>
#include "chassis_state_manager.hpp"
#include "host_state_manager.hpp"

namespace phosphor
{
namespace state
{
namespace manager
{

using namespace phosphor::logging;

constexpr auto MAPPER_BUSNAME = "xyz.openbmc_project.ObjectMapper";
constexpr auto MAPPER_PATH = "/xyz/openbmc_project/object_mapper";
constexpr auto MAPPER_INTERFACE = "xyz.openbmc_project.ObjectMapper";

constexpr auto PROPERTY_INTERFACE = "org.freedesktop.DBus.Properties";

constexpr auto HOST_PATH = "/xyz/openbmc_project/state/host0";

constexpr auto SETTINGS_PATH = "/org/openbmc/settings/host0";
constexpr auto SETTINGS_INTERFACE = "org.openbmc.settings.Host";

constexpr auto CHASSIS_PATH = "/xyz/openbmc_project/state/chassis0";

std::string getService(sdbusplus::bus::bus& bus, std::string path,
                       std::string interface)
{
    auto mapper = bus.new_method_call(MAPPER_BUSNAME,
                                      MAPPER_PATH,
                                      MAPPER_INTERFACE,
                                      "GetObject");

    mapper.append(path, std::vector<std::string>({interface}));
    auto mapperResponseMsg = bus.call(mapper);

    if (mapperResponseMsg.is_method_error())
    {
        log<level::ERR>("Error in mapper call",
                        entry("PATH=%s", path.c_str()),
                        entry("INTERFACE=%s", interface.c_str()));
        throw std::runtime_error("Error in mapper call");
    }

    std::map<std::string, std::vector<std::string>> mapperResponse;
    mapperResponseMsg.read(mapperResponse);
    if (mapperResponse.empty())
    {
        log<level::ERR>("Error reading mapper response",
                        entry("PATH=%s", path.c_str()),
                        entry("INTERFACE=%s", interface.c_str()));
        throw std::runtime_error("Error reading mapper response");
    }

    return mapperResponse.begin()->first;
}

std::string getProperty(sdbusplus::bus::bus& bus, std::string path,
                        std::string interface, std::string propertyName)
{
    sdbusplus::message::variant<std::string> property;
    std::string service = getService(bus, path, interface);

    auto method = bus.new_method_call(service.c_str(),
                                      path.c_str(),
                                      PROPERTY_INTERFACE,
                                      "Get");

    method.append(interface, propertyName);
    auto reply = bus.call(method);

    if (reply.is_method_error())
    {
        log<level::ERR>("Error in property Get",
                        entry("PROPERTY=%s", propertyName.c_str()));
        throw std::runtime_error("Error in property Get");
    }

    reply.read(property);

    if (sdbusplus::message::variant_ns::get<std::string>(property).empty())
    {
        log<level::ERR>("Error reading property response",
                        entry("PROPERTY=%s", propertyName.c_str()));
        throw std::runtime_error("Error reading property response");
    }

    return sdbusplus::message::variant_ns::get<std::string>(property);
}

void setProperty(sdbusplus::bus::bus& bus, std::string path,
                 std::string interface, std::string property, std::string value)
{
    sdbusplus::message::variant<std::string> variantValue = value;
    std::string service = getService(bus, path, interface);

    auto method = bus.new_method_call(service.c_str(),
                                      path.c_str(),
                                      PROPERTY_INTERFACE,
                                      "Set");

    method.append(interface, property, variantValue);
    bus.call_noreply(method);

    return;
}

} // namespace manager
} // namespace state
} // namepsace phosphor

int main()
{
    auto bus = sdbusplus::bus::new_default();

    using namespace phosphor::state::manager;
    namespace server = sdbusplus::xyz::openbmc_project::State::server;

    std::string currentPowerState = getProperty(bus, CHASSIS_PATH,
                                                CHASSIS_BUSNAME,
                                                "CurrentPowerState");

    if(currentPowerState == convertForMessage(server::Chassis::PowerState::Off))
    {
        std::string power_policy = getProperty(bus, SETTINGS_PATH,
                                               SETTINGS_INTERFACE,
                                               "power_policy");

        log<level::INFO>("Host power is off, checking power policy",
                         entry("POWER_POLICY=%s", power_policy.c_str()));

        if (power_policy == "ALWAYS_POWER_ON")
        {
            log<level::INFO>("power_policy=ALWAYS_POWER_ON, powering host on");
            setProperty(bus, HOST_PATH, HOST_BUSNAME,
                        "RequestedHostTransition",
                        convertForMessage(server::Host::Transition::On));
        }

    }

    return 0;
}
