/**
 * 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_interface.hpp"

#include "types.hpp"

#include <fmt/format.h>

#include <phosphor-logging/log.hpp>
#include <sdbusplus/exception.hpp>
#include <sdbusplus/sdbus.hpp>
#include <sdbusplus/server.hpp>

#include <string>
#include <tuple>

using namespace phosphor::logging;

namespace phosphor::power::sequencer
{

PowerInterface::PowerInterface(sdbusplus::bus::bus& bus, const char* path) :
    serverInterface(bus, path, POWER_IFACE, vtable, this)
{}

int PowerInterface::callbackGetPgood(sd_bus* /*bus*/, const char* /*path*/,
                                     const char* /*interface*/,
                                     const char* /*property*/,
                                     sd_bus_message* msg, void* context,
                                     sd_bus_error* error)
{
    if (msg != nullptr && context != nullptr)
    {
        try
        {
            auto pwrObj = static_cast<PowerInterface*>(context);
            int pgood = pwrObj->getPgood();
            log<level::INFO>(
                fmt::format("callbackGetPgood: {}", pgood).c_str());

            sdbusplus::message::message(msg).append(pgood);
        }
        catch (const sdbusplus::exception_t& e)
        {
            return sd_bus_error_set(error, e.name(), e.description());
        }
    }
    else
    {
        // The message or context were null
        log<level::ERR>("Unable to service get pgood property callback");
        return -1;
    }

    return 1;
}

int PowerInterface::callbackGetPgoodTimeout(sd_bus* /*bus*/,
                                            const char* /*path*/,
                                            const char* /*interface*/,
                                            const char* /*property*/,
                                            sd_bus_message* msg, void* context,
                                            sd_bus_error* error)
{
    if (msg != nullptr && context != nullptr)
    {
        try
        {
            auto pwrObj = static_cast<PowerInterface*>(context);
            int timeout = pwrObj->getPgoodTimeout();
            log<level::INFO>(
                fmt::format("callbackGetPgoodTimeout: {}", timeout).c_str());

            sdbusplus::message::message(msg).append(timeout);
        }
        catch (const sdbusplus::exception_t& e)
        {
            return sd_bus_error_set(error, e.name(), e.description());
        }
    }
    else
    {
        // The message or context were null
        log<level::ERR>(
            "Unable to service get pgood timeout property callback");
        return -1;
    }

    return 1;
}

int PowerInterface::callbackGetPowerState(sd_bus_message* msg, void* context,
                                          sd_bus_error* error)
{
    if (msg != nullptr && context != nullptr)
    {
        try
        {
            auto pwrObj = static_cast<PowerInterface*>(context);
            // Return the current power state of the GPIO, rather than the last
            // requested power state change
            int pgood = pwrObj->getPgood();
            log<level::INFO>(
                fmt::format("callbackGetPowerState: {}", pgood).c_str());

            auto reply = sdbusplus::message::message(msg).new_method_return();
            reply.append(pgood);
            reply.method_return();
        }
        catch (const sdbusplus::exception_t& e)
        {
            return sd_bus_error_set(error, e.name(), e.description());
        }
    }
    else
    {
        // The message or context were null
        log<level::ERR>("Unable to service getPowerState method callback");
        return -1;
    }

    return 1;
}

int PowerInterface::callbackSetPgoodTimeout(sd_bus* /*bus*/,
                                            const char* /*path*/,
                                            const char* /*interface*/,
                                            const char* /*property*/,
                                            sd_bus_message* msg, void* context,
                                            sd_bus_error* error)
{
    if (msg != nullptr && context != nullptr)
    {
        try
        {
            auto m = sdbusplus::message::message(msg);

            int timeout{};
            m.read(timeout);
            log<level::INFO>(
                fmt::format("callbackSetPgoodTimeout: {}", timeout).c_str());

            auto pwrObj = static_cast<PowerInterface*>(context);
            pwrObj->setPgoodTimeout(timeout);
        }
        catch (const sdbusplus::exception_t& e)
        {
            return sd_bus_error_set(error, e.name(), e.description());
        }
    }
    else
    {
        // The message or context were null
        log<level::ERR>(
            "Unable to service set pgood timeout property callback");
        return -1;
    }

    return 1;
}

