#include <stdio.h>
#include <stddef.h>
#include "coroutine.h"
#include "generator.h"
#include "asleep.h"
#include "task.h"

#include <dirent.h> 
#include <string.h>
#include <stdlib.h>
#include <time.h>

#define DEMO_STACK_SIZE (8192*sizeof(void *))

typedef struct asynctestpartparam {
    char *name;
    float delay;
    int count;
} asynctestpartparam;

bool asynctestpart(void *param, void **res){
    (void)res;
    asynctestpartparam *spec = (asynctestpartparam *)param;
    printf("%s started\n", spec->name);

    for (int i=0; i < spec->count; ++i){
        ASleep(spec->delay, NULL);
        printf("%s %d\n", spec->name, i);
    }
    return false;
}

bool asynctest(void *param, void **res){
    (void)param;
    (void)res;
    printf("async test started\n");

    asynctestpartparam task1param = {
        "First",
        0.5f,
        5
    };
    Task task1;
    Task_ctor(&task1, DEMO_STACK_SIZE, asynctestpart, &task1param);
    printf("task1 going\n");

    asynctestpartparam task2param = {
        "Second",
        0.75f,
        8
    };
    Task *task2 = Task_New(DEMO_STACK_SIZE, asynctestpart, &task2param);
    printf("task2 going\n");

    bool canceled1 = Task_Await(&task1, NULL);
    bool canceled2 = Task_Await(task2, NULL);

    Task_Delete(task2);
    Task_dtor(&task1);

    printf("Tasks complete %d %d\n", canceled1, canceled2);
    return canceled1 | canceled2;
}

int main(int argc, char *argv[]) {
    (void)argc;
    (void)argv;

    ASleep_StartSystem();
    Coroutine_StartSystem();
    void *res = NULL;
    bool canceled = Task_Run(DEMO_STACK_SIZE, asynctest, NULL, &res);
    Coroutine_StopSystem();
    ASleep_StopSystem();

    printf("Async result %d:%p\n", canceled, res);
}
