#ifndef TILE_IO_EVENT_LOOP_H
#define TILE_IO_EVENT_LOOP_H

#pragma once

#include "tile/base/handle.h"
#include "tile/base/thread/mutex.h"
#include "tile/io/descriptor.h"

#include <list>

namespace tile {
class EventLoop {
public:
    EventLoop();
    ~EventLoop();

    void AttachDescriptor(Descriptor *desc, bool enabled = true);
    void EnableDescriptor(Descriptor *desc);

    void RearmDescriptor(Descriptor *desc);

    void DisabledDescriptor(Descriptor *desc);

    void DetachDescriptor(Descriptor *desc);

    void AddTask(std::function<void()> &&cb);

    void Barrier();

    // Won't return until `Stop()` is called.
    void Run();

    void Stop();
    void Join();

    static EventLoop *Current();

private:
    void WaitAndRunEvents(std::chrono::milliseconds wait_for);
    void RunUserTasks();

private:
    std::atomic<bool> exiting_{false};

    Mutex tasks_lock_;
    std::list<std::function<void()>> tasks_;
};

}// namespace tile

#endif// TILE_IO_EVENT_LOOP_H
