#include "side_switch.hpp"

#include "utils.hpp"

#include <phosphor-logging/lg2.hpp>

#include <exception>
#include <string>
#include <thread>
#include <variant>
#include <vector>

PHOSPHOR_LOG2_USING;

bool sideSwitchNeeded(sdbusplus::bus_t& bus)
{

    std::string fwRunningVersionPath;
    uint8_t fwRunningPriority = 0;

    // Get active image
    try
    {
        std::vector<std::string> paths =
            utils::getProperty<std::vector<std::string>>(
                bus, "/xyz/openbmc_project/software/functional",
                "xyz.openbmc_project.Association", "endpoints");
        if (paths.size() != 1)
        {
            info("side-switch only supports BMC-purpose image systems");
            return (false);
        }
        fwRunningVersionPath = paths[0];
        info("Running firmware version path is {FW_PATH}", "FW_PATH",
             fwRunningVersionPath);
    }
    catch (const std::exception& e)
    {
        error("failed to retrieve active firmware version: {ERROR}", "ERROR",
              e);
        return (false);
    }

    // Check if active image has highest priority (0)
    try
    {
        fwRunningPriority = utils::getProperty<uint8_t>(
            bus, fwRunningVersionPath.c_str(),
            "xyz.openbmc_project.Software.RedundancyPriority", "Priority");
        info("Running firmware version priority is {FW_PRIORITY}",
             "FW_PRIORITY", fwRunningPriority);
    }
    catch (const std::exception& e)
    {
        error("failed to read priority from active image: {ERROR}", "ERROR", e);
        return (false);
    }

    // If running at highest priority (0) then no side switch needed
    if (fwRunningPriority == 0)
    {
        info("Running image is at priority 0, no side switch needed");
        return (false);
    }

    // Need to check if any other BMC images on system have a higher priority
    std::vector<std::string> allSoftwarePaths;
    try
    {
        auto method = bus.new_method_call("xyz.openbmc_project.ObjectMapper",
                                          "/xyz/openbmc_project/object_mapper",
                                          "xyz.openbmc_project.ObjectMapper",
                                          "GetSubTreePaths");
        method.append("/xyz/openbmc_project/software");
        method.append(0); // Depth 0 to search all
        method.append(
            std::vector<std::string>({"xyz.openbmc_project.Software.Version"}));
        auto reply = bus.call(method);
        reply.read(allSoftwarePaths);
        if (allSoftwarePaths.size() <= 1)
        {
            info("only 1 image present in flash so no side switch needed");
            return (false);
        }
    }
    catch (const std::exception& e)
    {
        error("failed to retrieve all firmware versions: {ERROR}", "ERROR", e);
        return (false);
    }

    // Cycle through all firmware images looking for a BMC version that
    // has a higher priority then our running image
    for (auto& fwPath : allSoftwarePaths)
    {
        if (fwPath == fwRunningVersionPath)
        {
            info("{FW_PATH} is the running image, skip", "FW_PATH", fwPath);
            continue;
        }
        try
        {
            uint8_t thisPathPri = utils::getProperty<uint8_t>(
                bus, fwPath.c_str(),
                "xyz.openbmc_project.Software.RedundancyPriority", "Priority");

            if (thisPathPri < fwRunningPriority)
            {
                info(
                    "{FW_PATH} has a higher priority, {FW_PRIORITY}, then running priority",
                    "FW_PATH", fwPath, "FW_PRIORITY", thisPathPri);
                return (true);
            }
        }
        catch (const std::exception& e)
        {
            // This could just be a host firmware image, just keep going
            info("failed to read a BMC priority from {FW_PATH}: {ERROR}",
                 "FW_PATH", fwPath, "ERROR", e);
            continue;
        }
    }

    return (false);
}

bool powerOffSystem(sdbusplus::bus_t& bus)
{

    try
    {
        utils::PropertyValue chassOff =
            "xyz.openbmc_project.State.Chassis.Transition.Off";
        utils::setProperty(bus, "/xyz/openbmc_project/state/chassis0",
                           "xyz.openbmc_project.State.Chassis",
                           "RequestedPowerTransition", chassOff);
    }
    catch (const std::exception& e)
    {
        error("chassis off request failed: {ERROR}", "ERROR", e);
        return (false);
    }

    // Now just wait for host and power to turn off
    // Worst case is a systemd service hangs in power off for 2 minutes so
    // take that and double it to avoid any timing issues. The user has
    // requested we switch to the other side, so a lengthy delay is warranted
    // if needed. On most systems the power off takes 5-15 seconds.
    for (int i = 0; i < 240; i++)
    {
        std::this_thread::sleep_for(std::chrono::milliseconds(1000));
        try
        {
            // First wait for host to be off
            auto currentHostState = utils::getProperty<std::string>(
                bus, "/xyz/openbmc_project/state/host0",
                "xyz.openbmc_project.State.Host", "CurrentHostState");

            if (currentHostState ==
                "xyz.openbmc_project.State.Host.HostState.Off")
            {
                info("host is off");
            }
            else
            {
                continue;
            }

            // Then verify chassis power is off
            auto currentPwrState = utils::getProperty<std::string>(
                bus, "/xyz/openbmc_project/state/chassis0",
                "xyz.openbmc_project.State.Chassis", "CurrentPowerState");

            if (currentPwrState ==
                "xyz.openbmc_project.State.Chassis.PowerState.Off")
            {
                info("chassis power is off");
                return (true);
            }
            else
            {
                continue;
            }
        }
        catch (const std::exception& e)
        {
            error("reading chassis power state failed: {ERROR}", "ERROR", e);
            return (false);
        }
    }
    error("timeout waiting for chassis power to turn off");
    return (false);
}

bool setAutoPowerRestart(sdbusplus::bus_t& bus)
{
    try
    {
        // Set the one-time power on policy to AlwaysOn so system auto boots
        // after BMC reboot
        utils::PropertyValue restorePolicyOn =
            "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOn";

        utils::setProperty(
            bus,
            "/xyz/openbmc_project/control/host0/power_restore_policy/one_time",
            "xyz.openbmc_project.Control.Power.RestorePolicy",
            "PowerRestorePolicy", restorePolicyOn);
    }
    catch (const std::exception& e)
    {
        error("setting power policy to always on failed: {ERROR}", "ERROR", e);
        return (false);
    }
    info("RestorePolicy set to AlwaysOn");
    return (true);
}

bool rebootTheBmc(sdbusplus::bus_t& bus)
{
    try
    {
        utils::PropertyValue bmcReboot =
            "xyz.openbmc_project.State.BMC.Transition.Reboot";

        utils::setProperty(bus, "/xyz/openbmc_project/state/bmc0",
                           "xyz.openbmc_project.State.BMC",
                           "RequestedBMCTransition", bmcReboot);
    }
    catch (const std::exception& e)
    {
        error("rebooting the bmc failed: {ERROR}", "ERROR", e);
        return (false);
    }
    info("BMC reboot initiated");
    return (true);
}

int main()
{
    info("Checking for side switch reboot");

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

    if (!sideSwitchNeeded(bus))
    {
        info("Side switch not needed");
        return 0;
    }

    if (!powerOffSystem(bus))
    {
        error("unable to power off chassis");
        return 0;
    }

    if (!setAutoPowerRestart(bus))
    {
        error("unable to set the auto power on restart policy");
        // system has been powered off, best to at least continue and
        // switch to new firmware image so continue
    }

    if (!rebootTheBmc(bus))
    {
        error("unable to reboot the BMC");
        // Return invalid rc to trigger systemd target recovery and appropriate
        // error logging
        return -1;
    }

    return 0;
}
