#include <9pm/windows.h>
#include <9pm/u.h>
#include <9pm/libc.h>
#undef main

long _plan9id;

static int args(char *argv[], int n, char *p);

void
main(int argc, char **argv)
{
	char *arg;
	char *p, buf[128];
	Rune *warg;

	win_useunicode = win_hasunicode();
	if(GetEnvironmentVariableA("9pmdebug", buf, sizeof buf))
		pm_setdebug(buf);
	pm_dprint(PmDebugStartup, "in main useunicode=%d\n", win_useunicode);
	pm_syscallinit();

	warg = GetCommandLine();
	arg = win_wstr2utf(warg);

	/* conservative guess at the number of args */
	for(argc=5,p=arg; *p; p++)
		if(*p == ' ' || *p == '\t')
			argc++;

	argv = malloc(argc*sizeof(char*));
	argc = args(argv, argc, arg);

	/*
	 * Pick off Plan 9 process id used to identify to kernel.
	 * This is a big big hack.  The string in question is random.
	 */
	if(argc > 1 && strncmp(argv[1], "15b9c1ca477fc8e7", 16)==0){
		_plan9id = atoi(argv[1]+16);
		argc--;
		argv++;
		argv[0] = argv[-1];
	}
	pm_main(argc, argv);
	pm_dprint(PmDebugStartup, "in main exiting\n");
	ExitThread(1);
}

int PASCAL
WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR xarg, int nshow)
{
	main(0, nil);
}

/* 
 * For gross hack in atexit.c (doesn't apply to us, but we have to help).
 */
ulong _pm_gross_hack;

void
pm_dwrite(char *s)
{
	static int first=1;
	static HANDLE h;
	DWORD m;

	if(first){
		first=0;
		AllocConsole();
		h = GetStdHandle(STD_ERROR_HANDLE);
	}
	if(h != INVALID_HANDLE_VALUE && h != NULL)
		WriteFile(h, s, strlen(s), &m, nil);
}

/*
 * Break the command line into arguments
 * The rules for this are not documented but appear to be the following
 * according to the source for the microsoft C library.
 * Words are seperated by space or tab
 * Words containing a space or tab can be quoted using "
 * 2N backslashes + " ==> N backslashes and end quote
 * 2N+1 backslashes + " ==> N backslashes + literal "
 * N backslashes not followed by " ==> N backslashes
 */
static int
args(char *argv[], int n, char *p)
{
	char *p2;
	int i, j, quote, nbs;

	for(i=0; *p && i<n-1; i++) {
		while(*p == ' ' || *p == '\t')
			p++;
		quote = 0;
		argv[i] = p2 = p;
		for(;*p; p++) {
			if(!quote && (*p == ' ' || *p == '\t'))
				break;
			for(nbs=0; *p == '\\'; p++,nbs++)
				;
			if(*p == '"') {
				for(j=0; j<(nbs>>1); j++)
					*p2++ = '\\';
				if(nbs&1)
					*p2++ = *p;
				else
					quote = !quote;
			} else {
				for(j=0; j<nbs; j++)
					*p2++ = '\\';
				*p2++ = *p;
			}
		}
		/* move p up one to avoid pointing to null at end of p2 */
		if(*p)
			p++;
		*p2 = 0;	
	}
	argv[i] = 0;

	return i;
}
