#include "base/base_arena.h"
#include <stdlib.h>

Arena *arena_alloc(U64 cap) {
    U8 *mem = (U8 *)malloc(sizeof(Arena) + cap);
    if (!mem) return NULL;
    Arena *arena = (Arena *)mem;
    arena->base = mem + sizeof(Arena);
    arena->pos = 0;
    arena->cap = cap;
    return arena;
}

void arena_release(Arena *arena) {
    if (arena) free(arena);
}

void *arena_push(Arena *arena, U64 size) {
    U64 aligned = AlignPow2(size, 8);
    if (arena->pos + aligned > arena->cap) {
        Assert(!"Arena overflow");
        return NULL;
    }
    void *result = arena->base + arena->pos;
    arena->pos += aligned;
    MemoryZero(result, aligned);
    return result;
}

void *arena_push_no_zero(Arena *arena, U64 size) {
    U64 aligned = AlignPow2(size, 8);
    if (arena->pos + aligned > arena->cap) {
        Assert(!"Arena overflow");
        return NULL;
    }
    void *result = arena->base + arena->pos;
    arena->pos += aligned;
    return result;
}

U64 arena_pos(Arena *arena) {
    return arena->pos;
}

void arena_pop_to(Arena *arena, U64 pos) {
    if (pos < arena->pos) {
        arena->pos = pos;
    }
}

void arena_clear(Arena *arena) {
    arena->pos = 0;
}
