/* Copyright (c) 2020-2022 The Creators of Simphone

   See the file COPYING.LESSER.txt for copying permission.
*/

#ifndef _SYSTEM_H_
#define _SYSTEM_H_

#include "simtypes.h"

/* install or uninstall system crash handler */
void system_init_crash (int mask);

/* set "type of service" field in ip header */
#ifdef _WIN32
simbool system_qos_set (simsocket sock, void *sin);
void system_qos_unset (simsocket sock);
#else
#define system_qos_set(sock, sin) false
#define system_qos_unset(sock)
#endif

/* return number of SMP units (cpu cores) */
int sim_system_cpu_count (void);

/* return used cpu time (number of nanoseconds). cpu is SYSTEM_CPU_TIME_xxx; thread should be NULL */
simunsigned sim_system_cpu_get (int cpu, void *thread);

#define SYSTEM_CPU_TIME_PROCESS 0 /* current process */
#define SYSTEM_CPU_TIME_THREAD 1  /* current thread (tid is NULL) */
#define SYSTEM_CPU_TIME_CYCLES 3  /* current thread (high resolution) */

/* return the amount of available if (total = false) or total memory in the system */
simnumber sim_system_get_memory (simbool total);

/* return file hash/size and name of executable in UTF-8 as *exe (caller must call sim_string_free on returned *exe)
   return nil or/and nil *exe if unknown */
simtype sim_system_get_exe (simtype *exe);

/* return unique identifier of pathname. caller must call string_buffer_free */
simtype sim_system_dir_get_id (const void *pathname);

/* read directory entries */
void *sim_system_dir_open (const char *pathname);
int sim_system_dir_close (void *dir);
char *sim_system_dir_read (void *dir);

/* thread to detect audio device insertion or removal */
simbool sim_system_pnp_cancel (void); /* skip next device event */
void system_pnp_start (void);
void system_pnp_stop_ (void);

/* return number of milliseconds elapsed since an undefined but unchanging point in time */
simunsigned system_get_tick (void);

extern int system_version_major, system_version_minor, system_version_patch;

/* return name of (insecure) operating system and its *version and *release */
char *sim_system_get_version (char *version, char *release);

/* lock memory into RAM if allocating mb megabytes is OK. if mb is zero, unlock memory from RAM */
int system_init_memory (int megabytes);

/* preinitialize random_public with randomness from the system */
void system_init_random (void);

/* enable application to work across firewall. NULL error to preinitialize */
int system_init_ (simbool install, int *error);

/* free allocated memory */
void system_uninit (void);

/* log stack usage by current thread */
void _system_log_stack (const char *module, int level, simunsigned created, const char *function);

#endif
