/*
 * headless Git - run Git without opening a console window on Windows
 */

#define STRICT
#define WIN32_LEAN_AND_MEAN
#define UNICODE
#define _UNICODE
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <wchar.h>

/*
 * If `dir` contains the path to a Git exec directory, extend `PATH` to
 * include the corresponding `bin/` directory (which is where all those
 * `.dll` files needed by `git.exe` are, on Windows).
 */
static int extend_path(wchar_t *dir, size_t dir_len)
{
	const wchar_t *suffix = L"\\libexec\\git-core";
	size_t suffix_len = wcslen(suffix);
	wchar_t *env;
	DWORD len;

	if (dir_len < suffix_len)
		return 0;

	dir_len -= suffix_len;
	if (memcmp(dir + dir_len, suffix, suffix_len * sizeof(wchar_t)))
		return 0;

	len = GetEnvironmentVariableW(L"PATH", NULL, 0);
	if (!len)
		return 0;

	env = _alloca((dir_len + 5 + len) * sizeof(wchar_t));
	wcsncpy(env, dir, dir_len);
	wcscpy(env + dir_len, L"\\bin;");
	if (!GetEnvironmentVariableW(L"PATH", env + dir_len + 5, len))
		return 0;

	SetEnvironmentVariableW(L"PATH", env);
	return 1;
}

int WINAPI wWinMain(_In_ HINSTANCE instance,
		    _In_opt_ HINSTANCE previous_instance,
		    _In_ LPWSTR command_line, _In_ int show)
{
	wchar_t git_command_line[32768];
	size_t size = sizeof(git_command_line) / sizeof(wchar_t);
	const wchar_t *needs_quotes = L"";
	int slash = 0, i;

	STARTUPINFO startup_info = {
		.cb = sizeof(STARTUPINFO),
		.dwFlags = STARTF_USESHOWWINDOW,
		.wShowWindow = SW_HIDE,
	};
	PROCESS_INFORMATION process_info = { 0 };
	DWORD creation_flags = CREATE_UNICODE_ENVIRONMENT |
		CREATE_NEW_CONSOLE | CREATE_NO_WINDOW;
	DWORD exit_code;

	/* First, determine the full path of argv[0] */
	for (i = 0; _wpgmptr[i]; i++)
		if (_wpgmptr[i] == L' ')
			needs_quotes = L"\"";
		else if (_wpgmptr[i] == L'\\')
			slash = i;

	if (slash >= size - 11)
		return 127; /* Too long path */

	/* If it is in Git's exec path, add the bin/ directory to the PATH */
	extend_path(_wpgmptr, slash);

	/* Then, add the full path of `git.exe` as argv[0] */
	i = swprintf_s(git_command_line, size, L"%ls%.*ls\\git.exe%ls",
		       needs_quotes, slash, _wpgmptr, needs_quotes);
	if (i < 0)
		return 127; /* Too long path */

	if (*command_line) {
		/* Now, append the command-line arguments */
		i = swprintf_s(git_command_line + i, size - i,
			       L" %ls", command_line);
		if (i < 0)
			return 127;
	}

	startup_info.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
	startup_info.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
	startup_info.hStdError = GetStdHandle(STD_ERROR_HANDLE);

	if (!CreateProcess(NULL, /* infer argv[0] from the command line */
			   git_command_line, /* modified command line */
			   NULL, /* inherit process handles? */
			   NULL, /* inherit thread handles? */
			   FALSE, /* handles inheritable? */
			   creation_flags,
			   NULL, /* use this process' environment */
			   NULL, /* use this process' working directory */
			   &startup_info, &process_info))
		return 129; /* could not start */
	WaitForSingleObject(process_info.hProcess, INFINITE);
	if (!GetExitCodeProcess(process_info.hProcess, &exit_code))
		exit_code = 130; /* Could not determine exit code? */

	CloseHandle(process_info.hProcess);
	CloseHandle(process_info.hThread);

	return (int)exit_code;
}
