/**
 * Copyright © 2021 IBM 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 "power_control.hpp"

#include "types.hpp"
#include "ucd90320_monitor.hpp"

#include <fmt/chrono.h>
#include <fmt/format.h>

#include <phosphor-logging/elog-errors.hpp>
#include <phosphor-logging/elog.hpp>
#include <phosphor-logging/log.hpp>
#include <xyz/openbmc_project/Common/error.hpp>

#include <exception>
#include <string>

using namespace phosphor::logging;

namespace phosphor::power::sequencer
{

const std::string interfaceName = "xyz.openbmc_project.Configuration.UCD90320";
const std::string addressPropertyName = "Address";
const std::string busPropertyName = "Bus";
const std::string namePropertyName = "Name";

PowerControl::PowerControl(sdbusplus::bus::bus& bus,
                           const sdeventplus::Event& event) :
    PowerObject{bus, POWER_OBJ_PATH, PowerObject::action::defer_emit},
    bus{bus}, device{std::make_unique<PowerSequencerMonitor>(bus)},
    match{bus,
          sdbusplus::bus::match::rules::interfacesAdded() +
              sdbusplus::bus::match::rules::sender(
                  "xyz.openbmc_project.EntityManager"),
          std::bind(&PowerControl::interfacesAddedHandler, this,
                    std::placeholders::_1)},
    powerOnAllowedTime{std::chrono::steady_clock::now() + minimumColdStartTime},
    timer{event, std::bind(&PowerControl::pollPgood, this), pollInterval}
{
    // Obtain dbus service name
    bus.request_name(POWER_IFACE);

    setUpDevice();
    setUpGpio();
}

void PowerControl::getDeviceProperties(util::DbusPropertyMap& properties)
{
    uint64_t* i2cBus = nullptr;
    uint64_t* i2cAddress = nullptr;
    std::string* name = nullptr;

    for (const auto& property : properties)
    {
        try
        {
            if (property.first == busPropertyName)
            {
                i2cBus = std::get_if<uint64_t>(&properties[busPropertyName]);
            }
            else if (property.first == addressPropertyName)
            {
                i2cAddress =
                    std::get_if<uint64_t>(&properties[addressPropertyName]);
            }
            else if (property.first == namePropertyName)
            {
                name = std::get_if<std::string>(&properties[namePropertyName]);
            }
        }
        catch (std::exception& e)
        {}
    }

    if (i2cBus && i2cAddress && name && !name->empty())
    {
        log<level::DEBUG>(
            fmt::format(
                "Found power sequencer device properties, name: {}, bus: {} addr: {:#02x} ",
                *name, *i2cBus, *i2cAddress)
                .c_str());
        // Create device object
        device = std::make_unique<UCD90320Monitor>(bus, *i2cBus, *i2cAddress);
        deviceFound = true;
    }
}

int PowerControl::getPgood() const
{
    return pgood;
}

int PowerControl::getPgoodTimeout() const
{
    return timeout.count();
}

int PowerControl::getState() const
{
    return state;
}

void PowerControl::interfacesAddedHandler(sdbusplus::message::message& msg)
{
    // Only continue if message is valid and device has not already been found
    if (!msg || deviceFound)
    {
        return;
    }

    try
    {
        // Read the dbus message
        sdbusplus::message::object_path objPath;
        std::map<std::string, std::map<std::string, util::DbusVariant>>
            interfaces;
        msg.read(objPath, interfaces);

        // Find the device interface, if present
        auto itIntf = interfaces.find(interfaceName);
        if (itIntf != interfaces.cend())
        {
            log<level::INFO>(
                fmt::format("InterfacesAdded for: {}", interfaceName).c_str());
            getDeviceProperties(itIntf->second);
        }
    }
    catch (const std::exception&)
    {
        // Error trying to read interfacesAdded message.
    }
}

void PowerControl::pollPgood()
{
    if (inStateTransition)
    {
        // In transition between power on and off, check for timeout
        const auto now = std::chrono::steady_clock::now();
        if (now > pgoodTimeoutTime)
        {
            log<level::ERR>("ERROR PowerControl: Pgood poll timeout");
            inStateTransition = false;

            if (state)
            {
                // Time out powering on
                device->onFailure(true, powerSupplyError);
            }
            else
            {
                // Time out powering off
                std::map<std::string, std::string> additionalData{};
                device->logError(
                    "xyz.openbmc_project.Power.Error.PowerOffTimeout",
                    additionalData);
            }

            failureFound = true;
            return;
        }
    }

    int pgoodState = pgoodLine.get_value();
    if (pgoodState != pgood)
    {
        // Power good has changed since last read
        pgood = pgoodState;
        if (pgoodState == 0)
        {
            emitPowerLostSignal();
        }
        else
        {
            emitPowerGoodSignal();
            // Clear any errors on the transition to power on
            powerSupplyError.clear();
            failureFound = false;
        }
        emitPropertyChangedSignal("pgood");
    }
    if (pgoodState == state)
    {
        // Power good matches requested state
        inStateTransition = false;
    }
    else if (!inStateTransition && (pgoodState == 0) && !failureFound)
    {
        // Not in power off state, not changing state, and power good is off
        device->onFailure(false, powerSupplyError);
        failureFound = true;
        // Power good has failed, call for chassis hard power off
        log<level::ERR>("Chassis pgood failure");

        auto method =
            bus.new_method_call(util::SYSTEMD_SERVICE, util::SYSTEMD_ROOT,
                                util::SYSTEMD_INTERFACE, "StartUnit");
        method.append(util::POWEROFF_TARGET);
        method.append("replace");
        bus.call_noreply(method);
    }
}

void PowerControl::setPgoodTimeout(int t)
{
    if (timeout.count() != t)
    {
        timeout = std::chrono::seconds(t);
        emitPropertyChangedSignal("pgood_timeout");
    }
}

void PowerControl::setPowerSupplyError(const std::string& error)
{
    powerSupplyError = error;
}

void PowerControl::setState(int s)
{
    if (state == s)
    {
        log<level::INFO>(
            fmt::format("Power already at requested state: {}", state).c_str());
        return;
    }
    if (s == 0)
    {
        // Wait for two seconds when powering down. This is to allow host and
        // other BMC applications time to complete power off processing
        std::this_thread::sleep_for(std::chrono::seconds(2));
    }
    else
    {
        // If minimum power off time has not passed, wait
        if (powerOnAllowedTime > std::chrono::steady_clock::now())
        {
            log<level::INFO>(
                fmt::format(
                    "Waiting {} seconds until power on allowed",
                    std::chrono::duration_cast<std::chrono::seconds>(
                        powerOnAllowedTime - std::chrono::steady_clock::now())
                        .count())
                    .c_str());
        }
        std::this_thread::sleep_until(powerOnAllowedTime);
    }

    log<level::INFO>(fmt::format("setState: {}", s).c_str());
    powerControlLine.request(
        {"phosphor-power-control", gpiod::line_request::DIRECTION_OUTPUT, 0});
    powerControlLine.set_value(s);
    powerControlLine.release();

    if (s == 0)
    {
        // Set a minimum amount of time to wait before next power on
        powerOnAllowedTime =
            std::chrono::steady_clock::now() + minimumPowerOffTime;
    }

    pgoodTimeoutTime = std::chrono::steady_clock::now() + timeout;
    inStateTransition = true;
    state = s;
    emitPropertyChangedSignal("state");
}

void PowerControl::setUpDevice()
{
    try
    {
        auto objects = util::getSubTree(bus, "/", interfaceName, 0);

        // Search for matching interface in returned objects
        for (const auto& [path, services] : objects)
        {
            auto service = services.begin()->first;

            if (path.empty() || service.empty())
            {
                continue;
            }

            // Get the properties for the device interface
            auto properties =
                util::getAllProperties(bus, path, interfaceName, service);

            getDeviceProperties(properties);
        }
    }
    catch (const std::exception& e)
    {
        // Interface or property not found. Let the Interfaces Added callback
        // process the information once the interfaces are added to D-Bus.
    }
}

void PowerControl::setUpGpio()
{
    const std::string powerControlLineName = "power-chassis-control";
    const std::string pgoodLineName = "power-chassis-good";

    pgoodLine = gpiod::find_line(pgoodLineName);
    if (!pgoodLine)
    {
        std::string errorString{"GPIO line name not found: " + pgoodLineName};
        log<level::ERR>(errorString.c_str());
        report<
            sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure>();
        throw std::runtime_error(errorString);
    }
    powerControlLine = gpiod::find_line(powerControlLineName);
    if (!powerControlLine)
    {
        std::string errorString{"GPIO line name not found: " +
                                powerControlLineName};
        log<level::ERR>(errorString.c_str());
        report<
            sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure>();
        throw std::runtime_error(errorString);
    }

    pgoodLine.request(
        {"phosphor-power-control", gpiod::line_request::DIRECTION_INPUT, 0});
    int pgoodState = pgoodLine.get_value();
    pgood = pgoodState;
    state = pgoodState;
    log<level::INFO>(fmt::format("Pgood state: {}", pgoodState).c_str());
}

} // namespace phosphor::power::sequencer
