#include <errno.h>
#include <luna.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/syscall.h>
#include <unistd.h>

typedef long ssize_t;

int print_version()
{
    char version[4096];

    FILE* verfile = fopen("/dev/version", "r");
    if (!verfile)
    {
        perror("fopen");
        return 1;
    }

    size_t nread = fread(version, 4096, 1, verfile);
    if (ferror(verfile))
    {
        perror("fread");
        return 1;
    }

    version[nread] = 0;

    if (fclose(verfile) < 0)
    {
        perror("fclose");
        return 1;
    }

    printf("Your kernel version is %s\n\n", version);

    return 0;
}

int main()
{
    if (gettid() == 0) // why are we the idle task?
    {
        fprintf(stderr, "SHENANIGANS! init is tid 0 (which is reserved for the idle task)\n");
        return 1;
    }

    FILE* serial = fopen("/dev/serial", "r");
    if (!serial)
    {
        perror("fopen");
        return 1;
    }
    if (fputs("Hello from init!\n", serial) < 0)
    {
        perror("fputs");
        return 1;
    }
    if (fclose(serial) < 0)
    {
        perror("fclose");
        return 1;
    }

    printf("Welcome to Luna!\n");

    printf("Running as tid %ld\n\n", gettid());

    sleep(1);

    if (print_version()) return 1;

    sleep(2);

    const char* filename = "/sys/config";

    printf("Opening %s for reading...\n", filename);

    FILE* config = fopen(filename, "r");
    if (!config)
    {
        perror("fopen");
        return 1;
    }

    if (fseek(config, 0, SEEK_END) < 0)
    {
        perror("fseek");
        return 1;
    }

    long offset = ftell(config);
    if (offset < 0)
    {
        perror("ftell");
        return 1;
    }

    printf("%s is %ld bytes long\n", filename, offset);

    rewind(config);

    char buf[4096];

    size_t nread = fread(buf, sizeof(buf), 1, config);
    if (ferror(config)) { perror("fread"); }
    else
    {
        buf[nread] = 0;

        printf("Read %zd bytes\n\n", nread);

        printf("%s", buf);
    }

    if (fclose(config) < 0) { perror("fclose"); }

    printf("\n\nGot random number %d\n\n", rand());

    sleep(2);

    printf("Press any key to restart.\n\n");

    int ferr = fileno(stderr);
    int newerr = dup(ferr);
    if (newerr < 0)
    {
        perror("dup");
        return 1;
    }
    FILE* new_stderr = fdopen(newerr, "rw");
    if (!new_stderr)
    {
        perror("fdopen");
        return 1;
    }

    fprintf(new_stderr, "Bye!\n\n");

    fclose(new_stderr);

    const char* pathname = "/etc";

    printf("Creating directory %s\n", pathname);

    if (mkdir(pathname, 0) < 0)
    {
        perror("mkdir");
        return 1;
    }

    printf("Success!!\n");

    const char* execpath = "/bin/sym";

    printf("Spawning %s\n", execpath);

    pid_t child;

    if ((child = spawn(execpath)) < 0)
    {
        perror("spawn");
        return 1;
    }

    printf("Success!! Got PID %ld\n", child);

    return 1;
}