#include "uveventloop.h"

namespace myapp::async {

std::shared_ptr<event_loop> event_loop::create()
{
    return std::make_shared<uv_event_loop>(
        uvw::Loop::create());
}

std::shared_ptr<event_loop> event_loop::getDefault()
{
    static std::weak_ptr<uv_event_loop> ref;
    std::shared_ptr<uv_event_loop> default_;

    if (!ref.expired())
    {
        default_ = ref.lock();
    }
    else
    {
        default_ = std::make_shared<uv_event_loop>(
            uvw::Loop::getDefault());
        ref = default_;
    }

    return default_;
}

uv_event_loop::uv_event_loop(std::shared_ptr<uvw::Loop> loop)
  : loop_(std::move(loop))
{
}

uv_event_loop::~uv_event_loop()
{
    loop_->walk([](uvw::BaseHandle& handle)
    {
        handle.close();
    });

    run_once();
}

uvw::Loop& uv_event_loop::handle() noexcept
{
    return *loop_;
}

uvw::Loop const& uv_event_loop::handle() const noexcept
{
    return *loop_;
}

void uv_event_loop::run()
{
    loop_->run();
}

void uv_event_loop::run_once()
{
    loop_->run<uvw::Loop::Mode::ONCE>();
}

void uv_event_loop::stop()
{
    loop_->stop();
}

} /* namespace myapp::async */
