#ifndef _COMPAT_H
#define _COMPAT_H 1



#include <stdint.h>

typedef uint32_t in_addr_t;
typedef uint16_t in_port_t;



#if defined(__GNUC__)

#include <unistd.h>
#include <pthread.h>

typedef pthread_mutex_t mutex_t;
#define MUTEX_INIT(x) pthread_mutex_init(&x, NULL)
#define MUTEX_LOCK(x) pthread_mutex_lock(&x)
#define MUTEX_UNLOCK(x) pthread_mutex_unlock(&x)

typedef pthread_t thread_t;
typedef void * thread_func_ret_t;
#define THREAD_FUNC_TYPE
#define THREAD_CREATE(x, y, z) pthread_create(&x, NULL, y, z)
#define THREAD_DETACH(x) pthread_detach(x)
#define THREAD_JOIN(x) pthread_join(x, NULL)

typedef int pipe_t;
#define PIPE_OPEN(x, y) pipe(&x)
#define PIPE_READ(r, x, y, z) (ssize_t)((r = read(x, y, z)))
#define PIPE_WRITE(r, x, y, z) (ssize_t)((r = write(x, y, z)))
#define PIPE_CLOSE(x) close(x)



#elif defined(_MSC_VER)

#include <stdio.h>
#include <windows.h>
#include <process.h>

#include "..\Runtime\Runtime.h"
#include "..\common\debug.h"

typedef CRITICAL_SECTION mutex_t;

//#define MUTEX_INIT(x) InitializeCriticalSection(&x)
//#define MUTEX_LOCK(x) EnterCriticalSection(&x)
//#define MUTEX_UNLOCK(x) LeaveCriticalSection(&x)

/* runtime */
#define MUTEX_INIT(x) API_INITIALIZECRITICALSECTION(&x)
#define MUTEX_LOCK(x) API_ENTERCRITICALSECTION(&x)
#define MUTEX_UNLOCK(x) API_LEAVECRITICALSECTION(&x)

#define PTHREAD_MUTEX_INITIALIZER { 0 };

typedef HANDLE thread_t;
typedef unsigned int thread_func_ret_t;
#define THREAD_FUNC_TYPE WINAPI

//#define THREAD_CREATE(x, y, z) (int)((x = (HANDLE)_beginthreadex(NULL, 0, y, z, 0, NULL)) == NULL)
//#define THREAD_DETACH(x) CloseHandle(x)
//#define THREAD_JOIN(x) ((WaitForSingleObject((x), INFINITE) != WAIT_OBJECT_0) || !CloseHandle(x))

/* runtime */
typedef struct _THREAD_ARGUMENTS
{
	PRUNTIME pRuntime;
	void* data;
}THREAD_ARGUMENT, *PTHREAD_ARGUMENT;

#define THREAD_CREATE(thread_handle, start_address , thread_args) (int)((thread_handle = (HANDLE)API__BEGINTHREADEX(NULL, 0, start_address, thread_args, 0, NULL)) == NULL)
#define THREAD_DETACH(x) API_CLOSEHANDLE(x)
#define THREAD_JOIN(x) ((API_WAITFORSINGLEOBJECT((x), INFINITE) != WAIT_OBJECT_0) || !API_CLOSEHANDLE(x))


typedef HANDLE pipe_t;

//#define PIPE_OPEN(x, y) CreatePipe(&x, &y, NULL, 0)
//#define PIPE_READ(r, x, y, z) ReadFile(x, y, z, &r, NULL)
//#define PIPE_WRITE(r, x, y, z) WriteFile(x, y, z, &r, NULL)
//#define PIPE_CLOSE(x) CloseHandle(x)

/* runtime */
#define PIPE_OPEN(x, y) API_CREATEPIPE(&x, &y, NULL, 0)
#define PIPE_READ(r, x, y, z)  API_READFILE(x, y, z, &r, NULL)
#define PIPE_WRITE(r, x, y, z)  API_WRITEFILE(x, y, z, &r, NULL)
#define PIPE_CLOSE(x) API_CLOSEHANDLE(x)

//
//#define sleep(x) Sleep(x)
//#define snprintf(...) _snprintf(__VA_ARGS__)

/* runtime */
#define sleep(x) API_SLEEP(x)
#define snprintf(...) API__SNPRINTF(__VA_ARGS__)

#else
#error "Unsupported compiler"
#endif

#endif /* _COMPAT_H */
