// Kyler Olsen
// YREA SLS
// File
// November 2025

#include <stdio.h>

#include "sls/file.h"
#include "sls/bool.h"
#include "sls/string.h"
#include "sls/interpreter.h"

Boolean exec_file(InterpreterState *interpreter_state, SlsStr filename) {
    FILE *file_o = fopen(filename.str, "r");
    if (file_o == NULL) {
        printf("Cannot read file: %s\n", filename.str);
        return FALSE;
    }

    if (fseek(file_o, 0, SEEK_END)) return FALSE;
    size_t file_length = ftell(file_o);
    rewind(file_o);

    LexerInfo lexer_info;
    SlsStr code = sls_str_new(file_length);
    for (size_t i = 0; i < file_length; i++) {
        int character = fgetc(file_o);
        if (character == EOF) return FALSE;
        else code.str[i] = (char)character;
    }
    init_lexer(&lexer_info, filename, code);

    LexerResult result = lexical_analysis(&lexer_info);
    if (result.type == SLS_ERROR) {
        printf("%s\n", result.error.message.str);
        sls_str_free(&result.error.message);
        return FALSE;
    } else {
        LexerTokenResult *head = result.result;
        while (head) {
            if (head->type == SLS_ERROR) {
                printf("%s\n", head->error.message.str);
                sls_str_free(&result.error.message);
                clean_token_result(result.result);
                return FALSE;
            } else if (!execute(interpreter_state, head)) {
                printf("A runtime error occurred!\n");
                break;
            }
            head = head->next;
        }
        clean_token_result(result.result);
    }
    sls_str_free(&code);

    if (fclose(file_o)) return FALSE;
    else return TRUE;
}

int file(SlsStr filename) {
    printf("Executing file: %s\n", filename.str);
    InterpreterState *interpreter_state = interpreter_create();
    if (interpreter_state == NULL) return 1;
    Boolean success = exec_file(interpreter_state, filename);
    interpreter_delete(interpreter_state);
    if (success) return 0;
    else return 1;
}