int PowerInterface::callbackGetState(sd_bus* /*bus*/, const char* /*path*/,
                                     const char* /*interface*/,
                                     const char* /*property*/,
                                     sd_bus_message* msg, void* context,
                                     sd_bus_error* error)
{
    if (msg != nullptr && context != nullptr)
    {
        try
        {
            auto pwrObj = static_cast<PowerInterface*>(context);
            int state = pwrObj->getState();
            log<level::INFO>(
                fmt::format("callbackGetState: {}", state).c_str());

            sdbusplus::message::message(msg).append(state);
        }
        catch (const sdbusplus::exception_t& e)
        {
            return sd_bus_error_set(error, e.name(), e.description());
        }
    }
    else
    {
        // The message or context were null
        log<level::ERR>("Unable to service get state property callback");
        return -1;
    }

    return 1;
}

int PowerInterface::callbackSetPowerState(sd_bus_message* msg, void* context,
                                          sd_bus_error* error)
{
    if (msg != nullptr && context != nullptr)
    {
        try
        {
            auto m = sdbusplus::message::message(msg);

            int state{};
            m.read(state);

            if (state != 1 && state != 0)
            {
                return sd_bus_error_set(error,
                                        "org.openbmc.ControlPower.Error.Failed",
                                        "Invalid power state");
            }
            log<level::INFO>(
                fmt::format("callbackSetPowerState: {}", state).c_str());

            auto pwrObj = static_cast<PowerInterface*>(context);
            pwrObj->setState(state);

            m.new_method_return().method_return();
        }
        catch (const sdbusplus::exception_t& e)
        {
            return sd_bus_error_set(error, e.name(), e.description());
        }
    }
    else
    {
        // The message or context were null
        log<level::ERR>("Unable to service setPowerState method callback");
        return -1;
    }

    return 1;
}

int PowerInterface::callbackSetPowerSupplyError(sd_bus_message* msg,
                                                void* context,
                                                sd_bus_error* error)
{
    if (msg != nullptr && context != nullptr)
    {
        try
        {
            auto m = sdbusplus::message::message(msg);

            std::string psError{};
            m.read(psError);
            log<level::INFO>(
                fmt::format("callbackSetPowerSupplyError: {}", psError)
                    .c_str());

            auto pwrObj = static_cast<PowerInterface*>(context);
            pwrObj->setPowerSupplyError(psError);

            m.new_method_return().method_return();
        }
        catch (const sdbusplus::exception_t& e)
        {
            return sd_bus_error_set(error, e.name(), e.description());
        }
    }
    else
    {
        // The message or context were null
        log<level::ERR>(
            "Unable to service setPowerSupplyError method callback");
        return -1;
    }

    return 1;
}

void PowerInterface::emitPowerGoodSignal()
{
    log<level::INFO>("emitPowerGoodSignal");
    serverInterface.new_signal("PowerGood").signal_send();
}

void PowerInterface::emitPowerLostSignal()
{
    log<level::INFO>("emitPowerLostSignal");
    serverInterface.new_signal("PowerLost").signal_send();
}

void PowerInterface::emitPropertyChangedSignal(const char* property)
{
    log<level::INFO>(
        fmt::format("emitPropertyChangedSignal: {}", property).c_str());
    serverInterface.property_changed(property);
}

const sdbusplus::vtable::vtable_t PowerInterface::vtable[] = {
    sdbusplus::vtable::start(),
    // Method setPowerState takes an int parameter and returns void
    sdbusplus::vtable::method("setPowerState", "i", "", callbackSetPowerState),
    // Method getPowerState takes no parameters and returns int
    sdbusplus::vtable::method("getPowerState", "", "i", callbackGetPowerState),
    // Signal PowerGood
    sdbusplus::vtable::signal("PowerGood", ""),
    // Signal PowerLost
    sdbusplus::vtable::signal("PowerLost", ""),
    // Property pgood is type int, read only, and uses the emits_change flag
    sdbusplus::vtable::property("pgood", "i", callbackGetPgood,
                                sdbusplus::vtable::property_::emits_change),
    // Property state is type int, read only, and uses the emits_change flag
    sdbusplus::vtable::property("state", "i", callbackGetState,
                                sdbusplus::vtable::property_::emits_change),
    // Property pgood_timeout is type int, read write, and uses the emits_change
    // flag
    sdbusplus::vtable::property("pgood_timeout", "i", callbackGetPgoodTimeout,
                                callbackSetPgoodTimeout,
                                sdbusplus::vtable::property_::emits_change),
    // Method setPowerSupplyError takes a string parameter and returns void
    sdbusplus::vtable::method("setPowerSupplyError", "s", "",
                              callbackSetPowerSupplyError),
    sdbusplus::vtable::end()};

} // namespace phosphor::power::sequencer
