#include "reconfigure.hpp"


typedef struct {
    AioFileIn::Result* aio;
    Config* config;
    bool canceled;
} reconfigure_ctx_t;
static reconfigure_ctx_t* pending = NULL;


static bool reconfigure(void* c) { // true when need to be called again
    reconfigure_ctx_t* ctx = (reconfigure_ctx_t*)c;
    if (!ctx->aio) {
    } else if (ctx->canceled) {
    } else if (ctx->aio->len < 0) {
    } else if (ctx->aio->len == 0) {
        return true;
    } else {
        (void)ctx->config->load(ctx->aio->buf, ctx->aio->len);
    }
    if (pending == ctx) {
        pending = NULL;
    }
    if (ctx->aio) {
        ctx->aio->delInst();
    }
    free(ctx);
    return false;
}


void reconfigure(Config* config) {
    reconfigure_ctx_t* ctx = talloc(reconfigure_ctx_t);
    ctx->config = config;
    ctx->aio = AioFileIn::enqueue(config->fn);
    ctx->canceled = false;
    if (pending) {
        assert(pending->config == config);
        pending->canceled = true;
    }
    pending = ctx;
    if (reconfigure(ctx)) {
        Poller::getInst()->add(&reconfigure, ctx); // maybe could use wakeup?
    }
}