#include <sys/eventfd.h>

#include <sdbusplus/event.hpp>
#include <sdbusplus/exception.hpp>

namespace sdbusplus::event
{

source::source(source&& s)
{
    if (&s == this)
    {
        return;
    }
    ev = std::exchange(s.ev, nullptr);
    sourcep = std::exchange(s.sourcep, nullptr);
}

source& source::operator=(source&& s)
{
    if (nullptr != sourcep)
    {
        auto l = ev->obtain_lock();
        sd_event_source_unref(sourcep);
    }
    ev = std::exchange(s.ev, nullptr);
    sourcep = std::exchange(s.sourcep, nullptr);

    return *this;
}

source::~source()
{
    if (nullptr != sourcep)
    {
        auto l = ev->obtain_lock();
        sd_event_source_unref(sourcep);
    }
}

condition::condition(condition&& c)
{
    if (&c == this)
    {
        return;
    }

    condition_source = std::move(c.condition_source);
    fd = std::exchange(c.fd, -1);
}

condition& condition::operator=(condition&& c)
{
    condition_source = std::move(c.condition_source);
    if (fd >= 0)
    {
        close(fd);
    }
    fd = std::exchange(c.fd, -1);

    return *this;
}

void condition::signal()
{
    uint64_t value = 1;
    auto rc = write(fd, &value, sizeof(value));
    if (rc < static_cast<decltype(rc)>(sizeof(value)))
    {
        throw exception::SdBusError(errno, __func__);
    }
}

void condition::ack()
{
    uint64_t value = 0;
    auto rc = read(fd, &value, sizeof(value));
    if (rc < static_cast<decltype(rc)>(sizeof(value)))
    {
        throw exception::SdBusError(errno, __func__);
    }
}

event::event()
{
    if (auto rc = sd_event_new(&eventp); rc < 0)
    {
        throw exception::SdBusError(-rc, __func__);
    }
    run_condition = add_condition(run_wakeup, this);
}

void event::run_one(std::chrono::microseconds timeout)
{
    auto l = obtain_lock<false>();

    auto rc = sd_event_run(eventp, static_cast<uint64_t>(timeout.count()));
    if (rc < 0)
    {
        throw exception::SdBusError(-rc, __func__);
    }
}

void event::break_run()
{
    run_condition.signal();
}

source event::add_io(int fd, uint32_t events, sd_event_io_handler_t handler,
                     void* data)
{
    auto l = obtain_lock();

    source s{*this};

    auto rc = sd_event_add_io(eventp, &s.sourcep, fd, events, handler, data);
    if (rc < 0)
    {
        throw exception::SdBusError(-rc, __func__);
    }

    return s;
}

condition event::add_condition(sd_event_io_handler_t handler, void* data)
{
    // We don't need any locks here because we only touch the sd_event
    // indirectly through `add_io` which handles its own locking.

    auto fd = eventfd(0, 0);
    if (fd < 0)
    {
        throw exception::SdBusError(errno, __func__);
    }

    try
    {
        auto io = add_io(fd, EPOLLIN, handler, data);
        return {std::move(io), std::move(fd)};
    }
    catch (...)
    {
        close(fd);
        throw;
    }
}

source event::add_oneshot_timer(sd_event_time_handler_t handler, void* data,
                                std::chrono::microseconds time,
                                std::chrono::microseconds accuracy)
{
    auto l = obtain_lock();

    source s{*this};

    auto rc = sd_event_add_time_relative(eventp, &s.sourcep, CLOCK_BOOTTIME,
                                         time.count(), accuracy.count(),
                                         handler, data);

    if (rc < 0)
    {
        throw exception::SdBusError(-rc, __func__);
    }

    return s;
}

int event::run_wakeup(sd_event_source*, int, uint32_t, void* data)
{
    auto self = static_cast<event*>(data);
    self->run_condition.ack();

    return 0;
}

template <bool Signal>
std::unique_lock<std::recursive_mutex> event::obtain_lock()
{
    std::unique_lock<std::recursive_mutex> l{this->lock, std::defer_lock_t()};
    if constexpr (Signal)
    {
        if (!l.try_lock())
        {
            run_condition.signal();
            l.lock();
        }
    }
    else
    {
        l.lock();
    }

    return l;
}

} // namespace sdbusplus::event
