/**
 * 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 <fmt/format.h>
#include <sys/types.h>
#include <unistd.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, true},
    bus{bus}, timer{event, std::bind(&PowerControl::pollPgood, this),
                    pollInterval}
{
    // Obtain dbus service name
    bus.request_name(POWER_IFACE);

    // Subscribe to D-Bus interfacesAdded signal from Entity Manager.  This
    // notifies us if the interface becomes available later.
    match = std::make_unique<sdbusplus::bus::match_t>(
        bus,
        sdbusplus::bus::match::rules::interfacesAdded() +
            sdbusplus::bus::match::rules::sender(
                "xyz.openbmc_project.EntityManager"),
        std::bind(&PowerControl::interfacesAddedHandler, this,
                  std::placeholders::_1));
    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::INFO>(
            fmt::format(
                "Found power sequencer device properties, name: {}, bus: {} addr: {:#02x} ",
                *name, *i2cBus, *i2cAddress)
                .c_str());
        // Create device object
    }
}

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)
{
    // Verify message is valid
    if (!msg)
    {
        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;

            try
            {
                auto method = bus.new_method_call(
                    "xyz.openbmc_project.Logging",
                    "/xyz/openbmc_project/logging",
                    "xyz.openbmc_project.Logging.Create", "Create");

                std::map<std::string, std::string> additionalData;
                // Add PID to AdditionalData
                additionalData.emplace("_PID", std::to_string(getpid()));

                method.append(
                    state ? "xyz.openbmc_project.Power.Error.PowerOnTimeout"
                          : "xyz.openbmc_project.Power.Error.PowerOffTimeout",
                    sdbusplus::xyz::openbmc_project::Logging::server::Entry::
                        Level::Critical,
                    additionalData);
                bus.call_noreply(method);
            }
            catch (const std::exception& e)
            {
                log<level::ERR>(
                    fmt::format(
                        "Unable to log timeout error, state: {}, error {}",
                        state, e.what())
                        .c_str());
            }

            return;
        }
    }

    int pgoodState = pgoodLine.get_value();
    if (pgoodState != pgood)
    {
        // Power good has changed since last read
        pgood = pgoodState;
        if (pgoodState == 0)
        {
            emitPowerLostSignal();
        }
        else
        {
            emitPowerGoodSignal();
        }
        emitPropertyChangedSignal("pgood");
    }
    if (pgoodState == state)
    {
        // Power good matches requested state
        inStateTransition = false;
    }
    else if (!inStateTransition && (pgoodState == 0))
    {
        // Not in power off state, not changing state, and power good is off
        // 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::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));
    }

    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();

    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
