/**
 * Copyright © 2017 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 "gpio.hpp"

#include "logging.hpp"
#include "rpolicy.hpp"
#include "sdbusplus.hpp"

#include <phosphor-logging/elog-errors.hpp>
#include <phosphor-logging/elog.hpp>
#include <sdeventplus/event.hpp>
#include <xyz/openbmc_project/Common/Callout/error.hpp>
#include <xyz/openbmc_project/Logging/Entry/server.hpp>

#include <functional>
#include <tuple>

namespace phosphor
{
namespace fan
{
namespace presence
{

const auto loggingService = "xyz.openbmc_project.Logging";
const auto loggingPath = "/xyz/openbmc_project/logging";
const auto loggingCreateIface = "xyz.openbmc_project.Logging.Create";

Gpio::Gpio(const std::string& physDevice, const std::string& device,
           unsigned int physPin) :
    currentState(false),
    evdevfd(open(device.c_str(), O_RDONLY | O_NONBLOCK)),
    evdev(evdevpp::evdev::newFromFD(evdevfd())), phys(physDevice), pin(physPin)
{}

bool Gpio::start()
{
    source.emplace(sdeventplus::Event::get_default(), evdevfd(), EPOLLIN,
                   std::bind(&Gpio::ioCallback, this));
    currentState = present();
    return currentState;
}

void Gpio::stop()
{
    source.reset();
}

bool Gpio::present()
{
    return evdev.fetch(EV_KEY, pin) != 0;
}

void Gpio::fail()
{
    using namespace sdbusplus::xyz::openbmc_project::Common::Callout::Error;
    using namespace phosphor::logging;
    using namespace xyz::openbmc_project::Common::Callout;

    report<sdbusplus::xyz::openbmc_project::Common::Callout::Error::GPIO>(
        GPIO::CALLOUT_GPIO_NUM(pin), GPIO::CALLOUT_ERRNO(0),
        GPIO::CALLOUT_DEVICE_PATH(phys.c_str()));
}

void Gpio::ioCallback()
{
    unsigned int type, code, value;

    std::tie(type, code, value) = evdev.next();
    if (type != EV_KEY || code != pin)
    {
        return;
    }

    bool newState = value != 0;

    if (currentState != newState)
    {
        getPolicy().stateChanged(newState, *this);
        currentState = newState;
    }
}

void Gpio::logConflict(const std::string& fanInventoryPath) const
{
    using namespace sdbusplus::xyz::openbmc_project::Logging::server;
    std::map<std::string, std::string> ad;
    Entry::Level severity = Entry::Level::Informational;

    static constexpr auto errorName =
        "xyz.openbmc_project.Fan.Presence.Error.Detection";

    ad.emplace("_PID", std::to_string(getpid()));
    ad.emplace("CALLOUT_INVENTORY_PATH", fanInventoryPath);
    ad.emplace("GPIO_NUM", std::to_string(pin));
    ad.emplace("GPIO_DEVICE_PATH", (phys.c_str()));

    getLogger().log(
        std::format("GPIO presence detect for fan {} said not present but "
                    "other methods indicated present",
                    fanInventoryPath));
    try
    {
        util::SDBusPlus::callMethod(loggingService, loggingPath,
                                    loggingCreateIface, "Create", errorName,
                                    severity, ad);
    }
    catch (const util::DBusError& e)
    {
        getLogger().log(
            std::format("Call to create a {} error for fan {} failed: {}",
                        errorName, fanInventoryPath, e.what()),
            Logger::error);
    }
}

} // namespace presence
} // namespace fan
} // namespace phosphor
