#include <stdint.h>

#include "coduo_engine_structs.h"
#include "../core_memory/core_memory_private.h"
#include "sv_globals_private.h"

#define SV_GAME_HUNK_COM_ERROR_DROP 1

static const char svGameHunkAllocError[] =
    "\x15"
    "trap_Hunk_Alloc can only be called in G_InitGame and the first few frames "
    "of G_RunFrame\n";
static const char svGameHunkAllocLowError[] =
    "\x15"
    "trap_Hunk_AllocLow can only be called in G_InitGame and the first few "
    "frames of G_RunFrame\n";
static const char svGameHunkAllocAlignError[] =
    "\x15"
    "trap_Hunk_AllocAlign can only be called in G_InitGame and the first few "
    "frames of G_RunFrame\n";
static const char svGameHunkAllocLowAlignError[] =
    "\x15"
    "trap_Hunk_AllocLowAlign can only be called in G_InitGame and the first "
    "few frames of G_RunFrame\n";

/* NOT_FROM_ORIGINAL_SOURCE: shared guard for four identical trap checks. */
static void coduomp_check_game_hunk_alloc_allowed(const char *message)
{
    if (sv.state != CODUO_SS_LOADING) {
        Com_Error(SV_GAME_HUNK_COM_ERROR_DROP, message);
    }
}

void *SV_GameHunkAlloc(size_t size)
{
    coduomp_check_game_hunk_alloc_allowed(svGameHunkAllocError);
    return Hunk_Alloc(size);
}

void *SV_GameHunkAllocLow(size_t size)
{
    coduomp_check_game_hunk_alloc_allowed(svGameHunkAllocLowError);
    return Hunk_AllocLow(size);
}

void *SV_GameHunkAllocAlign(size_t size,
                            int32_t alignment)
{
    coduomp_check_game_hunk_alloc_allowed(svGameHunkAllocAlignError);
    return Hunk_AllocAlign(size, alignment);
}

void *SV_GameHunkAllocLowAlign(size_t size,
                               int32_t alignment)
{
    coduomp_check_game_hunk_alloc_allowed(svGameHunkAllocLowAlignError);
    return Hunk_AllocLowAlign(size, alignment);
}

void *SV_GameHunkAllocateTempMemory(size_t size)
{
    return Hunk_AllocateTempMemory(size);
}

void SV_GameHunkFreeTempMemory(void *ptr)
{
    Hunk_FreeTempMemory(ptr);
}
