/*
// Copyright (c) 2018-2019 Intel Corporation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
*/
#include "i2c.hpp"

#include <sys/sysinfo.h>
#include <systemd/sd-journal.h>

#include <boost/asio/posix/stream_descriptor.hpp>
#include <boost/container/flat_map.hpp>
#include <filesystem>
#include <fstream>
#include <gpiod.hpp>
#include <iostream>
#include <sdbusplus/asio/object_server.hpp>
#include <string_view>

namespace power_control
{
static boost::asio::io_service io;
std::shared_ptr<sdbusplus::asio::connection> conn;
static std::shared_ptr<sdbusplus::asio::dbus_interface> hostIface;
static std::shared_ptr<sdbusplus::asio::dbus_interface> chassisIface;
static std::shared_ptr<sdbusplus::asio::dbus_interface> powerButtonIface;
static std::shared_ptr<sdbusplus::asio::dbus_interface> resetButtonIface;
static std::shared_ptr<sdbusplus::asio::dbus_interface> nmiButtonIface;
static std::shared_ptr<sdbusplus::asio::dbus_interface> osIface;
static std::shared_ptr<sdbusplus::asio::dbus_interface> idButtonIface;

static gpiod::line powerButtonMask;
static gpiod::line resetButtonMask;
static bool nmiButtonMasked = false;
static bool resetInProgress = false;

const static constexpr int powerPulseTimeMs = 200;
const static constexpr int forceOffPulseTimeMs = 15000;
const static constexpr int resetPulseTimeMs = 500;
const static constexpr int powerCycleTimeMs = 1000;
const static constexpr int sioPowerGoodWatchdogTimeMs = 1000;
const static constexpr int psPowerOKWatchdogTimeMs = 8000;
const static constexpr int gracefulPowerOffTimeMs = 60000;
const static constexpr int buttonMaskTimeMs = 60000;
const static constexpr int powerOffSaveTimeMs = 7000;

const static std::filesystem::path powerControlDir = "/var/lib/power-control";
const static constexpr std::string_view powerStateFile = "power-state";

static bool nmiEnabled = true;
static constexpr const char* nmiOutName = "NMI_OUT";
static constexpr const char* powerOutName = "POWER_OUT";
static constexpr const char* resetOutName = "RESET_OUT";

// Timers
// Time holding GPIOs asserted
static boost::asio::steady_timer gpioAssertTimer(io);
// Time between off and on during a power cycle
static boost::asio::steady_timer powerCycleTimer(io);
// Time OS gracefully powering off
static boost::asio::steady_timer gracefulPowerOffTimer(io);
// Time power supply power OK assertion on power-on
static boost::asio::steady_timer psPowerOKWatchdogTimer(io);
// Time SIO power good assertion on power-on
static boost::asio::steady_timer sioPowerGoodWatchdogTimer(io);
// Time power-off state save for power loss tracking
static boost::asio::steady_timer powerStateSaveTimer(io);
// POH timer
static boost::asio::steady_timer pohCounterTimer(io);

// GPIO Lines and Event Descriptors
static gpiod::line psPowerOKLine;
static boost::asio::posix::stream_descriptor psPowerOKEvent(io);
static gpiod::line sioPowerGoodLine;
static boost::asio::posix::stream_descriptor sioPowerGoodEvent(io);
static gpiod::line sioOnControlLine;
static boost::asio::posix::stream_descriptor sioOnControlEvent(io);
static gpiod::line sioS5Line;
static boost::asio::posix::stream_descriptor sioS5Event(io);
static gpiod::line powerButtonLine;
static boost::asio::posix::stream_descriptor powerButtonEvent(io);
static gpiod::line resetButtonLine;
static boost::asio::posix::stream_descriptor resetButtonEvent(io);
static gpiod::line nmiButtonLine;
static boost::asio::posix::stream_descriptor nmiButtonEvent(io);
static gpiod::line idButtonLine;
static boost::asio::posix::stream_descriptor idButtonEvent(io);
static gpiod::line postCompleteLine;
static boost::asio::posix::stream_descriptor postCompleteEvent(io);
static gpiod::line nmiOutLine;

static constexpr uint8_t beepPowerFail = 8;

static void beep(const uint8_t& beepPriority)
{
    std::cerr << "Beep with priority: " << (unsigned)beepPriority << "\n";

    conn->async_method_call(
        [](boost::system::error_code ec) {
            if (ec)
            {
                std::cerr << "beep returned error with "
                             "async_method_call (ec = "
                          << ec << ")\n";
                return;
            }
        },
        "xyz.openbmc_project.BeepCode", "/xyz/openbmc_project/BeepCode",
        "xyz.openbmc_project.BeepCode", "Beep", uint8_t(beepPriority));
}

enum class PowerState
{
    on,
    waitForPSPowerOK,
    waitForSIOPowerGood,
    failedTransitionToOn,
    off,
    transitionToOff,
    gracefulTransitionToOff,
    cycleOff,
    transitionToCycleOff,
    gracefulTransitionToCycleOff,
};
static PowerState powerState;
static std::string getPowerStateName(PowerState state)
{
    switch (state)
    {
        case PowerState::on:
            return "On";
            break;
        case PowerState::waitForPSPowerOK:
            return "Wait for Power Supply Power OK";
            break;
        case PowerState::waitForSIOPowerGood:
            return "Wait for SIO Power Good";
            break;
        case PowerState::failedTransitionToOn:
            return "Failed Transition to On";
            break;
        case PowerState::off:
            return "Off";
            break;
        case PowerState::transitionToOff:
            return "Transition to Off";
            break;
        case PowerState::gracefulTransitionToOff:
            return "Graceful Transition to Off";
            break;
        case PowerState::cycleOff:
            return "Power Cycle Off";
            break;
        case PowerState::transitionToCycleOff:
            return "Transition to Power Cycle Off";
            break;
        case PowerState::gracefulTransitionToCycleOff:
            return "Graceful Transition to Power Cycle Off";
            break;
        default:
            return "unknown state: " + std::to_string(static_cast<int>(state));
            break;
    }
}
static void logStateTransition(const PowerState state)
{
    std::cerr << "Moving to \"" << getPowerStateName(state) << "\" state.\n";
}

enum class Event
{
    psPowerOKAssert,
    psPowerOKDeAssert,
    sioPowerGoodAssert,
    sioPowerGoodDeAssert,
    sioS5Assert,
    sioS5DeAssert,
    powerButtonPressed,
    powerCycleTimerExpired,
    psPowerOKWatchdogTimerExpired,
    sioPowerGoodWatchdogTimerExpired,
    gracefulPowerOffTimerExpired,
    powerOnRequest,
    powerOffRequest,
    powerCycleRequest,
    resetRequest,
    gracefulPowerOffRequest,
    gracefulPowerCycleRequest,
};
static std::string getEventName(Event event)
{
    switch (event)
    {
        case Event::psPowerOKAssert:
            return "power supply power OK assert";
            break;
        case Event::psPowerOKDeAssert:
            return "power supply power OK de-assert";
            break;
        case Event::sioPowerGoodAssert:
            return "SIO power good assert";
            break;
        case Event::sioPowerGoodDeAssert:
            return "SIO power good de-assert";
            break;
        case Event::sioS5Assert:
            return "SIO S5 assert";
            break;
        case Event::sioS5DeAssert:
            return "SIO S5 de-assert";
            break;
        case Event::powerButtonPressed:
            return "power button pressed";
            break;
        case Event::powerCycleTimerExpired:
            return "power cycle timer expired";
            break;
        case Event::psPowerOKWatchdogTimerExpired:
            return "power supply power OK watchdog timer expired";
            break;
        case Event::sioPowerGoodWatchdogTimerExpired:
            return "SIO power good watchdog timer expired";
            break;
        case Event::gracefulPowerOffTimerExpired:
            return "graceful power-off timer expired";
            break;
        case Event::powerOnRequest:
            return "power-on request";
            break;
        case Event::powerOffRequest:
            return "power-off request";
            break;
        case Event::powerCycleRequest:
            return "power-cycle request";
            break;
        case Event::resetRequest:
            return "reset request";
            break;
        case Event::gracefulPowerOffRequest:
            return "graceful power-off request";
            break;
        case Event::gracefulPowerCycleRequest:
            return "graceful power-cycle request";
            break;
        default:
            return "unknown event: " + std::to_string(static_cast<int>(event));
            break;
    }
}
static void logEvent(const std::string_view stateHandler, const Event event)
{
    std::cerr << stateHandler << ": " << getEventName(event)
              << " event received.\n";
}

// Power state handlers
static void powerStateOn(const Event event);
static void powerStateWaitForPSPowerOK(const Event event);
static void powerStateWaitForSIOPowerGood(const Event event);
static void powerStateFailedTransitionToOn(const Event event);
static void powerStateOff(const Event event);
static void powerStateTransitionToOff(const Event event);
static void powerStateGracefulTransitionToOff(const Event event);
static void powerStateCycleOff(const Event event);
static void powerStateTransitionToCycleOff(const Event event);
static void powerStateGracefulTransitionToCycleOff(const Event event);

static std::function<void(const Event)> getPowerStateHandler(PowerState state)
{
    switch (state)
    {
        case PowerState::on:
            return powerStateOn;
            break;
        case PowerState::waitForPSPowerOK:
            return powerStateWaitForPSPowerOK;
            break;
        case PowerState::waitForSIOPowerGood:
            return powerStateWaitForSIOPowerGood;
            break;
        case PowerState::failedTransitionToOn:
            return powerStateFailedTransitionToOn;
            break;
        case PowerState::off:
            return powerStateOff;
            break;
        case PowerState::transitionToOff:
            return powerStateTransitionToOff;
            break;
        case PowerState::gracefulTransitionToOff:
            return powerStateGracefulTransitionToOff;
            break;
        case PowerState::cycleOff:
            return powerStateCycleOff;
            break;
        case PowerState::transitionToCycleOff:
            return powerStateTransitionToCycleOff;
            break;
        case PowerState::gracefulTransitionToCycleOff:
            return powerStateGracefulTransitionToCycleOff;
            break;
        default:
            return std::function<void(const Event)>{};
            break;
    }
};

static void sendPowerControlEvent(const Event event)
{
    std::function<void(const Event)> handler = getPowerStateHandler(powerState);
    if (handler == nullptr)
    {
        std::cerr << "Failed to find handler for power state: "
                  << static_cast<int>(powerState) << "\n";
        return;
    }
    handler(event);
}

static uint64_t getCurrentTimeMs()
{
    struct timespec time = {};

    if (clock_gettime(CLOCK_REALTIME, &time) < 0)
    {
        return 0;
    }
    uint64_t currentTimeMs = static_cast<uint64_t>(time.tv_sec) * 1000;
    currentTimeMs += static_cast<uint64_t>(time.tv_nsec) / 1000 / 1000;

    return currentTimeMs;
}

static constexpr std::string_view getHostState(const PowerState state)
{
    switch (state)
    {
        case PowerState::on:
        case PowerState::transitionToOff:
        case PowerState::gracefulTransitionToOff:
        case PowerState::transitionToCycleOff:
        case PowerState::gracefulTransitionToCycleOff:
            return "xyz.openbmc_project.State.Host.HostState.Running";
            break;
        case PowerState::waitForPSPowerOK:
        case PowerState::waitForSIOPowerGood:
        case PowerState::failedTransitionToOn:
        case PowerState::off:
        case PowerState::cycleOff:
            return "xyz.openbmc_project.State.Host.HostState.Off";
            break;
        default:
            return "";
            break;
    }
};
static constexpr std::string_view getChassisState(const PowerState state)
{
    switch (state)
    {
        case PowerState::on:
        case PowerState::transitionToOff:
        case PowerState::gracefulTransitionToOff:
        case PowerState::transitionToCycleOff:
        case PowerState::gracefulTransitionToCycleOff:
            return "xyz.openbmc_project.State.Chassis.PowerState.On";
            break;
        case PowerState::waitForPSPowerOK:
        case PowerState::waitForSIOPowerGood:
        case PowerState::failedTransitionToOn:
        case PowerState::off:
        case PowerState::cycleOff:
            return "xyz.openbmc_project.State.Chassis.PowerState.Off";
            break;
        default:
            return "";
            break;
    }
};
static void savePowerState(const PowerState state)
{
    powerStateSaveTimer.expires_after(
        std::chrono::milliseconds(powerOffSaveTimeMs));
    powerStateSaveTimer.async_wait([state](const boost::system::error_code ec) {
        if (ec)
        {
            // operation_aborted is expected if timer is canceled before
            // completion.
            if (ec != boost::asio::error::operation_aborted)
            {
                std::cerr << "Power-state save async_wait failed: "
                          << ec.message() << "\n";
            }
            return;
        }
        std::ofstream powerStateStream(powerControlDir / powerStateFile);
        powerStateStream << getChassisState(state);
    });
}
static void setPowerState(const PowerState state)
{
    powerState = state;
    logStateTransition(state);

    hostIface->set_property("CurrentHostState",
                            std::string(getHostState(powerState)));

    chassisIface->set_property("CurrentPowerState",
                               std::string(getChassisState(powerState)));
    chassisIface->set_property("LastStateChangeTime", getCurrentTimeMs());

    // Save the power state for the restore policy
    savePowerState(state);
}

enum class RestartCause
{
    command,
    resetButton,
    powerButton,
    powerPolicyOn,
    powerPolicyRestore,
    softReset,
};
static std::string getRestartCause(RestartCause cause)
{
    switch (cause)
    {
        case RestartCause::command:
            return "xyz.openbmc_project.State.Host.RestartCause.IpmiCommand";
            break;
        case RestartCause::resetButton:
            return "xyz.openbmc_project.State.Host.RestartCause.ResetButton";
            break;
        case RestartCause::powerButton:
            return "xyz.openbmc_project.State.Host.RestartCause.PowerButton";
            break;
        case RestartCause::powerPolicyOn:
            return "xyz.openbmc_project.State.Host.RestartCause."
                   "PowerPolicyAlwaysOn";
            break;
        case RestartCause::powerPolicyRestore:
            return "xyz.openbmc_project.State.Host.RestartCause."
                   "PowerPolicyPreviousState";
            break;
        case RestartCause::softReset:
            return "xyz.openbmc_project.State.Host.RestartCause.SoftReset";
            break;
        default:
            return "xyz.openbmc_project.State.Host.RestartCause.Unknown";
            break;
    }
}
static void setRestartCause(const RestartCause cause)
{
    conn->async_method_call(
        [](boost::system::error_code ec) {
            if (ec)
            {
                std::cerr << "failed to set RestartCause\n";
            }
        },
        "xyz.openbmc_project.Settings",
        "/xyz/openbmc_project/control/host0/restart_cause",
        "org.freedesktop.DBus.Properties", "Set",
        "xyz.openbmc_project.Common.RestartCause", "RestartCause",
        std::variant<std::string>(getRestartCause(cause)));
}

static void powerRestorePolicyLog()
{
    sd_journal_send("MESSAGE=PowerControl: power restore policy applied",
                    "PRIORITY=%i", LOG_INFO, "REDFISH_MESSAGE_ID=%s",
                    "OpenBMC.0.1.PowerRestorePolicyApplied", NULL);
}

static void powerButtonPressLog()
{
    sd_journal_send("MESSAGE=PowerControl: power button pressed", "PRIORITY=%i",
                    LOG_INFO, "REDFISH_MESSAGE_ID=%s",
                    "OpenBMC.0.1.PowerButtonPressed", NULL);
}

static void resetButtonPressLog()
{
    sd_journal_send("MESSAGE=PowerControl: reset button pressed", "PRIORITY=%i",
                    LOG_INFO, "REDFISH_MESSAGE_ID=%s",
                    "OpenBMC.0.1.ResetButtonPressed", NULL);
}

static void nmiButtonPressLog()
{
    sd_journal_send("MESSAGE=PowerControl: NMI button pressed", "PRIORITY=%i",
                    LOG_INFO, "REDFISH_MESSAGE_ID=%s",
                    "OpenBMC.0.1.NMIButtonPressed", NULL);
}

static void nmiDiagIntLog()
{
    sd_journal_send("MESSAGE=PowerControl: NMI Diagnostic Interrupt",
                    "PRIORITY=%i", LOG_INFO, "REDFISH_MESSAGE_ID=%s",
                    "OpenBMC.0.1.NMIDiagnosticInterrupt", NULL);
}

static int initializePowerStateStorage()
{
    // create the power control directory if it doesn't exist
    std::error_code ec;
    if (!(std::filesystem::create_directories(powerControlDir, ec)))
    {
        if (ec.value() != 0)
        {
            std::cerr << "failed to create " << powerControlDir << ": "
                      << ec.message() << "\n";
            return -1;
        }
    }
    // Create the power state file if it doesn't exist
    if (!std::filesystem::exists(powerControlDir / powerStateFile))
    {
        std::ofstream powerStateStream(powerControlDir / powerStateFile);
        powerStateStream << getChassisState(powerState);
    }
    return 0;
}

static bool wasPowerDropped()
{
    std::ifstream powerStateStream(powerControlDir / powerStateFile);
    if (!powerStateStream.is_open())
    {
        std::cerr << "Failed to open power state file\n";
        return false;
    }

    std::string state;
    std::getline(powerStateStream, state);
    return state == "xyz.openbmc_project.State.Chassis.PowerState.On";
}

static void invokePowerRestorePolicy(const std::string& policy)
{
    // Async events may call this twice, but we only want to run once
    static bool policyInvoked = false;
    if (policyInvoked)
    {
        return;
    }
    policyInvoked = true;

    std::cerr << "Power restore delay expired, invoking " << policy << "\n";
    if (policy ==
        "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOn")
    {
        sendPowerControlEvent(Event::powerOnRequest);
        setRestartCause(RestartCause::powerPolicyOn);
    }
    else if (policy == "xyz.openbmc_project.Control.Power.RestorePolicy."
                       "Policy.Restore")
    {
        if (wasPowerDropped())
        {
            std::cerr << "Power was dropped, restoring Host On state\n";
            sendPowerControlEvent(Event::powerOnRequest);
            setRestartCause(RestartCause::powerPolicyRestore);
        }
        else
        {
            std::cerr << "No power drop, restoring Host Off state\n";
        }
    }
}

static void powerRestorePolicyDelay(int delay)
{
    // Async events may call this twice, but we only want to run once
    static bool delayStarted = false;
    if (delayStarted)
    {
        return;
    }
    delayStarted = true;
    // Calculate the delay from now to meet the requested delay
    // Subtract the approximate uboot time
    static constexpr const int ubootSeconds = 20;
    delay -= ubootSeconds;
    // Subtract the time since boot
    struct sysinfo info = {};
    if (sysinfo(&info) == 0)
    {
        delay -= info.uptime;
    }
    // 0 is the minimum delay
    delay = std::max(delay, 0);

    static boost::asio::steady_timer powerRestorePolicyTimer(io);
    powerRestorePolicyTimer.expires_after(std::chrono::seconds(delay));
    std::cerr << "Power restore delay of " << delay << " seconds started\n";
    powerRestorePolicyTimer.async_wait([](const boost::system::error_code ec) {
        if (ec)
        {
            // operation_aborted is expected if timer is canceled before
            // completion.
            if (ec != boost::asio::error::operation_aborted)
            {
                std::cerr << "power restore policy async_wait failed: "
                          << ec.message() << "\n";
            }
            return;
        }
        // Get Power Restore Policy
        // In case PowerRestorePolicy is not available, set a match for it
        static std::unique_ptr<sdbusplus::bus::match::match>
            powerRestorePolicyMatch = std::make_unique<
                sdbusplus::bus::match::match>(
                *conn,
                "type='signal',interface='org.freedesktop.DBus.Properties',"
                "member='PropertiesChanged',arg0namespace='xyz.openbmc_"
                "project.Control.Power.RestorePolicy'",
                [](sdbusplus::message::message& msg) {
                    std::string interfaceName;
                    boost::container::flat_map<std::string,
                                               std::variant<std::string>>
                        propertiesChanged;
                    std::string policy;
                    try
                    {
                        msg.read(interfaceName, propertiesChanged);
                        policy = std::get<std::string>(
                            propertiesChanged.begin()->second);
                    }
                    catch (std::exception& e)
                    {
                        std::cerr
                            << "Unable to read power restore policy value\n";
                        powerRestorePolicyMatch.reset();
                        return;
                    }
                    invokePowerRestorePolicy(policy);
                    powerRestorePolicyMatch.reset();
                });

        // Check if it's already on DBus
        conn->async_method_call(
            [](boost::system::error_code ec,
               const std::variant<std::string>& policyProperty) {
                if (ec)
                {
                    return;
                }
                powerRestorePolicyMatch.reset();
                const std::string* policy =
                    std::get_if<std::string>(&policyProperty);
                if (policy == nullptr)
                {
                    std::cerr << "Unable to read power restore policy value\n";
                    return;
                }
                invokePowerRestorePolicy(*policy);
            },
            "xyz.openbmc_project.Settings",
            "/xyz/openbmc_project/control/host0/power_restore_policy",
            "org.freedesktop.DBus.Properties", "Get",
            "xyz.openbmc_project.Control.Power.RestorePolicy",
            "PowerRestorePolicy");
    });
}

static void powerRestorePolicyStart()
{
    std::cerr << "Power restore policy started\n";
    powerRestorePolicyLog();

    // Get the desired delay time
    // In case PowerRestoreDelay is not available, set a match for it
    static std::unique_ptr<sdbusplus::bus::match::match>
        powerRestoreDelayMatch = std::make_unique<sdbusplus::bus::match::match>(
            *conn,
            "type='signal',interface='org.freedesktop.DBus.Properties',member='"
            "PropertiesChanged',arg0namespace='xyz.openbmc_project.Control."
            "Power.RestoreDelay'",
            [](sdbusplus::message::message& msg) {
                std::string interfaceName;
                boost::container::flat_map<std::string, std::variant<uint16_t>>
                    propertiesChanged;
                int delay = 0;
                try
                {
                    msg.read(interfaceName, propertiesChanged);
                    delay =
                        std::get<uint16_t>(propertiesChanged.begin()->second);
                }
                catch (std::exception& e)
                {
                    std::cerr << "Unable to read power restore delay value\n";
                    powerRestoreDelayMatch.reset();
                    return;
                }
                powerRestorePolicyDelay(delay);
                powerRestoreDelayMatch.reset();
            });

    // Check if it's already on DBus
    conn->async_method_call(
        [](boost::system::error_code ec,
           const std::variant<uint16_t>& delayProperty) {
            if (ec)
            {
                return;
            }
            powerRestoreDelayMatch.reset();
            const uint16_t* delay = std::get_if<uint16_t>(&delayProperty);
            if (delay == nullptr)
            {
                std::cerr << "Unable to read power restore delay value\n";
                return;
            }
            powerRestorePolicyDelay(*delay);
        },
        "xyz.openbmc_project.Settings",
        "/xyz/openbmc_project/control/power_restore_delay",
        "org.freedesktop.DBus.Properties", "Get",
        "xyz.openbmc_project.Control.Power.RestoreDelay", "PowerRestoreDelay");
}

static void powerRestorePolicyCheck()
{
    // In case ACBoot is not available, set a match for it
    static std::unique_ptr<sdbusplus::bus::match::match> acBootMatch =
        std::make_unique<sdbusplus::bus::match::match>(
            *conn,
            "type='signal',interface='org.freedesktop.DBus.Properties',member='"
            "PropertiesChanged',arg0namespace='xyz.openbmc_project.Common."
            "ACBoot'",
            [](sdbusplus::message::message& msg) {
                std::string interfaceName;
                boost::container::flat_map<std::string,
                                           std::variant<std::string>>
                    propertiesChanged;
                std::string acBoot;
                try
                {
                    msg.read(interfaceName, propertiesChanged);
                    acBoot = std::get<std::string>(
                        propertiesChanged.begin()->second);
                }
                catch (std::exception& e)
                {
                    std::cerr << "Unable to read AC Boot status\n";
                    acBootMatch.reset();
                    return;
                }
                if (acBoot == "Unknown")
                {
                    return;
                }
                if (acBoot == "True")
                {
                    // Start the Power Restore policy
                    powerRestorePolicyStart();
                }
                acBootMatch.reset();
            });

    // Check if it's already on DBus
    conn->async_method_call(
        [](boost::system::error_code ec,
           const std::variant<std::string>& acBootProperty) {
            if (ec)
            {
                return;
            }
            const std::string* acBoot =
                std::get_if<std::string>(&acBootProperty);
            if (acBoot == nullptr)
            {
                std::cerr << "Unable to read AC Boot status\n";
                return;
            }
            if (*acBoot == "Unknown")
            {
                return;
            }
            if (*acBoot == "True")
            {
                // Start the Power Restore policy
                powerRestorePolicyStart();
            }
            acBootMatch.reset();
        },
        "xyz.openbmc_project.Settings",
        "/xyz/openbmc_project/control/host0/ac_boot",
        "org.freedesktop.DBus.Properties", "Get",
        "xyz.openbmc_project.Common.ACBoot", "ACBoot");
}

static bool requestGPIOEvents(
    const std::string& name, const std::function<void()>& handler,
    gpiod::line& gpioLine,
    boost::asio::posix::stream_descriptor& gpioEventDescriptor)
{
    // Find the GPIO line
    gpioLine = gpiod::find_line(name);
    if (!gpioLine)
    {
        std::cerr << "Failed to find the " << name << " line\n";
        return false;
    }

    try
    {
        gpioLine.request(
            {"power-control", gpiod::line_request::EVENT_BOTH_EDGES});
    }
    catch (std::exception&)
    {
        std::cerr << "Failed to request events for " << name << "\n";
        return false;
    }

    int gpioLineFd = gpioLine.event_get_fd();
    if (gpioLineFd < 0)
    {
        std::cerr << "Failed to get " << name << " fd\n";
        return false;
    }

    gpioEventDescriptor.assign(gpioLineFd);

    gpioEventDescriptor.async_wait(
        boost::asio::posix::stream_descriptor::wait_read,
        [&name, handler](const boost::system::error_code ec) {
            if (ec)
            {
                std::cerr << name << " fd handler error: " << ec.message()
                          << "\n";
                // TODO: throw here to force power-control to restart?
                return;
            }
            handler();
        });
    return true;
}

static bool setGPIOOutput(const std::string& name, const int value,
                          gpiod::line& gpioLine)
{
    // Find the GPIO line
    gpioLine = gpiod::find_line(name);
    if (!gpioLine)
    {
        std::cerr << "Failed to find the " << name << " line.\n";
        return false;
    }

    // Request GPIO output to specified value
    try
    {
        gpioLine.request({__FUNCTION__, gpiod::line_request::DIRECTION_OUTPUT},
                         value);
    }
    catch (std::exception&)
    {
        std::cerr << "Failed to request " << name << " output\n";
        return false;
    }

    std::cerr << name << " set to " << std::to_string(value) << "\n";
    return true;
}

static int setMaskedGPIOOutputForMs(gpiod::line& maskedGPIOLine,
                                    const std::string& name, const int value,
                                    const int durationMs)
{
    // Set the masked GPIO line to the specified value
    maskedGPIOLine.set_value(value);
    std::cerr << name << " set to " << std::to_string(value) << "\n";
    gpioAssertTimer.expires_after(std::chrono::milliseconds(durationMs));
    gpioAssertTimer.async_wait(
        [maskedGPIOLine, value, name](const boost::system::error_code ec) {
            // Set the masked GPIO line back to the opposite value
            maskedGPIOLine.set_value(!value);
            std::cerr << name << " released\n";
            if (ec)
            {
                // operation_aborted is expected if timer is canceled before
                // completion.
                if (ec != boost::asio::error::operation_aborted)
                {
                    std::cerr << name << " async_wait failed: " + ec.message()
                              << "\n";
                }
            }
        });
    return 0;
}

static int setGPIOOutputForMs(const std::string& name, const int value,
                              const int durationMs)
{
    // If the requested GPIO is masked, use the mask line to set the output
    if (powerButtonMask && name == power_control::powerOutName)
    {
        return setMaskedGPIOOutputForMs(powerButtonMask, name, value,
                                        durationMs);
    }
    if (resetButtonMask && name == power_control::resetOutName)
    {
        return setMaskedGPIOOutputForMs(resetButtonMask, name, value,
                                        durationMs);
    }

    // No mask set, so request and set the GPIO normally
    gpiod::line gpioLine;
    if (!setGPIOOutput(name, value, gpioLine))
    {
        return -1;
    }
    gpioAssertTimer.expires_after(std::chrono::milliseconds(durationMs));
    gpioAssertTimer.async_wait(
        [gpioLine, value, name](const boost::system::error_code ec) {
            // Set the GPIO line back to the opposite value
            gpioLine.set_value(!value);
            std::cerr << name << " released\n";
            if (ec)
            {
                // operation_aborted is expected if timer is canceled before
                // completion.
                if (ec != boost::asio::error::operation_aborted)
                {
                    std::cerr << name << " async_wait failed: " << ec.message()
                              << "\n";
                }
            }
        });
    return 0;
}

static void powerOn()
{
    setGPIOOutputForMs(power_control::powerOutName, 0, powerPulseTimeMs);
}

static void gracefulPowerOff()
{
    setGPIOOutputForMs(power_control::powerOutName, 0, powerPulseTimeMs);
}

static void forcePowerOff()
{
    if (setGPIOOutputForMs(power_control::powerOutName, 0,
                           forceOffPulseTimeMs) < 0)
    {
        return;
    }

    // If the force off timer expires, then the PCH power-button override
    // failed, so attempt the Unconditional Powerdown SMBus command.
    gpioAssertTimer.async_wait([](const boost::system::error_code ec) {
        if (ec)
        {
            // operation_aborted is expected if timer is canceled before
            // completion.
            if (ec != boost::asio::error::operation_aborted)
            {
                std::cerr << "Force power off async_wait failed: "
                          << ec.message() << "\n";
            }
            return;
        }
        std::cerr << "PCH Power-button override failed. Issuing Unconditional "
                     "Powerdown SMBus command.\n";
        const static constexpr size_t pchDevBusAddress = 3;
        const static constexpr size_t pchDevSlaveAddress = 0x44;
        const static constexpr size_t pchCmdReg = 0;
        const static constexpr size_t pchPowerDownCmd = 0x02;
        if (i2cSet(pchDevBusAddress, pchDevSlaveAddress, pchCmdReg,
                   pchPowerDownCmd) < 0)
        {
            std::cerr << "Unconditional Powerdown command failed! Not sure "
                         "what to do now.\n";
        }
    });
}

static void reset()
{
    setGPIOOutputForMs(power_control::resetOutName, 0, resetPulseTimeMs);
}

static void gracefulPowerOffTimerStart()
{
    std::cerr << "Graceful power-off timer started\n";
    gracefulPowerOffTimer.expires_after(
        std::chrono::milliseconds(gracefulPowerOffTimeMs));
    gracefulPowerOffTimer.async_wait([](const boost::system::error_code ec) {
        if (ec)
        {
            // operation_aborted is expected if timer is canceled before
            // completion.
            if (ec != boost::asio::error::operation_aborted)
            {
                std::cerr << "Graceful power-off async_wait failed: "
                          << ec.message() << "\n";
            }
            std::cerr << "Graceful power-off timer canceled\n";
            return;
        }
        std::cerr << "Graceful power-off timer completed\n";
        sendPowerControlEvent(Event::gracefulPowerOffTimerExpired);
    });
}

static void powerCycleTimerStart()
{
    std::cerr << "Power-cycle timer started\n";
    powerCycleTimer.expires_after(std::chrono::milliseconds(powerCycleTimeMs));
    powerCycleTimer.async_wait([](const boost::system::error_code ec) {
        if (ec)
        {
            // operation_aborted is expected if timer is canceled before
            // completion.
            if (ec != boost::asio::error::operation_aborted)
            {
                std::cerr << "Power-cycle async_wait failed: " << ec.message()
                          << "\n";
            }
            std::cerr << "Power-cycle timer canceled\n";
            return;
        }
        std::cerr << "Power-cycle timer completed\n";
        sendPowerControlEvent(Event::powerCycleTimerExpired);
    });
}

static void psPowerOKWatchdogTimerStart()
{
    std::cerr << "power supply power OK watchdog timer started\n";
    psPowerOKWatchdogTimer.expires_after(
        std::chrono::milliseconds(psPowerOKWatchdogTimeMs));
    psPowerOKWatchdogTimer.async_wait(
        [](const boost::system::error_code ec) {
            if (ec)
            {
                // operation_aborted is expected if timer is canceled before
                // completion.
                if (ec != boost::asio::error::operation_aborted)
                {
                    std::cerr
                        << "power supply power OK watchdog async_wait failed: "
                        << ec.message() << "\n";
                }
                std::cerr << "power supply power OK watchdog timer canceled\n";
                return;
            }
            std::cerr << "power supply power OK watchdog timer expired\n";
            sendPowerControlEvent(Event::psPowerOKWatchdogTimerExpired);
        });
}

static void pohCounterTimerStart()
{
    std::cerr << "POH timer started\n";
    // Set the time-out as 1 hour, to align with POH command in ipmid
    pohCounterTimer.expires_after(std::chrono::hours(1));
    pohCounterTimer.async_wait([](const boost::system::error_code& ec) {
        if (ec)
        {
            // operation_aborted is expected if timer is canceled before
            // completion.
            if (ec != boost::asio::error::operation_aborted)
            {
                std::cerr << "POH timer async_wait failed: " << ec.message()
                          << "\n";
            }
            std::cerr << "POH timer canceled\n";
            return;
        }

        if (getHostState(powerState) !=
            "xyz.openbmc_project.State.Host.HostState.Running")
        {
            return;
        }

        conn->async_method_call(
            [](boost::system::error_code ec,
               const std::variant<uint32_t>& pohCounterProperty) {
                if (ec)
                {
                    std::cerr << "error to get poh counter\n";
                    return;
                }
                const uint32_t* pohCounter =
                    std::get_if<uint32_t>(&pohCounterProperty);
                if (pohCounter == nullptr)
                {
                    std::cerr << "unable to read poh counter\n";
                    return;
                }

                conn->async_method_call(
                    [](boost::system::error_code ec) {
                        if (ec)
                        {
                            std::cerr << "failed to set poh counter\n";
                        }
                    },
                    "xyz.openbmc_project.Settings",
                    "/xyz/openbmc_project/state/chassis0",
                    "org.freedesktop.DBus.Properties", "Set",
                    "xyz.openbmc_project.State.PowerOnHours", "POHCounter",
                    std::variant<uint32_t>(*pohCounter + 1));
            },
            "xyz.openbmc_project.Settings",
            "/xyz/openbmc_project/state/chassis0",
            "org.freedesktop.DBus.Properties", "Get",
            "xyz.openbmc_project.State.PowerOnHours", "POHCounter");

        pohCounterTimerStart();
    });
}

static void currentHostStateMonitor()
{
    static auto match = sdbusplus::bus::match::match(
        *conn,
        "type='signal',member='PropertiesChanged', "
        "interface='org.freedesktop.DBus.Properties', "
        "arg0namespace='xyz.openbmc_project.State.Host'",
        [](sdbusplus::message::message& message) {
            std::string intfName;
            std::map<std::string, std::variant<std::string>> properties;

            message.read(intfName, properties);

            std::variant<std::string> currentHostState;

            try
            {
                currentHostState = properties.at("CurrentHostState");
            }
            catch (const std::out_of_range& e)
            {
                std::cerr << "Error in finding CurrentHostState property\n";

                return;
            }

            if (std::get<std::string>(currentHostState) ==
                "xyz.openbmc_project.State.Host.HostState.Running")
            {
                pohCounterTimerStart();
            }
            else
            {
                pohCounterTimer.cancel();
            }
        });
}

static void sioPowerGoodWatchdogTimerStart()
{
    std::cerr << "SIO power good watchdog timer started\n";
    sioPowerGoodWatchdogTimer.expires_after(
        std::chrono::milliseconds(sioPowerGoodWatchdogTimeMs));
    sioPowerGoodWatchdogTimer.async_wait(
        [](const boost::system::error_code ec) {
            if (ec)
            {
                // operation_aborted is expected if timer is canceled before
                // completion.
                if (ec != boost::asio::error::operation_aborted)
                {
                    std::cerr << "SIO power good watchdog async_wait failed: "
                              << ec.message() << "\n";
                }
                std::cerr << "SIO power good watchdog timer canceled\n";
                return;
            }
            std::cerr << "SIO power good watchdog timer completed\n";
            sendPowerControlEvent(Event::sioPowerGoodWatchdogTimerExpired);
        });
}

static void powerStateOn(const Event event)
{
    logEvent(__FUNCTION__, event);
    switch (event)
    {
        case Event::psPowerOKDeAssert:
            setPowerState(PowerState::off);
            // DC power is unexpectedly lost, beep
            beep(beepPowerFail);
            break;
        case Event::sioS5Assert:
            setPowerState(PowerState::transitionToOff);
            setRestartCause(RestartCause::softReset);
            break;
        case Event::powerButtonPressed:
            setPowerState(PowerState::gracefulTransitionToOff);
            gracefulPowerOffTimerStart();
            break;
        case Event::powerOffRequest:
            setPowerState(PowerState::transitionToOff);
            forcePowerOff();
            break;
        case Event::gracefulPowerOffRequest:
            setPowerState(PowerState::gracefulTransitionToOff);
            gracefulPowerOffTimerStart();
            gracefulPowerOff();
            break;
        case Event::powerCycleRequest:
            setPowerState(PowerState::transitionToCycleOff);
            forcePowerOff();
            break;
        case Event::gracefulPowerCycleRequest:
            setPowerState(PowerState::gracefulTransitionToCycleOff);
            gracefulPowerOffTimerStart();
            gracefulPowerOff();
            break;
        case Event::resetRequest:
            reset();
            break;
        default:
            std::cerr << "No action taken.\n";
            break;
    }
}

static void powerStateWaitForPSPowerOK(const Event event)
{
    logEvent(__FUNCTION__, event);
    switch (event)
    {
        case Event::psPowerOKAssert:
            // Cancel any GPIO assertions held during the transition
            gpioAssertTimer.cancel();
            psPowerOKWatchdogTimer.cancel();
            sioPowerGoodWatchdogTimerStart();
            setPowerState(PowerState::waitForSIOPowerGood);
            break;
        case Event::psPowerOKWatchdogTimerExpired:
            setPowerState(PowerState::failedTransitionToOn);
            break;
        default:
            std::cerr << "No action taken.\n";
            break;
    }
}

static void powerStateWaitForSIOPowerGood(const Event event)
{
    logEvent(__FUNCTION__, event);
    switch (event)
    {
        case Event::sioPowerGoodAssert:
            sioPowerGoodWatchdogTimer.cancel();
            setPowerState(PowerState::on);
            break;
        case Event::sioPowerGoodWatchdogTimerExpired:
            setPowerState(PowerState::failedTransitionToOn);
            forcePowerOff();
            break;
        default:
            std::cerr << "No action taken.\n";
            break;
    }
}

static void powerStateFailedTransitionToOn(const Event event)
{
    logEvent(__FUNCTION__, event);
    switch (event)
    {
        case Event::psPowerOKAssert:
            // We're in a failure state, so don't allow the system to turn on
            // without a user request
            forcePowerOff();
            break;
        case Event::psPowerOKDeAssert:
            // Cancel any GPIO assertions held during the transition
            gpioAssertTimer.cancel();
            break;
        case Event::powerButtonPressed:
            psPowerOKWatchdogTimerStart();
            setPowerState(PowerState::waitForPSPowerOK);
            break;
        case Event::powerOnRequest:
            psPowerOKWatchdogTimerStart();
            setPowerState(PowerState::waitForPSPowerOK);
            powerOn();
            break;
        default:
            std::cerr << "No action taken.\n";
            break;
    }
}

static void powerStateOff(const Event event)
{
    logEvent(__FUNCTION__, event);
    switch (event)
    {
        case Event::psPowerOKAssert:
            setPowerState(PowerState::waitForSIOPowerGood);
            break;
        case Event::sioS5DeAssert:
            setPowerState(PowerState::waitForPSPowerOK);
            break;
        case Event::powerButtonPressed:
            psPowerOKWatchdogTimerStart();
            setPowerState(PowerState::waitForPSPowerOK);
            break;
        case Event::powerOnRequest:
            psPowerOKWatchdogTimerStart();
            setPowerState(PowerState::waitForPSPowerOK);
            powerOn();
            break;
        default:
            std::cerr << "No action taken.\n";
            break;
    }
}

static void powerStateTransitionToOff(const Event event)
{
    logEvent(__FUNCTION__, event);
    switch (event)
    {
        case Event::psPowerOKDeAssert:
            // Cancel any GPIO assertions held during the transition
            gpioAssertTimer.cancel();
            setPowerState(PowerState::off);
            break;
        default:
            std::cerr << "No action taken.\n";
            break;
    }
}

static void powerStateGracefulTransitionToOff(const Event event)
{
    logEvent(__FUNCTION__, event);
    switch (event)
    {
        case Event::psPowerOKDeAssert:
            gracefulPowerOffTimer.cancel();
            setPowerState(PowerState::off);
            break;
        case Event::gracefulPowerOffTimerExpired:
            setPowerState(PowerState::on);
            break;
        default:
            std::cerr << "No action taken.\n";
            break;
    }
}

static void powerStateCycleOff(const Event event)
{
    logEvent(__FUNCTION__, event);
    switch (event)
    {
        case Event::powerCycleTimerExpired:
            psPowerOKWatchdogTimerStart();
            setPowerState(PowerState::waitForPSPowerOK);
            powerOn();
            break;
        default:
            std::cerr << "No action taken.\n";
            break;
    }
}

static void powerStateTransitionToCycleOff(const Event event)
{
    logEvent(__FUNCTION__, event);
    switch (event)
    {
        case Event::psPowerOKDeAssert:
            // Cancel any GPIO assertions held during the transition
            gpioAssertTimer.cancel();
            setPowerState(PowerState::cycleOff);
            powerCycleTimerStart();
            break;
        default:
            std::cerr << "No action taken.\n";
            break;
    }
}

static void powerStateGracefulTransitionToCycleOff(const Event event)
{
    logEvent(__FUNCTION__, event);
    switch (event)
    {
        case Event::psPowerOKDeAssert:
            gracefulPowerOffTimer.cancel();
            setPowerState(PowerState::cycleOff);
            powerCycleTimerStart();
            break;
        case Event::gracefulPowerOffTimerExpired:
            setPowerState(PowerState::on);
            break;
        default:
            std::cerr << "No action taken.\n";
            break;
    }
}

static void psPowerOKHandler()
{
    gpiod::line_event gpioLineEvent = psPowerOKLine.event_read();

    Event powerControlEvent =
        gpioLineEvent.event_type == gpiod::line_event::RISING_EDGE
            ? Event::psPowerOKAssert
            : Event::psPowerOKDeAssert;

    sendPowerControlEvent(powerControlEvent);
    psPowerOKEvent.async_wait(
        boost::asio::posix::stream_descriptor::wait_read,
        [](const boost::system::error_code ec) {
            if (ec)
            {
                std::cerr << "power supply power OK handler error: "
                          << ec.message() << "\n";
                return;
            }
            psPowerOKHandler();
        });
}

static void sioPowerGoodHandler()
{
    gpiod::line_event gpioLineEvent = sioPowerGoodLine.event_read();

    Event powerControlEvent =
        gpioLineEvent.event_type == gpiod::line_event::RISING_EDGE
            ? Event::sioPowerGoodAssert
            : Event::sioPowerGoodDeAssert;

    sendPowerControlEvent(powerControlEvent);
    sioPowerGoodEvent.async_wait(
        boost::asio::posix::stream_descriptor::wait_read,
        [](const boost::system::error_code ec) {
            if (ec)
            {
                std::cerr << "SIO power good handler error: " << ec.message()
                          << "\n";
                return;
            }
            sioPowerGoodHandler();
        });
}

static void sioOnControlHandler()
{
    gpiod::line_event gpioLineEvent = sioOnControlLine.event_read();

    bool sioOnControl =
        gpioLineEvent.event_type == gpiod::line_event::RISING_EDGE;
    std::cerr << "SIO_ONCONTROL value changed: " << sioOnControl << "\n";
    sioOnControlEvent.async_wait(
        boost::asio::posix::stream_descriptor::wait_read,
        [](const boost::system::error_code ec) {
            if (ec)
            {
                std::cerr << "SIO ONCONTROL handler error: " << ec.message()
                          << "\n";
                return;
            }
            sioOnControlHandler();
        });
}

static void sioS5Handler()
{
    gpiod::line_event gpioLineEvent = sioS5Line.event_read();

    Event powerControlEvent =
        gpioLineEvent.event_type == gpiod::line_event::FALLING_EDGE
            ? Event::sioS5Assert
            : Event::sioS5DeAssert;

    sendPowerControlEvent(powerControlEvent);
    sioS5Event.async_wait(boost::asio::posix::stream_descriptor::wait_read,
                          [](const boost::system::error_code ec) {
                              if (ec)
                              {
                                  std::cerr << "SIO S5 handler error: "
                                            << ec.message() << "\n";
                                  return;
                              }
                              sioS5Handler();
                          });
}

static void powerButtonHandler()
{
    gpiod::line_event gpioLineEvent = powerButtonLine.event_read();

    if (gpioLineEvent.event_type == gpiod::line_event::FALLING_EDGE)
    {
        powerButtonPressLog();
        powerButtonIface->set_property("ButtonPressed", true);
        if (!powerButtonMask)
        {
            sendPowerControlEvent(Event::powerButtonPressed);
            setRestartCause(RestartCause::powerButton);
        }
        else
        {
            std::cerr << "power button press masked\n";
        }
    }
    else if (gpioLineEvent.event_type == gpiod::line_event::RISING_EDGE)
    {
        powerButtonIface->set_property("ButtonPressed", false);
    }
    powerButtonEvent.async_wait(
        boost::asio::posix::stream_descriptor::wait_read,
        [](const boost::system::error_code ec) {
            if (ec)
            {
                std::cerr << "power button handler error: " << ec.message()
                          << "\n";
                return;
            }
            powerButtonHandler();
        });
}

static void resetButtonHandler()
{
    gpiod::line_event gpioLineEvent = resetButtonLine.event_read();

    if (gpioLineEvent.event_type == gpiod::line_event::FALLING_EDGE)
    {
        resetButtonPressLog();
        resetButtonIface->set_property("ButtonPressed", true);
        if (!resetButtonMask)
        {
            resetInProgress = true;
            setRestartCause(RestartCause::resetButton);
        }
        else
        {
            std::cerr << "reset button press masked\n";
        }
    }
    else if (gpioLineEvent.event_type == gpiod::line_event::RISING_EDGE)
    {
        resetButtonIface->set_property("ButtonPressed", false);
    }
    resetButtonEvent.async_wait(
        boost::asio::posix::stream_descriptor::wait_read,
        [](const boost::system::error_code ec) {
            if (ec)
            {
                std::cerr << "reset button handler error: " << ec.message()
                          << "\n";
                return;
            }
            resetButtonHandler();
        });
}

static void nmiSetEnablePorperty(bool value)
{
    conn->async_method_call(
        [](boost::system::error_code ec) {
            if (ec)
            {
                std::cerr << "failed to set NMI source\n";
            }
        },
        "xyz.openbmc_project.Settings", "/com/intel/control/NMISource",
        "org.freedesktop.DBus.Properties", "Set", "com.intel.Control.NMISource",
        "Enabled", std::variant<bool>{value});
}

static void nmiReset(void)
{
    static constexpr const uint8_t value = 1;
    const static constexpr int nmiOutPulseTimeMs = 200;

    std::cerr << "NMI out action \n";
    nmiOutLine.set_value(value);
    std::cerr << nmiOutName << " set to " << std::to_string(value) << "\n";
    gpioAssertTimer.expires_after(std::chrono::milliseconds(nmiOutPulseTimeMs));
    gpioAssertTimer.async_wait([](const boost::system::error_code ec) {
        // restore the NMI_OUT GPIO line back to the opposite value
        nmiOutLine.set_value(!value);
        std::cerr << nmiOutName << " released\n";
        if (ec)
        {
            // operation_aborted is expected if timer is canceled before
            // completion.
            if (ec != boost::asio::error::operation_aborted)
            {
                std::cerr << nmiOutName << " async_wait failed: " + ec.message()
                          << "\n";
            }
        }
    });
    // log to redfish
    nmiDiagIntLog();
    std::cerr << "NMI out action completed\n";
    // reset Enable Property
    nmiSetEnablePorperty(false);
}

static void nmiSourcePropertyMonitor(void)
{
    std::cerr << " NMI Source Property Monitor \n";

    static std::unique_ptr<sdbusplus::bus::match::match> nmiSourceMatch =
        std::make_unique<sdbusplus::bus::match::match>(
            *conn,
            "type='signal',interface='org.freedesktop.DBus.Properties',"
            "member='PropertiesChanged',arg0namespace='com.intel.Control."
            "NMISource'",
            [](sdbusplus::message::message& msg) {
                std::string interfaceName;
                boost::container::flat_map<std::string,
                                           std::variant<bool, std::string>>
                    propertiesChanged;
                std::string state;
                bool value = true;
                try
                {
                    msg.read(interfaceName, propertiesChanged);
                    if (propertiesChanged.begin()->first == "Enabled")
                    {
                        value =
                            std::get<bool>(propertiesChanged.begin()->second);
                        std::cerr
                            << " NMI Enabled propertiesChanged value: " << value
                            << "\n";
                        nmiEnabled = value;
                        if (nmiEnabled)
                        {
                            nmiReset();
                        }
                    }
                }
                catch (std::exception& e)
                {
                    std::cerr << "Unable to read NMI source\n";
                    return;
                }
            });
}

static void setNmiSource()
{
    conn->async_method_call(
        [](boost::system::error_code ec) {
            if (ec)
            {
                std::cerr << "failed to set NMI source\n";
            }
        },
        "xyz.openbmc_project.Settings", "/com/intel/control/NMISource",
        "org.freedesktop.DBus.Properties", "Set", "com.intel.Control.NMISource",
        "BMCSource",
        std::variant<std::string>{
            "com.intel.Control.NMISource.BMCSourceSignal.FpBtn"});
    // set Enable Property
    nmiSetEnablePorperty(true);
}

static void nmiButtonHandler()
{
    gpiod::line_event gpioLineEvent = nmiButtonLine.event_read();

    if (gpioLineEvent.event_type == gpiod::line_event::FALLING_EDGE)
    {
        nmiButtonPressLog();
        nmiButtonIface->set_property("ButtonPressed", true);
        if (nmiButtonMasked)
        {
            std::cerr << "NMI button press masked\n";
        }
        else
        {
            setNmiSource();
        }
    }
    else if (gpioLineEvent.event_type == gpiod::line_event::RISING_EDGE)
    {
        nmiButtonIface->set_property("ButtonPressed", false);
    }
    nmiButtonEvent.async_wait(boost::asio::posix::stream_descriptor::wait_read,
                              [](const boost::system::error_code ec) {
                                  if (ec)
                                  {
                                      std::cerr << "NMI button handler error: "
                                                << ec.message() << "\n";
                                      return;
                                  }
                                  nmiButtonHandler();
                              });
}

static void idButtonHandler()
{
    gpiod::line_event gpioLineEvent = idButtonLine.event_read();

    if (gpioLineEvent.event_type == gpiod::line_event::FALLING_EDGE)
    {
        idButtonIface->set_property("ButtonPressed", true);
    }
    else if (gpioLineEvent.event_type == gpiod::line_event::RISING_EDGE)
    {
        idButtonIface->set_property("ButtonPressed", false);
    }
    idButtonEvent.async_wait(boost::asio::posix::stream_descriptor::wait_read,
                             [](const boost::system::error_code& ec) {
                                 if (ec)
                                 {
                                     std::cerr << "ID button handler error: "
                                               << ec.message() << "\n";
                                     return;
                                 }
                                 idButtonHandler();
                             });
}

static void postCompleteHandler()
{
    gpiod::line_event gpioLineEvent = postCompleteLine.event_read();

    bool postComplete =
        gpioLineEvent.event_type == gpiod::line_event::FALLING_EDGE;
    std::cerr << "POST complete value changed: " << postComplete << "\n";
    if (postComplete)
    {
        osIface->set_property("OperatingSystemState", std::string("Standby"));
        resetInProgress = false;
    }
    else
    {
        osIface->set_property("OperatingSystemState", std::string("Inactive"));
        // Set the restart cause if POST complete de-asserted by host software
        if (powerState == PowerState::on && !resetInProgress)
        {
            resetInProgress = true;
            setRestartCause(RestartCause::softReset);
        }
    }
    postCompleteEvent.async_wait(
        boost::asio::posix::stream_descriptor::wait_read,
        [](const boost::system::error_code ec) {
            if (ec)
            {
                std::cerr << "POST complete handler error: " << ec.message()
                          << "\n";
                return;
            }
            postCompleteHandler();
        });
}
} // namespace power_control

