// Arena Allocator
// Supports multiple arenas that can be destroyed independently
// Much more practical than a simple bump allocator

// Global heap management
static heap_start: u32 = 0x30000;
static heap_end: u32 = 0x40000;
static heap_current: u32 = 0x30000;

// Arena structure (stored at the start of each arena):
// [0-3]: start_address (u32)
// [4-7]: current_position (u32)
// [8-11]: end_address (u32)
// Total header size: 12 bytes

// Create a new arena with given size
// Returns pointer to arena handle (or 0 if failed)
fn arena_create(size: u32) -> u32 {
    let total_size: u32 = size + 12;
    let arena_ptr: u32 = heap_current;
    let new_current: u32 = arena_ptr + total_size;

    // Check if we have space
    if new_current > heap_end {
        return 0;
    }

    // Calculate arena data region
    let data_start: u32 = arena_ptr + 12;
    let data_end: u32 = arena_ptr + total_size;

    // Initialize arena header
    // Note: In real implementation, you'd use pointer writes here
    // For now, using placeholder comments:
    *arena_ptr = data_start;        // start_address
    *(arena_ptr + 4) = data_start;  // current_position
    *(arena_ptr + 8) = data_end;    // end_address

    heap_current = new_current;

    return arena_ptr;
}

// Allocate from an arena
// Returns pointer to allocated memory (or 0 if failed)
fn arena_alloc(arena: u32, size: u32) -> u32 {
    // Read current position from arena
    let current: u32 = *(arena + 4);
    let end: u32 = *(arena + 8);

    let new_current: u32 = current + size;

    // Check if arena has space
    if new_current > end {
        return 0;
    }

    // Update current position in arena
    *(arena + 4) = new_current;

    return current;
}

// Destroy an arena (in bump allocator, this is a no-op)
// In a real allocator, you'd mark the memory as free
fn arena_destroy(arena: u32) {
    // In a true allocator, mark memory as reusable
    // For bump allocator, we can't reclaim memory
    // unless we destroy ALL arenas and reset
    return 0;
}

// Reset entire heap (destroys ALL arenas)
fn reset_all() {
    heap_current = heap_start;
    return 0;
}
