#ifndef CODUO_CORE_RUNTIME_PRIVATE_H
#define CODUO_CORE_RUNTIME_PRIVATE_H

#include <float.h>
#include <setjmp.h>
#include <stdarg.h>
#include <stddef.h>
#include <stdint.h>
#if !defined(_WIN32)
#include <termios.h>
#endif

#include "coduo_engine_structs.h"
#include "com_sprintf.h"
#include "q_string_compare.h"

#if defined(_WIN32)
typedef jmp_buf coduo_jump_buffer_t;
typedef struct coduo_terminal_state_s {
    int unused;
} coduo_terminal_state_t;
#define CODUO_SETJMP(buffer, saveMask) setjmp(buffer)
#else
typedef sigjmp_buf coduo_jump_buffer_t;
typedef struct termios coduo_terminal_state_t;
#define CODUO_SETJMP(buffer, saveMask) sigsetjmp(buffer, saveMask)
#endif

struct stat;

#define CODUO_COM_PRINT_CHANNEL_DEFAULT 0
#define CODUO_COM_PRINT_CHANNEL_DEVELOPER 4
#define CODUO_COM_PB_PRINT_LIMIT 4096
#define CODUO_COM_PRINT_FORMAT_BUFFER_SIZE 0x1000
#define CODUO_COM_REDIRECT_NUL_BYTE 1
#define CODUO_COM_DEDICATED_DISABLED 0
#define CODUO_COM_LOGFILE_DISABLED 0
#define CODUO_COM_LOG_FILE_CLOSED_HANDLE 0
#define CODUO_COM_LOGFILE_SYNC_THRESHOLD 1
#define CODUO_COM_CONSOLE_STUB_ARG2 0
#define CODUO_COM_CONSOLE_STUB_ARG3 0

#define SYS_STDIN_FILE_DESCRIPTOR 0

enum {
    SYS_DELAYED_PROCESS_COMMAND_SIZE = 1024,
    SYS_STDIN_INACTIVE = 0,
    SYS_STDIN_ACTIVE = 1,
    SYS_TTY_HISTORY_RESET_CURSOR = -1
};
#define SYS_F_GETFL_COMMAND 3
#define SYS_F_GETFL_UNUSED_ARGUMENT 0
#define SYS_F_SETFL_COMMAND 4
#define SYS_LINUX_O_NONBLOCK 0x800
#define SYS_ERROR_MESSAGE_BUFFER_SIZE 1024
#define SYS_WARNING_MESSAGE_BUFFER_SIZE 1024
#define SYS_ERROR_EXIT_STATUS 1
#define SYS_OUT_OF_MEMORY_EXIT_STATUS -1

#ifndef CODUO_ENGINE_HOST_LONG_DOUBLE_IS_X87
#define CODUO_ENGINE_HOST_LONG_DOUBLE_IS_X87 \
    (LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384)
#endif

#ifndef CODUO_ENGINE_HAS_X87_INLINE_ASM
#if (defined(__i386__) || defined(__i486__) || defined(__i586__) || \
     defined(__i686__) || defined(__x86_64__)) && \
    CODUO_ENGINE_HOST_LONG_DOUBLE_IS_X87 && \
    (defined(__GNUC__) || defined(__clang__))
#define CODUO_ENGINE_HAS_X87_INLINE_ASM 1
#else
#define CODUO_ENGINE_HAS_X87_INLINE_ASM 0
#endif
#endif

extern cvar_t *dedicated;
extern cvar_t *developer;
extern cvar_t *logfile;
extern cvar_t *ttycon;
extern cvar_t *cl_shownet;
extern cvar_t *com_journal;
extern cvar_t *host_cvar_com_animCheck_pointer_slot;
extern cvar_t *host_cvar_com_maxfps_pointer_slot;
extern cvar_t *host_cvar_com_speeds_pointer_slot;
extern cvar_t *host_cvar_cl_running_pointer_slot;
extern cvar_t *host_cvar_developer_script_pointer_slot;
extern cvar_t *host_cvar_fixedtime_pointer_slot;
extern cvar_t *host_cvar_sv_running_pointer_slot;
extern cvar_t *host_cvar_timescale_pointer_slot;
extern cvar_t *host_cvar_viewlog_pointer_slot;