int main(int argc, char* argv[])
{
    std::cerr << "Start Chassis power control service...\n";
    power_control::conn =
        std::make_shared<sdbusplus::asio::connection>(power_control::io);

    // Request all the dbus names
    power_control::conn->request_name("xyz.openbmc_project.State.Host");
    power_control::conn->request_name("xyz.openbmc_project.State.Chassis");
    power_control::conn->request_name(
        "xyz.openbmc_project.State.OperatingSystem");
    power_control::conn->request_name("xyz.openbmc_project.Chassis.Buttons");

    // Request PS_PWROK GPIO events
    if (!power_control::requestGPIOEvents(
            "PS_PWROK", power_control::psPowerOKHandler,
            power_control::psPowerOKLine, power_control::psPowerOKEvent))
    {
        return -1;
    }

    // Request SIO_POWER_GOOD GPIO events
    if (!power_control::requestGPIOEvents(
            "SIO_POWER_GOOD", power_control::sioPowerGoodHandler,
            power_control::sioPowerGoodLine, power_control::sioPowerGoodEvent))
    {
        return -1;
    }

    // Request SIO_ONCONTROL GPIO events
    if (!power_control::requestGPIOEvents(
            "SIO_ONCONTROL", power_control::sioOnControlHandler,
            power_control::sioOnControlLine, power_control::sioOnControlEvent))
    {
        return -1;
    }

    // Request SIO_S5 GPIO events
    if (!power_control::requestGPIOEvents("SIO_S5", power_control::sioS5Handler,
                                          power_control::sioS5Line,
                                          power_control::sioS5Event))
    {
        return -1;
    }

    // Request POWER_BUTTON GPIO events
    if (!power_control::requestGPIOEvents(
            "POWER_BUTTON", power_control::powerButtonHandler,
            power_control::powerButtonLine, power_control::powerButtonEvent))
    {
        return -1;
    }

    // Request RESET_BUTTON GPIO events
    if (!power_control::requestGPIOEvents(
            "RESET_BUTTON", power_control::resetButtonHandler,
            power_control::resetButtonLine, power_control::resetButtonEvent))
    {
        return -1;
    }

    // Request NMI_BUTTON GPIO events
    if (!power_control::requestGPIOEvents(
            "NMI_BUTTON", power_control::nmiButtonHandler,
            power_control::nmiButtonLine, power_control::nmiButtonEvent))
    {
        return -1;
    }

    // Request ID_BUTTON GPIO events
    if (!power_control::requestGPIOEvents(
            "ID_BUTTON", power_control::idButtonHandler,
            power_control::idButtonLine, power_control::idButtonEvent))
    {
        return -1;
    }

    // Request POST_COMPLETE GPIO events
    if (!power_control::requestGPIOEvents(
            "POST_COMPLETE", power_control::postCompleteHandler,
            power_control::postCompleteLine, power_control::postCompleteEvent))
    {
        return -1;
    }

    // initialize NMI_OUT GPIO.
    if (!power_control::setGPIOOutput(power_control::nmiOutName, 0,
                                      power_control::nmiOutLine))
    {
        return -1;
    }

    // Initialize POWER_OUT and RESET_OUT GPIO.
    gpiod::line line;
    if (!power_control::setGPIOOutput(power_control::powerOutName, 1, line))
    {
        return -1;
    }

    if (!power_control::setGPIOOutput(power_control::resetOutName, 1, line))
    {
        return -1;
    }

    // Release line
    line.reset();

    // Initialize the power state
    power_control::powerState = power_control::PowerState::off;
    // Check power good
    if (power_control::psPowerOKLine.get_value() > 0)
    {
        power_control::powerState = power_control::PowerState::on;
    }

    // Initialize the power state storage
    if (power_control::initializePowerStateStorage() < 0)
    {
        return -1;
    }

    // Check if we need to start the Power Restore policy
    power_control::powerRestorePolicyCheck();

    power_control::nmiSourcePropertyMonitor();

    std::cerr << "Initializing power state. ";
    power_control::logStateTransition(power_control::powerState);

    // Power Control Service
    sdbusplus::asio::object_server hostServer =
        sdbusplus::asio::object_server(power_control::conn);

    // Power Control Interface
    power_control::hostIface = hostServer.add_interface(
        "/xyz/openbmc_project/state/host0", "xyz.openbmc_project.State.Host");

    power_control::hostIface->register_property(
        "RequestedHostTransition",
        std::string("xyz.openbmc_project.State.Host.Transition.Off"),
        [](const std::string& requested, std::string& resp) {
            if (requested == "xyz.openbmc_project.State.Host.Transition.Off")
            {
                sendPowerControlEvent(
                    power_control::Event::gracefulPowerOffRequest);
            }
            else if (requested ==
                     "xyz.openbmc_project.State.Host.Transition.On")
            {
                sendPowerControlEvent(power_control::Event::powerOnRequest);
                setRestartCause(power_control::RestartCause::command);
            }
            else if (requested ==
                     "xyz.openbmc_project.State.Host.Transition.Reboot")
            {
                sendPowerControlEvent(
                    power_control::Event::gracefulPowerCycleRequest);
                setRestartCause(power_control::RestartCause::command);
            }
            else
            {
                std::cerr << "Unrecognized host state transition request.\n";
                throw std::invalid_argument("Unrecognized Transition Request");
                return 0;
            }
            resp = requested;
            return 1;
        });
    power_control::hostIface->register_property(
        "CurrentHostState",
        std::string(power_control::getHostState(power_control::powerState)));

    power_control::currentHostStateMonitor();

    power_control::hostIface->initialize();

    // Chassis Control Service
    sdbusplus::asio::object_server chassisServer =
        sdbusplus::asio::object_server(power_control::conn);

    // Chassis Control Interface
    power_control::chassisIface =
        chassisServer.add_interface("/xyz/openbmc_project/state/chassis0",
                                    "xyz.openbmc_project.State.Chassis");

    power_control::chassisIface->register_property(
        "RequestedPowerTransition",
        std::string("xyz.openbmc_project.State.Chassis.Transition.Off"),
        [](const std::string& requested, std::string& resp) {
            if (requested == "xyz.openbmc_project.State.Chassis.Transition.Off")
            {
                sendPowerControlEvent(power_control::Event::powerOffRequest);
            }
            else if (requested ==
                     "xyz.openbmc_project.State.Chassis.Transition.On")
            {
                sendPowerControlEvent(power_control::Event::powerOnRequest);
                setRestartCause(power_control::RestartCause::command);
            }
            else if (requested ==
                     "xyz.openbmc_project.State.Chassis.Transition.PowerCycle")
            {
                sendPowerControlEvent(power_control::Event::powerCycleRequest);
                setRestartCause(power_control::RestartCause::command);
            }
            else if (requested ==
                     "xyz.openbmc_project.State.Chassis.Transition.Reset")
            {
                setRestartCause(power_control::RestartCause::command);
                sendPowerControlEvent(power_control::Event::resetRequest);
            }
            else
            {
                std::cerr << "Unrecognized chassis state transition request.\n";
                throw std::invalid_argument("Unrecognized Transition Request");
                return 0;
            }
            resp = requested;
            return 1;
        });
    power_control::chassisIface->register_property(
        "CurrentPowerState",
        std::string(power_control::getChassisState(power_control::powerState)));
    power_control::chassisIface->register_property(
        "LastStateChangeTime", power_control::getCurrentTimeMs());

    power_control::chassisIface->initialize();

    // Buttons Service
    sdbusplus::asio::object_server buttonsServer =
        sdbusplus::asio::object_server(power_control::conn);

    // Power Button Interface
    power_control::powerButtonIface = buttonsServer.add_interface(
        "/xyz/openbmc_project/chassis/buttons/power",
        "xyz.openbmc_project.Chassis.Buttons");

    power_control::powerButtonIface->register_property(
        "ButtonMasked", false, [](const bool requested, bool& current) {
            if (requested)
            {
                if (power_control::powerButtonMask)
                {
                    return 1;
                }
                if (!power_control::setGPIOOutput(
                        power_control::powerOutName, 1,
                        power_control::powerButtonMask))
                {
                    throw std::runtime_error("Failed to request GPIO");
                    return 0;
                }
                std::cerr << "Power Button Masked.\n";
            }
            else
            {
                if (!power_control::powerButtonMask)
                {
                    return 1;
                }
                std::cerr << "Power Button Un-masked\n";
                power_control::powerButtonMask.reset();
            }
            // Update the mask setting
            current = requested;
            return 1;
        });

    // Check power button state
    bool powerButtonPressed = power_control::powerButtonLine.get_value() == 0;
    power_control::powerButtonIface->register_property("ButtonPressed",
                                                       powerButtonPressed);

    power_control::powerButtonIface->initialize();

    // Reset Button Interface
    power_control::resetButtonIface = buttonsServer.add_interface(
        "/xyz/openbmc_project/chassis/buttons/reset",
        "xyz.openbmc_project.Chassis.Buttons");

    power_control::resetButtonIface->register_property(
        "ButtonMasked", false, [](const bool requested, bool& current) {
            if (requested)
            {
                if (power_control::resetButtonMask)
                {
                    return 1;
                }
                if (!power_control::setGPIOOutput(
                        power_control::resetOutName, 1,
                        power_control::resetButtonMask))
                {
                    throw std::runtime_error("Failed to request GPIO");
                    return 0;
                }
                std::cerr << "Reset Button Masked.\n";
            }
            else
            {
                if (!power_control::resetButtonMask)
                {
                    return 1;
                }
                std::cerr << "Reset Button Un-masked\n";
                power_control::resetButtonMask.reset();
            }
            // Update the mask setting
            current = requested;
            return 1;
        });

    // Check reset button state
    bool resetButtonPressed = power_control::resetButtonLine.get_value() == 0;
    power_control::resetButtonIface->register_property("ButtonPressed",
                                                       resetButtonPressed);

    power_control::resetButtonIface->initialize();

    // NMI Button Interface
    power_control::nmiButtonIface =
        buttonsServer.add_interface("/xyz/openbmc_project/chassis/buttons/nmi",
                                    "xyz.openbmc_project.Chassis.Buttons");

    power_control::nmiButtonIface->register_property(
        "ButtonMasked", false, [](const bool requested, bool& current) {
            if (power_control::nmiButtonMasked == requested)
            {
                // NMI button mask is already set as requested, so no change
                return 1;
            }
            if (requested)
            {
                std::cerr << "NMI Button Masked.\n";
                power_control::nmiButtonMasked = true;
            }
            else
            {
                std::cerr << "NMI Button Un-masked.\n";
                power_control::nmiButtonMasked = false;
            }
            // Update the mask setting
            current = power_control::nmiButtonMasked;
            return 1;
        });

    // Check NMI button state
    bool nmiButtonPressed = power_control::nmiButtonLine.get_value() == 0;
    power_control::nmiButtonIface->register_property("ButtonPressed",
                                                     nmiButtonPressed);

    power_control::nmiButtonIface->initialize();

    // ID Button Interface
    power_control::idButtonIface =
        buttonsServer.add_interface("/xyz/openbmc_project/chassis/buttons/id",
                                    "xyz.openbmc_project.Chassis.Buttons");

    // Check ID button state
    bool idButtonPressed = power_control::idButtonLine.get_value() == 0;
    power_control::idButtonIface->register_property("ButtonPressed",
                                                    idButtonPressed);

    power_control::idButtonIface->initialize();

    // OS State Service
    sdbusplus::asio::object_server osServer =
        sdbusplus::asio::object_server(power_control::conn);

    // OS State Interface
    power_control::osIface = osServer.add_interface(
        "/xyz/openbmc_project/state/os",
        "xyz.openbmc_project.State.OperatingSystem.Status");

    // Get the initial OS state based on POST complete
    //      0: Asserted, OS state is "Standby" (ready to boot)
    //      1: De-Asserted, OS state is "Inactive"
    std::string osState = power_control::postCompleteLine.get_value() > 0
                              ? "Inactive"
                              : "Standby";

    power_control::osIface->register_property("OperatingSystemState",
                                              std::string(osState));

    power_control::osIface->initialize();

    power_control::io.run();

    return 0;
}
