#ifndef SWIFT_THREAD_THREAD_H
#define SWIFT_THREAD_THREAD_H

#include <swift/atomic.h>
#include <swift/stdlib.h>
#include <swift/time.h>

#include <swift/thread/api.h>

typedef unsigned long swift_thread_id_t;
typedef struct swift_thread_t swift_thread_t;
typedef struct swift_mutex_t swift_mutex_t;

typedef int (* swift_run_thread_fn_t)(void *user_data);

enum swift_thread_flags_t {
	SWIFT_THREAD_EXITED = (1 << 0),
	SWIFT_THREAD_DETACHED = (1 << 1),
	SWIFT_THREAD_TO_BE_JOINED = (1 << 2),
	SWIFT_THREAD_FOREIGN = (1 << 3),
};

enum swift_thread_prio_t {
	SWIFT_THREAD_PRIO_VERY_LOW = 0,
	SWIFT_THREAD_PRIO_LOW = 25,
	SWIFT_THREAD_PRIO_NORMAL = 50,
	SWIFT_THREAD_PRIO_HIGH = 75,
	SWIFT_THREAD_PRIO_VERY_HIGH = 100,
};

struct swift_thread_t {
	swift_ref_t ref;
	void *data;
	swift_mutex_t *lock;
	swift_thread_id_t thread_id;
	unsigned int flags, prio;
	int status;
	bool on_heap;
};

SWIFT_THREAD_API bool swift_init_threads(void);
SWIFT_THREAD_API void swift_term_threads(void);

SWIFT_THREAD_API swift_thread_id_t swift_get_main_thread_id(void);
SWIFT_THREAD_API swift_thread_id_t swift_get_current_thread_id(void);
SWIFT_THREAD_API swift_thread_t *swift_get_thread(swift_thread_id_t thread_id);
SWIFT_THREAD_API swift_thread_t *swift_get_current_thread(void);

SWIFT_THREAD_API void swift_yield_thread(void);
SWIFT_THREAD_API void swift_exit_thread(int status);

SWIFT_THREAD_API bool swift_init_thread(swift_thread_t *thread,
	swift_run_thread_fn_t run_thread, void *user_data, size_t stack_size,
	unsigned int flags);
SWIFT_THREAD_API void swift_term_thread(swift_thread_t *thread);
SWIFT_THREAD_API swift_thread_t *swift_new_thread(
	swift_run_thread_fn_t run_thread, void *user_data, size_t stack_size,
	unsigned int flags);
SWIFT_THREAD_API void swift_del_thread(swift_thread_t *thread);

SWIFT_THREAD_API bool swift_thread_wait(swift_thread_t *thread, int *status);
SWIFT_THREAD_API bool swift_thread_get_prio(swift_thread_t *thread,
	unsigned int *prio);
SWIFT_THREAD_API bool swift_thread_set_prio(swift_thread_t *thread,
	unsigned int prio);

#endif /* SWIFT_THREAD_THREAD_H */
