/*
 * Copyright (C) the libgit2 contributors. All rights reserved.
 *
 * This file is part of libgit2, distributed under the GNU GPL v2 with
 * a Linking Exception. For full terms see the included COPYING file.
 */

#include "thread.h"
#include "../global.h"

#define CLEAN_THREAD_EXIT 0x6F012842

typedef void (WINAPI *win32_srwlock_fn)(GIT_SRWLOCK *);

static win32_srwlock_fn win32_srwlock_initialize;
static win32_srwlock_fn win32_srwlock_acquire_shared;
static win32_srwlock_fn win32_srwlock_release_shared;
static win32_srwlock_fn win32_srwlock_acquire_exclusive;
static win32_srwlock_fn win32_srwlock_release_exclusive;

/* The thread procedure stub used to invoke the caller's procedure
 * and capture the return value for later collection. Windows will
 * only hold a DWORD, but we need to be able to store an entire
 * void pointer. This requires the indirection. */
static DWORD WINAPI git_win32__threadproc(LPVOID lpParameter)
{
	git_thread *thread = lpParameter;

	/* Set the current thread for `git_thread_exit` */
	GIT_GLOBAL->current_thread = thread;

	thread->result = thread->proc(thread->param);

	git__free_tls_data();

	return CLEAN_THREAD_EXIT;
}

int git_threads_init(void)
{
	HMODULE hModule = GetModuleHandleW(L"kernel32");

	if (hModule) {
		win32_srwlock_initialize = (win32_srwlock_fn)
			GetProcAddress(hModule, "InitializeSRWLock");
		win32_srwlock_acquire_shared = (win32_srwlock_fn)
			GetProcAddress(hModule, "AcquireSRWLockShared");
		win32_srwlock_release_shared = (win32_srwlock_fn)
			GetProcAddress(hModule, "ReleaseSRWLockShared");
		win32_srwlock_acquire_exclusive = (win32_srwlock_fn)
			GetProcAddress(hModule, "AcquireSRWLockExclusive");
		win32_srwlock_release_exclusive = (win32_srwlock_fn)
			GetProcAddress(hModule, "ReleaseSRWLockExclusive");
	}

	return 0;
}

int git_thread_create(
	git_thread *GIT_RESTRICT thread,
	void *(*start_routine)(void*),
	void *GIT_RESTRICT arg)
{
	thread->result = NULL;
	thread->param = arg;
	thread->proc = start_routine;
	thread->thread = CreateThread(
		NULL, 0, git_win32__threadproc, thread, 0, NULL);

	return thread->thread ? 0 : -1;
}

int git_thread_join(
	git_thread *thread,
	void **value_ptr)
{
	DWORD exit;

	if (WaitForSingleObject(thread->thread, INFINITE) != WAIT_OBJECT_0)
		return -1;

	if (!GetExitCodeThread(thread->thread, &exit)) {
		CloseHandle(thread->thread);
		return -1;
	}

	/* Check for the thread having exited uncleanly. If exit was unclean,
	 * then we don't have a return value to give back to the caller. */
	if (exit != CLEAN_THREAD_EXIT) {
		assert(false);
		thread->result = NULL;
	}

	if (value_ptr)
		*value_ptr = thread->result;

	CloseHandle(thread->thread);
	return 0;
}

void git_thread_exit(void *value)
{
	assert(GIT_GLOBAL->current_thread);
	GIT_GLOBAL->current_thread->result = value;

	git__free_tls_data();

	ExitThread(CLEAN_THREAD_EXIT);
}

size_t git_thread_currentid(void)
{
	return GetCurrentThreadId();
}

int git_mutex_init(git_mutex *GIT_RESTRICT mutex)
{
	InitializeCriticalSection(mutex);
	return 0;
}

int git_mutex_free(git_mutex *mutex)
{
	DeleteCriticalSection(mutex);
	return 0;
}

int git_mutex_lock(git_mutex *mutex)
{
	EnterCriticalSection(mutex);
	return 0;
}

int git_mutex_unlock(git_mutex *mutex)
{
	LeaveCriticalSection(mutex);
	return 0;
}

int git_cond_init(git_cond *cond)
{
	/* This is an auto-reset event. */
	*cond = CreateEventW(NULL, FALSE, FALSE, NULL);
	assert(*cond);

	/* If we can't create the event, claim that the reason was out-of-memory.
	 * The actual reason can be fetched with GetLastError(). */
	return *cond ? 0 : ENOMEM;
}

int git_cond_free(git_cond *cond)
{
	BOOL closed;

	if (!cond)
		return EINVAL;

	closed = CloseHandle(*cond);
	assert(closed);
	GIT_UNUSED(closed);

	*cond = NULL;
	return 0;
}

int git_cond_wait(git_cond *cond, git_mutex *mutex)
{
	int error;
	DWORD wait_result;

	if (!cond || !mutex)
		return EINVAL;

	/* The caller must be holding the mutex. */
	error = git_mutex_unlock(mutex);

	if (error)
		return error;

	wait_result = WaitForSingleObject(*cond, INFINITE);
	assert(WAIT_OBJECT_0 == wait_result);
	GIT_UNUSED(wait_result);

	return git_mutex_lock(mutex);
}

int git_cond_signal(git_cond *cond)
{
	BOOL signaled;

	if (!cond)
		return EINVAL;

	signaled = SetEvent(*cond);
	assert(signaled);
	GIT_UNUSED(signaled);

	return 0;
}

int git_rwlock_init(git_rwlock *GIT_RESTRICT lock)
{
	if (win32_srwlock_initialize)
		win32_srwlock_initialize(&lock->native.srwl);
	else
		InitializeCriticalSection(&lock->native.csec);

	return 0;
}

int git_rwlock_rdlock(git_rwlock *lock)
{
	if (win32_srwlock_acquire_shared)
		win32_srwlock_acquire_shared(&lock->native.srwl);
	else
		EnterCriticalSection(&lock->native.csec);

	return 0;
}

int git_rwlock_rdunlock(git_rwlock *lock)
{
	if (win32_srwlock_release_shared)
		win32_srwlock_release_shared(&lock->native.srwl);
	else
		LeaveCriticalSection(&lock->native.csec);

	return 0;
}

int git_rwlock_wrlock(git_rwlock *lock)
{
	if (win32_srwlock_acquire_exclusive)
		win32_srwlock_acquire_exclusive(&lock->native.srwl);
	else
		EnterCriticalSection(&lock->native.csec);

	return 0;
}

int git_rwlock_wrunlock(git_rwlock *lock)
{
	if (win32_srwlock_release_exclusive)
		win32_srwlock_release_exclusive(&lock->native.srwl);
	else
		LeaveCriticalSection(&lock->native.csec);

	return 0;
}

int git_rwlock_free(git_rwlock *lock)
{
	if (!win32_srwlock_initialize)
		DeleteCriticalSection(&lock->native.csec);
	git__memzero(lock, sizeof(*lock));
	return 0;
}
