#ifndef CLEONOS_SYSCALL_H
#define CLEONOS_SYSCALL_H

typedef unsigned long long u64;
typedef unsigned long long usize;

#define CLEONOS_FS_NAME_MAX 96ULL
#define CLEONOS_PROC_PATH_MAX 192ULL

#define CLEONOS_PROC_STATE_UNUSED 0ULL
#define CLEONOS_PROC_STATE_PENDING 1ULL
#define CLEONOS_PROC_STATE_RUNNING 2ULL
#define CLEONOS_PROC_STATE_EXITED 3ULL
#define CLEONOS_PROC_STATE_STOPPED 4ULL

#define CLEONOS_SIGKILL 9ULL
#define CLEONOS_SIGTERM 15ULL
#define CLEONOS_SIGCONT 18ULL
#define CLEONOS_SIGSTOP 19ULL

#define CLEONOS_O_RDONLY 0x0000ULL
#define CLEONOS_O_WRONLY 0x0001ULL
#define CLEONOS_O_RDWR 0x0002ULL
#define CLEONOS_O_CREAT 0x0040ULL
#define CLEONOS_O_TRUNC 0x0200ULL
#define CLEONOS_O_APPEND 0x0400ULL
#define CLEONOS_FD_INHERIT ((u64) - 1)

typedef struct cleonos_proc_snapshot {
    u64 pid;
    u64 ppid;
    u64 state;
    u64 started_tick;
    u64 exited_tick;
    u64 exit_status;
    u64 runtime_ticks;
    u64 mem_bytes;
    u64 tty_index;
    u64 last_signal;
    u64 last_fault_vector;
    u64 last_fault_error;
    u64 last_fault_rip;
    char path[CLEONOS_PROC_PATH_MAX];
} cleonos_proc_snapshot;

typedef struct cleonos_fb_info {
    u64 width;
    u64 height;
    u64 pitch;
    u64 bpp;
} cleonos_fb_info;

typedef struct cleonos_mouse_state {
    u64 x;
    u64 y;
    u64 buttons;
    u64 packet_count;
    u64 ready;
} cleonos_mouse_state;

#define CLEONOS_WM_EVENT_FOCUS_GAINED 1ULL
#define CLEONOS_WM_EVENT_FOCUS_LOST 2ULL
#define CLEONOS_WM_EVENT_KEY 3ULL
#define CLEONOS_WM_EVENT_MOUSE_MOVE 4ULL
#define CLEONOS_WM_EVENT_MOUSE_BUTTON 5ULL

#define CLEONOS_WM_FLAG_TOPMOST 0x1ULL

typedef struct cleonos_wm_event {
    u64 type;
    u64 arg0;
    u64 arg1;
    u64 arg2;
    u64 arg3;
} cleonos_wm_event;

typedef struct cleonos_wm_snapshot {
    u64 window_id;
    u64 owner_pid;
    u64 flags;
    u64 x;
    u64 y;
    u64 width;
    u64 height;
    u64 focused;
    u64 presented;
    u64 event_count;
} cleonos_wm_snapshot;

typedef struct cleonos_wm_create_req {
    u64 x;
    u64 y;
    u64 width;
    u64 height;
    u64 flags;
} cleonos_wm_create_req;

typedef struct cleonos_wm_present_req {
    u64 window_id;
    u64 pixels_ptr;
    u64 src_width;
    u64 src_height;
    u64 src_pitch_bytes;
} cleonos_wm_present_req;

typedef struct cleonos_wm_move_req {
    u64 window_id;
    u64 x;
    u64 y;
} cleonos_wm_move_req;

typedef struct cleonos_wm_resize_req {
    u64 window_id;
    u64 width;
    u64 height;
} cleonos_wm_resize_req;

typedef struct cleonos_fb_blit_req {
    u64 pixels_ptr;
    u64 src_width;
    u64 src_height;
    u64 src_pitch_bytes;
    u64 dst_x;
    u64 dst_y;
    u64 scale;
} cleonos_fb_blit_req;

typedef struct cleonos_net_udp_send_req {
    u64 dst_ipv4_be;
    u64 dst_port;
    u64 src_port;
    u64 payload_ptr;
    u64 payload_len;
} cleonos_net_udp_send_req;

typedef struct cleonos_net_udp_recv_req {
    u64 out_payload_ptr;
    u64 payload_capacity;
    u64 out_src_ipv4_ptr;
    u64 out_src_port_ptr;
    u64 out_dst_port_ptr;
} cleonos_net_udp_recv_req;

