/*
 * libusb event abstraction on Microsoft Windows
 *
 * Copyright © 2020 Chris Dickens <christopher.a.dickens@gmail.com>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */

#include <config.h>

#include "libusbi.h"
#include "windows_common.h"

int usbi_create_event(usbi_event_t *event)
{
	event->hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
	if (event->hEvent == NULL) {
		usbi_err(NULL, "CreateEvent failed: %s", windows_error_str(0));
		return LIBUSB_ERROR_OTHER;
	}

	return 0;
}

void usbi_destroy_event(usbi_event_t *event)
{
	if (!CloseHandle(event->hEvent))
		usbi_warn(NULL, "CloseHandle failed: %s", windows_error_str(0));
}

void usbi_signal_event(usbi_event_t *event)
{
	if (!SetEvent(event->hEvent))
		usbi_warn(NULL, "SetEvent failed: %s", windows_error_str(0));
}

void usbi_clear_event(usbi_event_t *event)
{
	if (!ResetEvent(event->hEvent))
		usbi_warn(NULL, "ResetEvent failed: %s", windows_error_str(0));
}

#ifdef HAVE_OS_TIMER
int usbi_create_timer(usbi_timer_t *timer)
{
	timer->hTimer = CreateWaitableTimer(NULL, TRUE, NULL);
	if (timer->hTimer == NULL) {
		usbi_warn(NULL, "CreateWaitableTimer failed: %s", windows_error_str(0));
		return LIBUSB_ERROR_OTHER;
	}

	return 0;
}

void usbi_destroy_timer(usbi_timer_t *timer)
{
	if (!CloseHandle(timer->hTimer))
		usbi_warn(NULL, "CloseHandle failed: %s", windows_error_str(0));
}

int usbi_arm_timer(usbi_timer_t *timer, const struct timespec *timeout)
{
	struct timespec systime, remaining;
	FILETIME filetime;
	LARGE_INTEGER dueTime;

	/* Transfer timeouts are based on the monotonic clock and the waitable
	 * timers on the system clock. This requires a conversion between the
	 * two, so we calculate the remaining time relative to the monotonic
	 * clock and calculate an absolute system time for the timer expiration.
	 * Note that if the timeout has already passed, the remaining time will
	 * be negative and thus an absolute system time in the past will be set.
	 * This works just as intended because the timer becomes signalled
	 * immediately. */
	usbi_get_monotonic_time(&systime);

	TIMESPEC_SUB(timeout, &systime, &remaining);

	GetSystemTimeAsFileTime(&filetime);
	dueTime.LowPart = filetime.dwLowDateTime;
	dueTime.HighPart = filetime.dwHighDateTime;
	dueTime.QuadPart += (remaining.tv_sec * 10000000LL) + (remaining.tv_nsec / 100LL);

	if (!SetWaitableTimer(timer->hTimer, &dueTime, 0, NULL, NULL, FALSE)) {
		usbi_warn(NULL, "SetWaitableTimer failed: %s", windows_error_str(0));
		return LIBUSB_ERROR_OTHER;
	}

	return 0;
}

int usbi_disarm_timer(usbi_timer_t *timer)
{
	LARGE_INTEGER dueTime;

	/* A manual-reset waitable timer will stay in the signalled state until
	 * another call to SetWaitableTimer() is made. It is possible that the
	 * timer has already expired by the time we come in to disarm it, so to
	 * be entirely sure the timer is disarmed and not in the signalled state,
	 * we will set it with an impossibly large expiration and immediately
	 * cancel. */
	dueTime.QuadPart = LLONG_MAX;
	if (!SetWaitableTimer(timer->hTimer, &dueTime, 0, NULL, NULL, FALSE)) {
		usbi_warn(NULL, "SetWaitableTimer failed: %s", windows_error_str(0));
		return LIBUSB_ERROR_OTHER;
	}

	if (!CancelWaitableTimer(timer->hTimer)) {
		usbi_warn(NULL, "SetWaitableTimer failed: %s", windows_error_str(0));
		return LIBUSB_ERROR_OTHER;
	}

	return 0;
}
#endif

int usbi_alloc_event_data(struct libusb_context *ctx)
{
	struct usbi_event_source *ievent_source;
	HANDLE *handles;
	size_t i = 0;

	/* Event sources are only added during usbi_io_init(). We should not
	 * be running this function again if the event data has already been
	 * allocated. */
	if (ctx->event_data) {
		usbi_warn(ctx, "program assertion failed - event data already allocated");
		return LIBUSB_ERROR_OTHER;
	}

	ctx->event_data_cnt = 0;
	for_each_event_source(ctx, ievent_source)
		ctx->event_data_cnt++;

	/* We only expect up to two HANDLEs to wait on, one for the internal
	 * signalling event and the other for the timer. */
	if (ctx->event_data_cnt != 1 && ctx->event_data_cnt != 2) {
		usbi_err(ctx, "program assertion failed - expected exactly 1 or 2 HANDLEs");
		return LIBUSB_ERROR_OTHER;
	}

	handles = calloc(ctx->event_data_cnt, sizeof(HANDLE));
	if (!handles)
		return LIBUSB_ERROR_NO_MEM;

	for_each_event_source(ctx, ievent_source) {
		handles[i] = ievent_source->data.os_handle;
		i++;
	}

	ctx->event_data = handles;
	return 0;
}

int usbi_wait_for_events(struct libusb_context *ctx,
	struct usbi_reported_events *reported_events, int timeout_ms)
{
	HANDLE *handles = ctx->event_data;
	DWORD num_handles = (DWORD)ctx->event_data_cnt;
	DWORD result;

	usbi_dbg(ctx, "WaitForMultipleObjects() for %lu HANDLEs with timeout in %dms", ULONG_CAST(num_handles), timeout_ms);
	result = WaitForMultipleObjects(num_handles, handles, FALSE, (DWORD)timeout_ms);
	usbi_dbg(ctx, "WaitForMultipleObjects() returned %lu", ULONG_CAST(result));
	if (result == WAIT_TIMEOUT) {
		if (usbi_using_timer(ctx))
			goto done;
		return LIBUSB_ERROR_TIMEOUT;
	} else if (result == WAIT_FAILED) {
		usbi_err(ctx, "WaitForMultipleObjects() failed: %s", windows_error_str(0));
		return LIBUSB_ERROR_IO;
	}

	result -= WAIT_OBJECT_0;

	/* handles[0] is always the internal signalling event */
	if (result == 0)
		reported_events->event_triggered = 1;
	else
		reported_events->event_triggered = 0;

#ifdef HAVE_OS_TIMER
	/* on timer configurations, handles[1] is the timer */
	if (usbi_using_timer(ctx)) {
		/* The WaitForMultipleObjects() function reports the index of
		 * the first object that became signalled. If the internal
		 * signalling event was reported, we need to also check and
		 * report whether the timer is in the signalled state. */
		if (result == 1 || WaitForSingleObject(handles[1], 0) == WAIT_OBJECT_0)
			reported_events->timer_triggered = 1;
		else
			reported_events->timer_triggered = 0;
	} else {
		reported_events->timer_triggered = 0;
	}
#endif

done:
	/* no events are ever reported to the backend */
	reported_events->num_ready = 0;
	return LIBUSB_SUCCESS;
}
