#include <time.h>
#include <signal.h>

#include "xlisp.h"

static volatile int have_intr = 0;

void osinit (char *banner) {
    printf("%s\n", banner);
}

int osrand (int x) {
    return rand() % x;
}

int osgetc (FILE *fp) {
    int c = getc(fp);
    if ((c == EOF) && feof(fp)) {
        clearerr(fp);
    }
    return c;
}

void osputc (int c, FILE *fp) {
    putc(c, fp);
}

void oscheck (void) {
    if(have_intr) {
        have_intr = 0;
        // osflush();
        xlbreak("BREAK", s_unbound);
    }
}

static void sigint_handler (int sig) {
    (void)sig;
    have_intr = 1;
}

NODE *xtime (NODE *args) {
    NODE *form, *val;
    NODE ***oldstk;
    char buf[100];
    unsigned long long ti;

    oldstk = xlsave(&form, &val, 0);

    form = xlarg(&args);
    xllastarg(args);
    ti = (unsigned long long)clock();
    val = xleval(form);
    ti = (unsigned long long)clock() - ti;
    ti = (1000 * ti) / CLOCKS_PER_SEC;
    stdputstr(";; ");
    xlprint(getvalue(s_stdout), form, 0);
    sprintf(buf, " took %llums\n", (unsigned long long)ti);
    stdputstr(buf);

    xlstack = oldstk;
    return val;
}

void osfinit (void) {
    signal(SIGINT, sigint_handler);
    xlsubr("TIME", FSUBR, xtime);
}

void osfinish (void) {
  printf("Take care.\n");
  fflush(stdout);
}
