#include "occ_errors.hpp"

#include "elog-errors.hpp"

#include <errno.h>
#include <fcntl.h>
#include <fmt/core.h>
#include <sys/ioctl.h>
#include <unistd.h>

#include <org/open_power/OCC/Device/error.hpp>
#include <phosphor-logging/elog.hpp>
#include <phosphor-logging/log.hpp>
#include <xyz/openbmc_project/Common/error.hpp>
namespace open_power
{
namespace occ
{

using namespace phosphor::logging;
using namespace sdbusplus::org::open_power::OCC::Device::Error;
using InternalFailure =
    sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure;

// Populate the file descriptor on the error file
void Error::openFile()
{
    using namespace phosphor::logging;

    fd = open(file.c_str(), O_RDONLY | O_NONBLOCK);
    const int open_errno = errno;
    if (fd < 0)
    {
        log<level::ERR>(
            fmt::format("Error::openFile: open failed (errno={})", open_errno)
                .c_str());
        elog<OpenFailure>(phosphor::logging::org::open_power::OCC::Device::
                              OpenFailure::CALLOUT_ERRNO(open_errno),
                          phosphor::logging::org::open_power::OCC::Device::
                              OpenFailure::CALLOUT_DEVICE_PATH(file.c_str()));
    }
}

// Attaches the FD to event loop and registers the callback handler
void Error::registerCallBack()
{
    decltype(eventSource.get()) sourcePtr = nullptr;
    auto r = sd_event_add_io(event.get(), &sourcePtr, fd, EPOLLPRI | EPOLLERR,
                             processEvents, this);
    eventSource.reset(sourcePtr);

    if (r < 0)
    {
        log<level::ERR>("Failed to register callback handler",
                        entry("ERROR=%s", strerror(-r)));
        elog<InternalFailure>();
    }
}

// Starts to watch for errors
void Error::addWatch(bool poll)
{
    if (!watching)
    {
        // Open the file
        openFile();

        if (poll)
        {
            // register the callback handler
            registerCallBack();
        }

        // Set we are watching the error
        watching = true;
    }
}

// Stops watching for errors
void Error::removeWatch()
{
    if (watching)
    {
        // Close the file
        if (fd >= 0)
        {
            close(fd);
        }

        // Reduce the reference count. Since there is only one instances
        // of add_io, this will result empty loop
        eventSource.reset();

        // We are no more watching the error
        watching = false;
    }
}

// Callback handler when there is an activity on the FD
int Error::processEvents(sd_event_source* /*es*/, int /*fd*/,
                         uint32_t /*revents*/, void* userData)
{
    auto error = static_cast<Error*>(userData);

    error->analyzeEvent();
    return 0;
}

// Reads the error file and analyzes the data
void Error::analyzeEvent()
{
    // Get the number of bytes to read
    int err = 0;
    int len = -1;
    auto r = ioctl(fd, FIONREAD, &len);
    if (r < 0)
    {
        elog<ConfigFailure>(
            phosphor::logging::org::open_power::OCC::Device::ConfigFailure::
                CALLOUT_ERRNO(errno),
            phosphor::logging::org::open_power::OCC::Device::ConfigFailure::
                CALLOUT_DEVICE_PATH(file.c_str()));
    }

    // A non-zero data indicates an error condition
    // Let the caller take appropriate action on this
    auto data = readFile(len);
    if (!data.empty())
        err = std::stoi(data, nullptr, 0);
    if (callBack)
    {
        callBack(err);
    }
    return;
}

// Reads so many bytes as passed in
std::string Error::readFile(int len) const
{
    auto data = std::make_unique<char[]>(len + 1);
    auto retries = 3;
    auto delay = std::chrono::milliseconds{100};

    // OCC / FSI have intermittent issues so retry all reads
    while (true)
    {
        // This file get created soon after binding. A value of 0 is
        // deemed success and anything else is a Failure
        // Since all the sysfs files would have size of 4096, if we read 0
        // bytes -or- value '0', then it just means we are fine
        auto r = read(fd, data.get(), len);
        if (r < 0)
        {
            retries--;
            if (retries == 0)
            {
                elog<ReadFailure>(
                    phosphor::logging::org::open_power::OCC::Device::
                        ReadFailure::CALLOUT_ERRNO(errno),
                    phosphor::logging::org::open_power::OCC::Device::
                        ReadFailure::CALLOUT_DEVICE_PATH(file.c_str()));
                break;
            }
            std::this_thread::sleep_for(delay);
            continue;
        }
        break;
    }
    // Need to seek to START, else the poll returns immediately telling
    // there is data to be read
    auto r = lseek(fd, 0, SEEK_SET);
    if (r < 0)
    {
        log<level::ERR>("Failure seeking error file to START");
        elog<ConfigFailure>(
            phosphor::logging::org::open_power::OCC::Device::ConfigFailure::
                CALLOUT_ERRNO(errno),
            phosphor::logging::org::open_power::OCC::Device::ConfigFailure::
                CALLOUT_DEVICE_PATH(file.c_str()));
    }
    return std::string(data.get());
}

} // namespace occ
} // namespace open_power
