#include "occ_errors.hpp"

#include "elog-errors.hpp"

#include <errno.h>
#include <fcntl.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
{

// Value in error file indicating success
constexpr auto NO_ERROR = '0';

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);
    if (fd < 0)
    {
        elog<OpenFailure>(phosphor::logging::org::open_power::OCC::Device::
                              OpenFailure::CALLOUT_ERRNO(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()
{
    if (!watching)
    {
        // Open the file
        openFile();

        // 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 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);
    bool error = !(data.empty() || data.front() == NO_ERROR);
    if (callBack)
    {
        callBack(error);
    }
    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