extern qboolean com_configAutowriteEnabled;
extern coduo_jump_buffer_t com_frameAbortContext;
extern int32_t com_errorEntered;
extern int32_t com_frameNumber;
extern int32_t com_journalDataFile;
extern int32_t com_journalFile;
extern int32_t com_logFileHandle;
extern int32_t com_hunkUsed;
extern int32_t com_timeBackend;
extern int32_t com_timeFrontend;
extern int32_t com_timeGame;
extern qboolean com_printMessageOpeningLog;
extern qboolean com_vprintfOpeningLog;
extern char *com_redirectBuffer;
extern int32_t com_redirectBufferSize;
extern coduo_com_redirect_flush_t com_redirectFlush;
extern int32_t host_sv_serverId_source;
extern int32_t host_sv_frame_running_flag;

extern int32_t hunk_logFile;
extern coduo_hunk_log_block_t *hunk_logBlocks;
extern size_t hunk_totalZoneSize;

extern int32_t sys_stdinActive;
extern int32_t sys_ttyConsoleActive;
extern uint16_t sys_snapVectorSavedFpuControlWord;
extern uint16_t sys_snapVectorFpuControlWord;
extern coduo_terminal_state_t sys_ttyOriginalTermios;
extern int32_t sys_ttyEraseChar;
extern int32_t sys_ttyEofChar;
extern int32_t
    sys_ttyOutputSuppressionDepth;
extern int32_t sys_ttyHistoryCursor;
extern int32_t sys_ttyHistoryCount;
extern coduo_sys_tty_input_return_buffer_t sys_ttyInputReturnBuffer;
extern coduo_sys_tty_line_t sys_ttyCurrentLine;
extern coduo_sys_tty_history_t sys_ttyHistory;
extern coduo_sys_event_queue_t sys_eventQueue;
extern int32_t sys_eventQueueProducer;
extern int32_t sys_eventQueueConsumer;
extern uint8_t sys_packetBuffer[CODUO_MAX_MSGLEN];
extern char com_netadrString[64];
extern char sys_delayedProcessCommand[SYS_DELAYED_PROCESS_COMMAND_SIZE];

void PB_Print(const char *message, int32_t limit);
void PB_StartServer(void);
void PB_RunServerFrame(void);
void Cbuf_ExecuteText(coduo_cbuf_exec_when_t exec_when, const char *text);
cvar_t *Cvar_Get(const char *name, const char *value,
                              uint32_t flags);
cvar_t *Cvar_Set(const char *name, const char *value);
const char *Cvar_VariableString(const char *name);
void CL_ConsolePrint(int32_t channel, const char *message,
                     int32_t arg2, int32_t arg3);
void CL_MapLoading(void);
qboolean CL_CDKeyValidate(const char *cdkey, const char *hash);
void CL_Frame(int32_t rawMsec, int32_t scaledMsec);
void CL_MouseEvent(int32_t value,
                   int32_t value2,
                   int32_t time);
void CL_PacketEvent(netadr_t from, msg_t *msg,
                    int32_t time);
void CL_CharEvent(int32_t value);
void CL_KeyEvent(int32_t value,
                 int32_t value2,
                 int32_t time);
void CL_JoystickEvent(int32_t value,
                      int32_t value2,
                      int32_t time);
void Key_WriteBindings(int32_t handle);
void Sys_Print(const char *message);
qboolean FS_Initialized(void);
int32_t FS_FOpenFileWrite(const char *qpath);
int32_t FS_FOpenTextFileWrite(const char *qpath);
void FS_SetHandleUnbuffered(int32_t handle);
int FS_LoadCount(void);
int32_t FS_Read(void *buffer, int32_t length, int32_t handle);
int32_t FS_Write(const void *buffer, int32_t length,
                 int32_t handle);
int32_t FS_Seek(int32_t handle, long offset, int32_t origin);
void Cmd_Shutdown(void);
void Cvar_Shutdown(void);
/*
 * Checked 2026-06-29: these remaining FUN_ hooks are default-named no-op or
 * identity client/platform stubs in the Linux dedicated binary. Their bodies
 * and current callers do not prove source-level names.
 */
