/**
 * utils.c:
 *
 * Useful utilities for general use.
**/
#include "utils.h"

#include <sysinfoapi.h>
#include <windef.h>
#include <winbase.h>
#include <winuser.h>
#include <stringapiset.h>
#include <stdint.h>

/* self explanatory. */
uint64_t get_system_time_in_milliseconds(void) {
 	FILETIME ft;
	GetSystemTimeAsFileTime(&ft);
	uint64_t ul = (uint64_t) ft.dwHighDateTime << 32 | ft.dwLowDateTime;
	return ((ul - 116444736000000000ULL) * (1.0/10000000));
}

/*
 * appends the contents of a UTF-8 string with the content of a wide string
 *
 * [in] LPCWSTR wstr, the wstring to append
 * [out] LPSTR str, the utf-8 string to append to
 * [in] size_t offset, an offset in bytes of `str` to append at
 * [in] size_t size, the total size of `str` in bytes
 *
 * if the function fails, it returns 0.
 * if the string is empty (i.e. str[0] == '\0'), this function returns 0.
 * if the wide string is too large to be appended within `size`, it returns 0.
 * on success, it returns the amount of characters written ***NOT INCLUDING THE
 * NUL BYTE***.
*/
size_t append_wstr_to_utf8(LPCWSTR wstr, LPSTR str, size_t offset, size_t size) {
	if (!wstr || !str)
		return 0;

	const int wstr_len = WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, wstr, -1, NULL, 0, NULL, NULL);
	if (wstr_len < 0 || offset + wstr_len >= size)
		return 0;

	const int actual_len = WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, wstr, -1, str + offset, wstr_len, NULL, NULL);
	if (actual_len < 1)
		return 0;

	return actual_len - 1; // remove nul byte from offset
}
