#include <stdio.h>
#include <unistd.h>
#include <setjmp.h>
#include <sprinter_exit.h>

static void bye1(void) { puts("[atexit] bye1 (registered first, runs last)"); }
static void bye2(void) { puts("[atexit] bye2 (registered second)"); }
static void bye3(void) { puts("[atexit] bye3 (registered third, runs first)"); }

static jmp_buf env;
static int     attempt;

static void might_fail(int n)
{
    printf("  might_fail(%d) running...\n", n);
    if (n == 2) {
        puts("  -> longjmp(env, 42)");
        longjmp(env, 42);
        /* not reached */
    }
    printf("  might_fail(%d) returned normally\n", n);
}

int main(void)
{
    puts("Sprinter runtime features test:");
    puts("");

    /* --- atexit registration --- */
    atexit(bye1);
    atexit(bye2);
    atexit(bye3);

    /* --- setjmp / longjmp --- */
    puts("setjmp/longjmp:");
    int r = setjmp(env);
    if (r == 0) {
        attempt = 1;
        puts("  first arrival from setjmp (r=0)");
        might_fail(attempt);
        attempt = 2;
        might_fail(attempt);
        puts("  -- this line is NOT reached");
    } else {
        printf("  resumed via longjmp, setjmp returned %d (attempt=%d)\n",
               r, attempt);
    }

    /* --- sleep --- */
    puts("");
    puts("sleep(5): pausing 5 seconds...");
    sleep(5);
    puts("  done.");

    /* --- delayms --- */
    puts("");
    puts("delayms(500) x 6: pausing ~3 seconds...");
    for (int i = 0; i < 6; i++) delayms(500);
    puts("  done.");

    puts("");
    puts("Press any key, atexit chain will run after.");
    (void)getchar();

    /* Use exit() to drive the atexit chain (vs returning from main, which
     * doesn't necessarily go through exit() under SDCC). */
    exit(0);
    return 0;
}