void Com_InitZoneMemory(void);
void Com_SetRecommended(void);
void CL_Disconnect(qboolean showMainMenu);
void CL_Shutdown(void);
void CL_ShutdownAll(void);
void CL_InitKeyCommands(void);
void CL_StartHunkUsers(void);
void CL_CDDialog(void);
void Sys_Input(void);
void Sys_SendKeyEvents(void);
void Com_ClearServerFrameRunningFlag(void);
void Sys_TTYResetLine(coduo_sys_tty_line_t *line);
void Sys_TTYCompleteLine(coduo_sys_tty_line_t *line);
void Sys_TTYDrainInput(void);
void Sys_TTYErasePreviousChar(void);
void Sys_TTYHideInputLine(void);
void Sys_TTYShowInputLine(void);
const char *NET_ErrorString(void);
void Sys_TTYStoreHistoryLine(coduo_sys_tty_line_t *line);
coduo_sys_tty_line_t *Sys_TTYPreviousHistoryLine(void);
coduo_sys_tty_line_t *Sys_TTYNextHistoryLine(void);
void Sys_ShowConsole(int32_t visLevel, qboolean quitOnClose);
/*
 * Checked 2026-06-29: the remaining Sys_* address-band FUN_ hooks are
 * constant-return or empty platform hooks; no source-level names are proven by
 * the binary.
 */
int32_t FUN_080cb267(void);
void FUN_080cb271(void);
void FUN_080cb276(void);
void CL_Init(void);
void Hunk_ClearData(void);
void Com_InitServerRuntimePools(void);

void Com_PrintMessage(int32_t channel, const char *message);
int32_t Com_VPrintf(const char *format, va_list args);
int32_t Com_Milliseconds(void);
int32_t Com_ModifyMsec(int32_t msec);
int Com_AddToString(const char *src, char *dest, int offset, int destsize,
                    qboolean allowIncomplete);
int32_t Com_EventLoop(void);
void *Z_Malloc(size_t size);
void Z_Free(void *ptr);
void *Hunk_Alloc(size_t size);
void Com_Error(int32_t code, const char *format, ...);
void Com_ErrorCleanup(void);
void Com_Printf(const char *format, ...);
void Com_DPrintf(const char *format, ...);
void Com_BeginRedirect(char *buffer, int bufferSize,
                       coduo_com_redirect_flush_t flush);
void Com_EndRedirect(void);
void Com_ClearTempMemory(void);
void *Hunk_AllocateTempMemoryHighInternal(size_t size);
void Hunk_ClearTempMemory(void);
void Hunk_ClearTempMemoryHigh(void);
void Hunk_Clear(void);
void Hunk_CommitTempMemory(void);
void Hunk_ClearToLowTempMark(void);
void Hunk_SetLowTempMark(void);
void Com_LogPrintf(const char *format, ...);
void Com_Shutdown(const char *finalMessage);
void Com_Init(char *commandLine);
void Com_Frame(void);
void Com_ParseCommandLine(char *commandLine);
void Com_StartupVariable(const char *name);
qboolean Com_AddStartupCommands(void);
void Com_InitJournaling(void);
int32_t Com_ApplyConfigureFileChecksum(void);
void Com_InitPushEvent(void);
void Com_InitScriptRuntime(void);
void Hunk_InitMemory(void);
void Com_Quit_f(void);
void Com_Error_f(void);
void Com_Freeze_f(void);
void Com_Crash_f(void);
void Com_WriteConfig_f(void);
void Com_WriteDefaults_f(void);
void Sys_Error(const char *format, ...);
int32_t Sys_Milliseconds(void);
char *Sys_ConsoleInput(void);
const char *Sys_Cwd(void);
void Sys_Init(void);
void Sys_CheckCrashOrRerun(void);
int32_t Sys_GetProcessorId(void);
qboolean Sys_InfoChanged(void);
qboolean Sys_ConfigureChecksumChanged(int32_t checksum);
qboolean Sys_GetPacket(netadr_t *from, msg_t *msg);
qboolean Sys_IsLANAddress(netadr_t adr);
qboolean Sys_StringToAdr(const char *text, netadr_t *adr);
void Sys_SendPacket(int32_t length,
                    const void *data,
                    netadr_t to);
void Sys_SendPacketByName(const char *address, uint16_t port,
                          const void *data, int32_t length);