typedef struct cleonos_net_tcp_connect_req {
    u64 dst_ipv4_be;
    u64 dst_port;
    u64 src_port;
    u64 poll_budget;
} cleonos_net_tcp_connect_req;

typedef struct cleonos_net_tcp_send_req {
    u64 payload_ptr;
    u64 payload_len;
    u64 poll_budget;
} cleonos_net_tcp_send_req;

typedef struct cleonos_net_tcp_recv_req {
    u64 out_payload_ptr;
    u64 payload_capacity;
    u64 poll_budget;
} cleonos_net_tcp_recv_req;

#define CLEONOS_SYSCALL_LOG_WRITE 0ULL
#define CLEONOS_SYSCALL_TIMER_TICKS 1ULL
#define CLEONOS_SYSCALL_TASK_COUNT 2ULL
#define CLEONOS_SYSCALL_CUR_TASK 3ULL
#define CLEONOS_SYSCALL_SERVICE_COUNT 4ULL
#define CLEONOS_SYSCALL_SERVICE_READY_COUNT 5ULL
#define CLEONOS_SYSCALL_CONTEXT_SWITCHES 6ULL
#define CLEONOS_SYSCALL_KELF_COUNT 7ULL
#define CLEONOS_SYSCALL_KELF_RUNS 8ULL
#define CLEONOS_SYSCALL_FS_NODE_COUNT 9ULL
#define CLEONOS_SYSCALL_FS_CHILD_COUNT 10ULL
#define CLEONOS_SYSCALL_FS_GET_CHILD_NAME 11ULL
#define CLEONOS_SYSCALL_FS_READ 12ULL
#define CLEONOS_SYSCALL_EXEC_PATH 13ULL
#define CLEONOS_SYSCALL_EXEC_REQUESTS 14ULL
#define CLEONOS_SYSCALL_EXEC_SUCCESS 15ULL
#define CLEONOS_SYSCALL_USER_SHELL_READY 16ULL
#define CLEONOS_SYSCALL_USER_EXEC_REQUESTED 17ULL
#define CLEONOS_SYSCALL_USER_LAUNCH_TRIES 18ULL
#define CLEONOS_SYSCALL_USER_LAUNCH_OK 19ULL
#define CLEONOS_SYSCALL_USER_LAUNCH_FAIL 20ULL
#define CLEONOS_SYSCALL_TTY_COUNT 21ULL
#define CLEONOS_SYSCALL_TTY_ACTIVE 22ULL
#define CLEONOS_SYSCALL_TTY_SWITCH 23ULL
#define CLEONOS_SYSCALL_TTY_WRITE 24ULL
#define CLEONOS_SYSCALL_TTY_WRITE_CHAR 25ULL
#define CLEONOS_SYSCALL_KBD_GET_CHAR 26ULL
#define CLEONOS_SYSCALL_FS_STAT_TYPE 27ULL
#define CLEONOS_SYSCALL_FS_STAT_SIZE 28ULL
#define CLEONOS_SYSCALL_FS_MKDIR 29ULL
#define CLEONOS_SYSCALL_FS_WRITE 30ULL
#define CLEONOS_SYSCALL_FS_APPEND 31ULL
#define CLEONOS_SYSCALL_FS_REMOVE 32ULL
#define CLEONOS_SYSCALL_LOG_JOURNAL_COUNT 33ULL
#define CLEONOS_SYSCALL_LOG_JOURNAL_READ 34ULL
#define CLEONOS_SYSCALL_KBD_BUFFERED 35ULL
#define CLEONOS_SYSCALL_KBD_PUSHED 36ULL
#define CLEONOS_SYSCALL_KBD_POPPED 37ULL
#define CLEONOS_SYSCALL_KBD_DROPPED 38ULL
#define CLEONOS_SYSCALL_KBD_HOTKEY_SWITCHES 39ULL
#define CLEONOS_SYSCALL_GETPID 40ULL
#define CLEONOS_SYSCALL_SPAWN_PATH 41ULL
#define CLEONOS_SYSCALL_WAITPID 42ULL
#define CLEONOS_SYSCALL_EXIT 43ULL
#define CLEONOS_SYSCALL_SLEEP_TICKS 44ULL
#define CLEONOS_SYSCALL_YIELD 45ULL
#define CLEONOS_SYSCALL_SHUTDOWN 46ULL
#define CLEONOS_SYSCALL_RESTART 47ULL
#define CLEONOS_SYSCALL_AUDIO_AVAILABLE 48ULL
#define CLEONOS_SYSCALL_AUDIO_PLAY_TONE 49ULL
#define CLEONOS_SYSCALL_AUDIO_STOP 50ULL
#define CLEONOS_SYSCALL_EXEC_PATHV 51ULL
#define CLEONOS_SYSCALL_SPAWN_PATHV 52ULL
#define CLEONOS_SYSCALL_PROC_ARGC 53ULL
#define CLEONOS_SYSCALL_PROC_ARGV 54ULL
#define CLEONOS_SYSCALL_PROC_ENVC 55ULL
#define CLEONOS_SYSCALL_PROC_ENV 56ULL
#define CLEONOS_SYSCALL_PROC_LAST_SIGNAL 57ULL
#define CLEONOS_SYSCALL_PROC_FAULT_VECTOR 58ULL
#define CLEONOS_SYSCALL_PROC_FAULT_ERROR 59ULL
#define CLEONOS_SYSCALL_PROC_FAULT_RIP 60ULL
#define CLEONOS_SYSCALL_PROC_COUNT 61ULL
#define CLEONOS_SYSCALL_PROC_PID_AT 62ULL
#define CLEONOS_SYSCALL_PROC_SNAPSHOT 63ULL
#define CLEONOS_SYSCALL_PROC_KILL 64ULL
#define CLEONOS_SYSCALL_KDBG_SYM 65ULL
#define CLEONOS_SYSCALL_KDBG_BT 66ULL
#define CLEONOS_SYSCALL_KDBG_REGS 67ULL
#define CLEONOS_SYSCALL_STATS_TOTAL 68ULL
#define CLEONOS_SYSCALL_STATS_ID_COUNT 69ULL
#define CLEONOS_SYSCALL_STATS_RECENT_WINDOW 70ULL
#define CLEONOS_SYSCALL_STATS_RECENT_ID 71ULL
#define CLEONOS_SYSCALL_FD_OPEN 72ULL
#define CLEONOS_SYSCALL_FD_READ 73ULL
#define CLEONOS_SYSCALL_FD_WRITE 74ULL
#define CLEONOS_SYSCALL_FD_CLOSE 75ULL
#define CLEONOS_SYSCALL_FD_DUP 76ULL
#define CLEONOS_SYSCALL_DL_OPEN 77ULL
#define CLEONOS_SYSCALL_DL_CLOSE 78ULL
#define CLEONOS_SYSCALL_DL_SYM 79ULL
#define CLEONOS_SYSCALL_EXEC_PATHV_IO 80ULL
#define CLEONOS_SYSCALL_FB_INFO 81ULL
#define CLEONOS_SYSCALL_FB_BLIT 82ULL
#define CLEONOS_SYSCALL_FB_CLEAR 83ULL
#define CLEONOS_SYSCALL_KERNEL_VERSION 84ULL
#define CLEONOS_SYSCALL_DISK_PRESENT 85ULL
#define CLEONOS_SYSCALL_DISK_SIZE_BYTES 86ULL
#define CLEONOS_SYSCALL_DISK_SECTOR_COUNT 87ULL
#define CLEONOS_SYSCALL_DISK_FORMATTED 88ULL
#define CLEONOS_SYSCALL_DISK_FORMAT_FAT32 89ULL
#define CLEONOS_SYSCALL_DISK_MOUNT 90ULL
#define CLEONOS_SYSCALL_DISK_MOUNTED 91ULL
#define CLEONOS_SYSCALL_DISK_MOUNT_PATH 92ULL
#define CLEONOS_SYSCALL_DISK_READ_SECTOR 93ULL
#define CLEONOS_SYSCALL_DISK_WRITE_SECTOR 94ULL
#define CLEONOS_SYSCALL_NET_AVAILABLE 95ULL
#define CLEONOS_SYSCALL_NET_IPV4_ADDR 96ULL
#define CLEONOS_SYSCALL_NET_PING 97ULL
#define CLEONOS_SYSCALL_NET_UDP_SEND 98ULL
#define CLEONOS_SYSCALL_NET_UDP_RECV 99ULL
#define CLEONOS_SYSCALL_NET_NETMASK 100ULL
#define CLEONOS_SYSCALL_NET_GATEWAY 101ULL
#define CLEONOS_SYSCALL_NET_DNS_SERVER 102ULL
#define CLEONOS_SYSCALL_NET_TCP_CONNECT 103ULL
#define CLEONOS_SYSCALL_NET_TCP_SEND 104ULL
#define CLEONOS_SYSCALL_NET_TCP_RECV 105ULL
#define CLEONOS_SYSCALL_NET_TCP_CLOSE 106ULL
#define CLEONOS_SYSCALL_MOUSE_STATE 107ULL
#define CLEONOS_SYSCALL_WM_CREATE 108ULL
#define CLEONOS_SYSCALL_WM_DESTROY 109ULL
#define CLEONOS_SYSCALL_WM_PRESENT 110ULL
#define CLEONOS_SYSCALL_WM_POLL_EVENT 111ULL
#define CLEONOS_SYSCALL_WM_MOVE 112ULL
#define CLEONOS_SYSCALL_WM_SET_FOCUS 113ULL
#define CLEONOS_SYSCALL_WM_SET_FLAGS 114ULL
#define CLEONOS_SYSCALL_WM_RESIZE 115ULL
#define CLEONOS_SYSCALL_PTY_OPEN 116ULL
#define CLEONOS_SYSCALL_WM_COUNT 117ULL
#define CLEONOS_SYSCALL_WM_ID_AT 118ULL
#define CLEONOS_SYSCALL_WM_SNAPSHOT 119ULL

