#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>

int main(int argc, char **argv)
{
	SECURITY_ATTRIBUTES sa;
	STARTUPINFOA si;
	PROCESS_INFORMATION pi;
	HANDLE child_stdin_read = NULL;
	HANDLE child_stdin_write = NULL;
	HANDLE child_stdout_read = NULL;
	HANDLE child_stdout_write = NULL;
	char command[1024];
	char password[512];
	char buffer[4096];
	DWORD count;
	DWORD exit_code = 1;
	const unsigned char *p;

	if (argc != 2) {
		fprintf(stderr, "usage: %s ACCOUNT < password.txt\n", argv[0]);
		return 2;
	}
	if (!fgets(password, sizeof(password), stdin)) {
		fprintf(stderr, "password input is required\n");
		return 2;
	}
	password[strcspn(password, "\r\n")] = 0;
	for (p = (const unsigned char *)argv[1]; *p; p++) {
		if (!isalnum(*p) && *p != '@' && *p != '.' && *p != '_' && *p != '-') {
			fprintf(stderr, "account contains an unsupported character\n");
			return 2;
		}
	}

	sa.nLength = sizeof(sa);
	sa.lpSecurityDescriptor = NULL;
	sa.bInheritHandle = TRUE;
	if (!CreatePipe(&child_stdin_read, &child_stdin_write, &sa, 0) ||
	    !CreatePipe(&child_stdout_read, &child_stdout_write, &sa, 0)) {
		fprintf(stderr, "CreatePipe failed: %lu\n", GetLastError());
		return 1;
	}
	SetHandleInformation(child_stdin_write, HANDLE_FLAG_INHERIT, 0);
	SetHandleInformation(child_stdout_read, HANDLE_FLAG_INHERIT, 0);

	count = (DWORD)snprintf(command, sizeof(command),
	    "starbonding-cli.exe --username %s --password-stdin --restream-get",
	    argv[1]);
	if (count >= sizeof(command)) {
		return 1;
	}
	memset(&si, 0, sizeof(si));
	si.cb = sizeof(si);
	si.dwFlags = STARTF_USESTDHANDLES;
	si.hStdInput = child_stdin_read;
	si.hStdOutput = child_stdout_write;
	si.hStdError = GetStdHandle(STD_ERROR_HANDLE);
	memset(&pi, 0, sizeof(pi));

	if (!CreateProcessA(NULL, command, NULL, NULL, TRUE,
	    CREATE_NO_WINDOW, NULL, NULL, &si, &pi)) {
		fprintf(stderr, "CreateProcess failed: %lu\n", GetLastError());
		return 1;
	}
	CloseHandle(child_stdin_read);
	CloseHandle(child_stdout_write);

	WriteFile(child_stdin_write, password, (DWORD)strlen(password), &count, NULL);
	WriteFile(child_stdin_write, "\r\n", 2, &count, NULL);
	CloseHandle(child_stdin_write);

	while (ReadFile(child_stdout_read, buffer, sizeof(buffer), &count, NULL) && count)
		fwrite(buffer, 1, count, stdout);
	CloseHandle(child_stdout_read);
	WaitForSingleObject(pi.hProcess, INFINITE);
	GetExitCodeProcess(pi.hProcess, &exit_code);
	CloseHandle(pi.hThread);
	CloseHandle(pi.hProcess);
	SecureZeroMemory(password, sizeof(password));
	return (int)exit_code;
}