void NET_Sleep(int32_t msec);
sysEvent_t Sys_GetEvent(void);
void *Com_ZoneDebugAlloc(size_t size);
void *Com_ZoneDebugAllocClear(size_t size);
void Com_DebugFree(void *ptr);
int Q_isprint(int value);
int Q_islower(int value);
int Q_isupper(int value);
int Q_isalpha(int value);
int Q_isnumeric(int value);
int Q_isalphanumeric(int value);
int Q_isforfilename(int value);
/*
 * Checked 2026-06-29: one-call identity helper used by Netchan_Process when
 * rewriting a reassembled fragment sequence header. The call site matches the
 * LittleLong(sequence) netchan pattern, but this binary already has a separate
 * recovered LittleLong at 0x0808387c and no symbol proves this helper's source
 * name.
 */
int32_t FUN_08085130(int32_t value);
char *Q_strrchr(const char *string, int value);
void Q_strncpyz(char *dest, const char *src, int destsize);
int Q_strncasecmp(const char *left, const char *right, int count);
int Q_strcasecmp(const char *left, const char *right);
char *Q_strlwr(char *string);
char *Q_strupr(char *string);
void Q_strcat(char *dest, int size, const char *src);
int Q_DrawStrlen(const char *string);
char *Q_CleanStr(char *string);
int Q_CleanCharacter(int value);
char *va(const char *format, ...);
float *tv(float x, float y, float z);
char *Com_GetLastTokenPos(void);
void Com_ResetParseSessions(void);
void Com_BeginParseSession(const char *name);
void Com_EndParseSession(void);
void Com_UngetToken(void);
qboolean Com_SafeMode(void);
char *Com_Parse(char **data);
char *Com_ParseOnLine(char **data);
void Com_SetCSV(qboolean csv);
void Com_MatchToken(char **data, const char *match, qboolean warning);
qboolean Com_SkipBracedSection(char **data, int32_t depth);
void Com_SkipRestOfLine(char **data);
char *Com_ParseRestOfLine(char **data);
int32_t Com_Compress(char *data);
float Com_ParseFloat(char **data);
int32_t Com_ParseInt(char **data);
void Com_Parse1DMatrix(char **data, int32_t x, float *m);
void Com_Parse2DMatrix(char **data, int32_t y, int32_t x, float *m);
void Com_Parse3DMatrix(char **data, int32_t z, int32_t y, int32_t x,
                       float *m);
char ColorIndex(char value);
float Com_Clamp(float min, float max, float value);
char *Com_SkipPath(char *path);
void Com_StripExtension(const char *in, char *out);
void Com_StripFilename(const char *in, char *out);
void Com_DefaultExtension(char *path, int maxSize, const char *extension);
char *CopyString(const char *text);
qboolean Com_FilterPath(const char *filter, const char *name,
                        qboolean caseSensitive);
int32_t Com_BitCheck(const uint32_t *bits, int32_t bitNum);
void Com_BitSet(uint32_t *bits, int32_t bitNum);
void Com_BitClear(uint32_t *bits, int32_t bitNum);
typedef struct coduo_uint64_pair_s {
    uint32_t low;
    uint32_t high;
} coduo_uint64_pair_t;
int32_t BigShort(int16_t value);
int32_t BigLong(int32_t value);
coduo_uint64_pair_t BigLong64(coduo_uint64_pair_t value);
coduo_uint64_pair_t LittleLong64(coduo_uint64_pair_t value);
float BigFloat(float value);
int32_t ShortSwap(int16_t value);
int32_t ShortNoSwap(int16_t value);
int32_t LongSwap(int32_t value);
int32_t LongNoSwap(int32_t value);
coduo_uint64_pair_t Long64Swap(coduo_uint64_pair_t value);
coduo_uint64_pair_t Long64NoSwap(coduo_uint64_pair_t value);
float FloatSwap(float value);
float FloatNoSwap(float value);
void Swap_Init(void);
const char *Sys_GetCurrentUser(void);
void Sys_SnapVector(vec3_t vector);
void Sys_SnapVectorWithControlWord(vec3_t vector, uint16_t controlWord);
void Sys_InitInput(void);
void Sys_ShutdownInput(void);
void IN_Restart_f(void);
void Sys_ShutdownTerminalConsole(void);
void Sys_InitTerminalConsole(void);
int32_t Sys_Stat(const char *path, struct stat *statbuf);
void Sys_Exit(int status);
void Sys_Quit(void);
void Hunk_Shutdown(void);
void NET_Init(void);
void Com_Close(void);
void MSG_Init(msg_t *msg, uint8_t *data,
              int32_t length);

#endif
