#ifndef INCLUDED_AWAITABLE_
#define INCLUDED_AWAITABLE_

#include <iostream>

#include "../awaiter/awaiter.h"

template <typename Handler>
struct Awaitable
{
    std::coroutine_handle<> d_handle;

    Awaitable(Handler &handler, char const *from, char ch);
    Awaitable(Handler &handler, char const *from, int chNr);
    Awaitable(Handler &handler, char const *from);

    Awaiter operator co_await();
};

template <typename Handler>
inline Awaitable<Handler>::Awaitable(Handler &handler, char const *from,
                                                       char ch)
:
    d_handle(handler.handle())
{
    std::cout << "at `" << ch << "' from " << from << " to " <<
                handler.name() << '\n';
}

template <typename Handler>
inline Awaitable<Handler>::Awaitable(Handler &handler, char const *from,
                                                       int chNr)
:
    d_handle(handler.handle())
{
    std::cout << "at #" << chNr << " from " << from << " to " <<
                handler.name() << '\n';
}

template <typename Handler>
inline Awaitable<Handler>::Awaitable(Handler &handler, char const *from)
:
    d_handle(handler.handle())
{
    std::cout << "at EOF at " << from << ": Done\n";
}

template <typename Handler>
inline Awaiter Awaitable<Handler>::operator co_await()
{
    return Awaiter{ d_handle };
}

#endif
