#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "core.h"
#include "ast.h"
#include "optimizer.h"
#include "codegen.h"
#include "elf.h"
#include "util.h"

int core_compile(Config *cfg) {
    char *source = util_read_file(cfg->input);
    if (!source) {
        fprintf(stderr, "error: cannot read %s\n", cfg->input);
        return 1;
    }

    Stmt *ast = ast_parse(source);
    free(source);
    if (!ast) {
        fprintf(stderr, "error: no valid statements\n");
        return 1;
    }

    if (cfg->optimize_level > 0) {
        ast = optimizer_run(ast, cfg->optimize_level);
    }

    CodeBuffer *text = codebuf_new();
    CodeBuffer *rodata = codebuf_new();
    CodeBuffer *data = codebuf_new();
    VarInfo vinfo = {0};

    if (codegen_arm64(ast, text, rodata, data, &vinfo, cfg->optimize_level) != 0) {
        codebuf_free(text); codebuf_free(rodata); codebuf_free(data);
        ast_free(ast);
        return 1;
    }

    int tsz = text->size, rsz = rodata->size, dsz = data->size;

    int ret = elf_write(cfg->output, text, rodata, data);
    codebuf_free(text); codebuf_free(rodata); codebuf_free(data);
    ast_free(ast);

    if (ret != 0) {
        fprintf(stderr, "error: ELF write failed\n");
        return 1;
    }

    for (int i = 0; i < vinfo.var_count; i++) free(vinfo.var_names[i]);

    printf("ok: %s (O%d, text=%d, rodata=%d, data=%d)\n",
           cfg->output, cfg->optimize_level, tsz, rsz, dsz);
    return 0;
}