u64 cleonos_syscall(u64 id, u64 arg0, u64 arg1, u64 arg2);
u64 cleonos_sys_log_write(const char *message, u64 length);
u64 cleonos_sys_timer_ticks(void);
u64 cleonos_sys_task_count(void);
u64 cleonos_sys_service_count(void);
u64 cleonos_sys_service_ready_count(void);
u64 cleonos_sys_context_switches(void);
u64 cleonos_sys_kelf_count(void);
u64 cleonos_sys_kelf_runs(void);
u64 cleonos_sys_fs_node_count(void);
u64 cleonos_sys_fs_child_count(const char *dir_path);
u64 cleonos_sys_fs_get_child_name(const char *dir_path, u64 index, char *out_name);
u64 cleonos_sys_fs_read(const char *path, char *out_buffer, u64 buffer_size);
u64 cleonos_sys_exec_path(const char *path);
u64 cleonos_sys_exec_pathv(const char *path, const char *argv_line, const char *env_line);
u64 cleonos_sys_exec_pathv_io(const char *path, const char *argv_line, const char *env_line, u64 stdin_fd,
                              u64 stdout_fd, u64 stderr_fd);
u64 cleonos_sys_exec_request_count(void);
u64 cleonos_sys_exec_success_count(void);
u64 cleonos_sys_user_shell_ready(void);
u64 cleonos_sys_user_exec_requested(void);
u64 cleonos_sys_user_launch_tries(void);
u64 cleonos_sys_user_launch_ok(void);
u64 cleonos_sys_user_launch_fail(void);
u64 cleonos_sys_tty_count(void);
u64 cleonos_sys_tty_active(void);
u64 cleonos_sys_tty_switch(u64 tty_index);
u64 cleonos_sys_tty_write(const char *text, u64 length);
u64 cleonos_sys_tty_write_char(char ch);
u64 cleonos_sys_kbd_get_char(void);
u64 cleonos_sys_fs_stat_type(const char *path);
u64 cleonos_sys_fs_stat_size(const char *path);
u64 cleonos_sys_fs_mkdir(const char *path);
u64 cleonos_sys_fs_write(const char *path, const char *data, u64 size);
u64 cleonos_sys_fs_append(const char *path, const char *data, u64 size);
u64 cleonos_sys_fs_remove(const char *path);
u64 cleonos_sys_log_journal_count(void);
u64 cleonos_sys_log_journal_read(u64 index_from_oldest, char *out_line, u64 out_size);
u64 cleonos_sys_kbd_buffered(void);
u64 cleonos_sys_kbd_pushed(void);
u64 cleonos_sys_kbd_popped(void);
u64 cleonos_sys_kbd_dropped(void);
u64 cleonos_sys_kbd_hotkey_switches(void);
u64 cleonos_sys_getpid(void);
u64 cleonos_sys_spawn_path(const char *path);
u64 cleonos_sys_spawn_pathv(const char *path, const char *argv_line, const char *env_line);
u64 cleonos_sys_wait_pid(u64 pid, u64 *out_status);
u64 cleonos_sys_exit(u64 status);
u64 cleonos_sys_sleep_ticks(u64 ticks);
u64 cleonos_sys_yield(void);
u64 cleonos_sys_shutdown(void);
u64 cleonos_sys_restart(void);
u64 cleonos_sys_audio_available(void);
u64 cleonos_sys_audio_play_tone(u64 hz, u64 ticks);
u64 cleonos_sys_audio_stop(void);
u64 cleonos_sys_proc_argc(void);
u64 cleonos_sys_proc_argv(u64 index, char *out_value, u64 out_size);
u64 cleonos_sys_proc_envc(void);
u64 cleonos_sys_proc_env(u64 index, char *out_value, u64 out_size);
u64 cleonos_sys_proc_last_signal(void);
u64 cleonos_sys_proc_fault_vector(void);
u64 cleonos_sys_proc_fault_error(void);
u64 cleonos_sys_proc_fault_rip(void);
u64 cleonos_sys_proc_count(void);
u64 cleonos_sys_proc_pid_at(u64 index, u64 *out_pid);
u64 cleonos_sys_proc_snapshot(u64 pid, cleonos_proc_snapshot *out_snapshot, u64 out_size);
u64 cleonos_sys_proc_kill(u64 pid, u64 signal);
u64 cleonos_sys_kdbg_sym(u64 addr, char *out_line, u64 out_size);
u64 cleonos_sys_kdbg_bt(u64 rbp, u64 rip, char *out_text, u64 out_size);
u64 cleonos_sys_kdbg_regs(char *out_text, u64 out_size);
u64 cleonos_sys_stats_total(void);
u64 cleonos_sys_stats_id_count(u64 id);
u64 cleonos_sys_stats_recent_window(void);
u64 cleonos_sys_stats_recent_id(u64 id);
u64 cleonos_sys_fd_open(const char *path, u64 flags, u64 mode);
u64 cleonos_sys_fd_read(u64 fd, void *out_buffer, u64 size);
u64 cleonos_sys_fd_write(u64 fd, const void *buffer, u64 size);
u64 cleonos_sys_fd_close(u64 fd);
u64 cleonos_sys_fd_dup(u64 fd);
u64 cleonos_sys_dl_open(const char *path);
u64 cleonos_sys_dl_close(u64 handle);
u64 cleonos_sys_dl_sym(u64 handle, const char *symbol);
u64 cleonos_sys_fb_info(cleonos_fb_info *out_info);
u64 cleonos_sys_fb_blit(const cleonos_fb_blit_req *req);
u64 cleonos_sys_fb_clear(u64 rgb);
u64 cleonos_sys_kernel_version(char *out_version, u64 out_size);
u64 cleonos_sys_disk_present(void);
u64 cleonos_sys_disk_size_bytes(void);
u64 cleonos_sys_disk_sector_count(void);
u64 cleonos_sys_disk_formatted(void);
u64 cleonos_sys_disk_format_fat32(const char *label);
u64 cleonos_sys_disk_mount(const char *mount_path);
u64 cleonos_sys_disk_mounted(void);
u64 cleonos_sys_disk_mount_path(char *out_path, u64 out_size);
u64 cleonos_sys_disk_read_sector(u64 lba, void *out_sector);
u64 cleonos_sys_disk_write_sector(u64 lba, const void *sector_data);
u64 cleonos_sys_net_available(void);
u64 cleonos_sys_net_ipv4_addr(void);
u64 cleonos_sys_net_netmask(void);
u64 cleonos_sys_net_gateway(void);
u64 cleonos_sys_net_dns_server(void);
u64 cleonos_sys_net_ping(u64 dst_ipv4_be, u64 poll_budget);
u64 cleonos_sys_net_udp_send(const cleonos_net_udp_send_req *req);
u64 cleonos_sys_net_udp_recv(cleonos_net_udp_recv_req *req);
u64 cleonos_sys_net_tcp_connect(const cleonos_net_tcp_connect_req *req);
u64 cleonos_sys_net_tcp_send(const cleonos_net_tcp_send_req *req);
u64 cleonos_sys_net_tcp_recv(cleonos_net_tcp_recv_req *req);
u64 cleonos_sys_net_tcp_close(u64 poll_budget);
u64 cleonos_sys_mouse_state(cleonos_mouse_state *out_state);
u64 cleonos_sys_wm_create(const cleonos_wm_create_req *req);
u64 cleonos_sys_wm_destroy(u64 window_id);
u64 cleonos_sys_wm_present(const cleonos_wm_present_req *req);
u64 cleonos_sys_wm_poll_event(u64 window_id, cleonos_wm_event *out_event);
u64 cleonos_sys_wm_move(const cleonos_wm_move_req *req);
u64 cleonos_sys_wm_set_focus(u64 window_id);
u64 cleonos_sys_wm_set_flags(u64 window_id, u64 flags);
u64 cleonos_sys_wm_resize(const cleonos_wm_resize_req *req);
u64 cleonos_sys_wm_count(void);
u64 cleonos_sys_wm_id_at(u64 index, u64 *out_window_id);
u64 cleonos_sys_wm_snapshot(u64 window_id, cleonos_wm_snapshot *out_snapshot, u64 out_size);
u64 cleonos_sys_pty_open(void);

#endif
