#pragma once

#include "wrap-set.hpp"

#include "streambuffer.hpp"

#include <cstdint>

class SchedEntry : public eng::nevernew  {
private:
    friend class Schedule;
    int64_t clock_;
    int64_t thread_id_;
    int64_t place_id_;

public:
    int64_t clock() const { return clock_; }
    int64_t thread_id() const { return thread_id_; }
    int64_t place_id() const { return place_id_; }

    SchedEntry(int64_t clk, int64_t thid, int64_t plid) {
        clock_ = clk;
        thread_id_ = thid;
        place_id_ = plid;
    }

    bool operator < (const SchedEntry &other) const;

    eng::string debug_string() const;
};

class Schedule : public eng::nevernew  {
private:
    eng::set<SchedEntry> schedule_;
public:
    void add(int64_t clk, int64_t thid, int64_t plid);
    bool ready(int64_t clk) const;
    bool empty() const { return schedule_.empty(); }
    SchedEntry pop();
    eng::string debug_string();

    void serialize(StreamBuffer *sb);
    void deserialize(StreamBuffer *sb);
};


