#include "config.h"

#include "host_state_manager.hpp"
#include "settings.hpp"
#include "utils.hpp"
#include "xyz/openbmc_project/Common/error.hpp"
#include "xyz/openbmc_project/Control/Power/RestorePolicy/server.hpp"

#include <getopt.h>
#include <systemd/sd-bus.h>

#include <phosphor-logging/elog-errors.hpp>
#include <phosphor-logging/lg2.hpp>
#include <sdbusplus/exception.hpp>
#include <sdbusplus/server.hpp>

#include <iostream>
#include <map>
#include <string>

namespace phosphor
{
namespace state
{
namespace manager
{

PHOSPHOR_LOG2_USING;

using namespace phosphor::logging;
using namespace sdbusplus::xyz::openbmc_project::Common::Error;
using namespace sdbusplus::xyz::openbmc_project::Control::Power::server;

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

int main(int argc, char** argv)
{
    using namespace phosphor::logging;

    std::string hostPath = "/xyz/openbmc_project/state/host0";
    int arg;
    int optIndex = 0;

    static struct option longOpts[] = {{"host", required_argument, 0, 'h'},
                                       {0, 0, 0, 0}};

    while ((arg = getopt_long(argc, argv, "h:", longOpts, &optIndex)) != -1)
    {
        switch (arg)
        {
            case 'h':
                hostPath =
                    std::string("/xyz/openbmc_project/state/host") + optarg;
                break;
            default:
                break;
        }
    }

    auto bus = sdbusplus::bus::new_default();

    using namespace settings;
    Objects settings(bus);

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

    // This application is only run if chassis power is off

    // If the BMC was rebooted due to a user initiated pinhole reset, do not
    // implement any power restore policies
    auto bmcRebootCause = phosphor::state::manager::utils::getProperty(
        bus, "/xyz/openbmc_project/state/bmc0", BMC_BUSNAME, "LastRebootCause");
    if (bmcRebootCause ==
        "xyz.openbmc_project.State.BMC.RebootCause.PinholeReset")
    {
        info(
            "BMC was reset due to pinhole reset, no power restore policy will be run");
        return 0;
    }
    else if (bmcRebootCause ==
             "xyz.openbmc_project.State.BMC.RebootCause.Watchdog")
    {
        info(
            "BMC was reset due to cold reset, no power restore policy will be run");
        return 0;
    }

    /* The logic here is to first check the one-time PowerRestorePolicy setting.
     * If this property is not the default then look at the persistent
     * user setting in the non one-time object, otherwise honor the one-time
     * setting.
     */
    auto methodOneTime = bus.new_method_call(
        settings.service(settings.powerRestorePolicy, powerRestoreIntf).c_str(),
        settings.powerRestorePolicyOneTime.c_str(),
        "org.freedesktop.DBus.Properties", "Get");
    methodOneTime.append(powerRestoreIntf, "PowerRestorePolicy");

    auto methodUserSetting = bus.new_method_call(
        settings.service(settings.powerRestorePolicy, powerRestoreIntf).c_str(),
        settings.powerRestorePolicy.c_str(), "org.freedesktop.DBus.Properties",
        "Get");
    methodUserSetting.append(powerRestoreIntf, "PowerRestorePolicy");

    std::variant<std::string> result;
    try
    {
        auto reply = bus.call(methodOneTime);
        reply.read(result);
        auto powerPolicy = std::get<std::string>(result);

        if (RestorePolicy::Policy::None ==
            RestorePolicy::convertPolicyFromString(powerPolicy))
        {
            // one_time is set to None so use the customer setting
            info("One time not set, check user setting of power policy");
            auto reply = bus.call(methodUserSetting);
            reply.read(result);
            powerPolicy = std::get<std::string>(result);
        }
        else
        {
            // one_time setting was set so we're going to use it. Reset it
            // to default for next time.
            info("One time set, use it and reset to default");
            phosphor::state::manager::utils::setProperty(
                bus, settings.powerRestorePolicyOneTime.c_str(),
                powerRestoreIntf, "PowerRestorePolicy",
                convertForMessage(RestorePolicy::Policy::None));
        }

        info("Host power is off, processing power policy {POWER_POLICY}",
             "POWER_POLICY", powerPolicy);

        if (RestorePolicy::Policy::AlwaysOn ==
            RestorePolicy::convertPolicyFromString(powerPolicy))
        {
            info("power_policy=ALWAYS_POWER_ON, powering host on");
            phosphor::state::manager::utils::setProperty(
                bus, hostPath, HOST_BUSNAME, "RestartCause",
                convertForMessage(
                    server::Host::RestartCause::PowerPolicyAlwaysOn));
            phosphor::state::manager::utils::setProperty(
                bus, hostPath, HOST_BUSNAME, "RequestedHostTransition",
                convertForMessage(server::Host::Transition::On));
        }
        else if (RestorePolicy::Policy::AlwaysOff ==
                 RestorePolicy::convertPolicyFromString(powerPolicy))
        {
            info("power_policy=ALWAYS_POWER_OFF, set requested state to off");
            // Read last requested state and re-request it to execute it
            auto hostReqState = phosphor::state::manager::utils::getProperty(
                bus, hostPath, HOST_BUSNAME, "RequestedHostTransition");
            if (hostReqState == convertForMessage(server::Host::Transition::On))
            {
                phosphor::state::manager::utils::setProperty(
                    bus, hostPath, HOST_BUSNAME, "RequestedHostTransition",
                    convertForMessage(server::Host::Transition::Off));
            }
        }
        else if (RestorePolicy::Policy::Restore ==
                 RestorePolicy::convertPolicyFromString(powerPolicy))
        {
            info("power_policy=RESTORE, restoring last state");
            // Read last requested state and re-request it to execute it
            auto hostReqState = phosphor::state::manager::utils::getProperty(
                bus, hostPath, HOST_BUSNAME, "RequestedHostTransition");
            if (hostReqState == convertForMessage(server::Host::Transition::On))
            {
                phosphor::state::manager::utils::setProperty(
                    bus, hostPath, HOST_BUSNAME, "RestartCause",
                    convertForMessage(
                        server::Host::RestartCause::PowerPolicyPreviousState));
                phosphor::state::manager::utils::setProperty(
                    bus, hostPath, HOST_BUSNAME, "RequestedHostTransition",
                    hostReqState);
            }
        }
    }
    catch (const sdbusplus::exception::exception& e)
    {
        error("Error in PowerRestorePolicy Get: {ERROR}", "ERROR", e);
        elog<InternalFailure>();
    }

    return 0;
}
