#include <9pm/windows.h>
#include <9pm/u.h>
#include <9pm/libc.h>
#include <9pm/thread.h>
#include <9pm/syscall.h>
#include "../9/Windows/syscall.h"
#undef main

Rune srv[] = L"Plan 9 Kernel";

int
sleep(int n)
{
	Sleep(n);
	return 0;
}


int
errstr(char *buf, uint nbuf)
{
	strcpy(buf, "oops");
	return 0;
}


int
write(int fd, void *s, long n)
{
	static HANDLE h;
	DWORD m;

	USED(fd);
	if(h == INVALID_HANDLE_VALUE || h == NULL)
		h = GetStdHandle(STD_ERROR_HANDLE);
	if(h != INVALID_HANDLE_VALUE && h != NULL)
		WriteFile(h, s, n, &m, nil);
	else
		abort();
	return m;
}

void
pm_panic(char *fmt, ...)
{
	char buf[128], *out;
	va_list arg;

	va_start(arg, fmt);
	out = doprint(buf, buf+128, fmt, arg);
	va_end(arg);
	write(1, buf, (long)(out-buf));
	abort();
}

int
print(char *fmt, ...)
{
	char buf[128], *out;
	va_list arg;

	va_start(arg, fmt);
	out = doprint(buf, buf+128, fmt, arg);
	va_end(arg);
	write(1, buf, (long)(out-buf));
	return out-buf;
}

void
main(int argc, char **argv)
{
	HWND hwin;
	HANDLE hsrv;
	HANDLE hmem;
	Handles *h;
	Syscallmem *c;
	int pid;
	char err[ERRMAX];

	print("hello world\n");

	hwin = FindWindow(srv, srv);
	if(hwin == 0){
		osrerrstr(err, sizeof err);
		print("cannot find window: %s\n", err);
		ExitProcess(1);
	}

	GetWindowThreadProcessId(hwin, &pid);
	hsrv = OpenProcess(PROCESS_ALL_ACCESS, 0, pid);
	if(hsrv == 0){
		osrerrstr(err, sizeof err);
		print("cannot access kernel pid %d: %s\n", pid, err);
		ExitProcess(1);
	}

	hmem = (void*)SendMessage(hwin, WM_USER, 0, GetCurrentProcessId());
	if(hmem == 0){
		osrerrstr(err, sizeof err);
		print("cannot get shared memory: %s\n", err);
		ExitProcess(1);
	}

	c = MapViewOfFile(hmem, FILE_MAP_WRITE, 0, 0, 0);
	if(c == nil){
		osrerrstr(err, sizeof err);
		print("cannot map shapred memory: %s\n");
		ExitProcess(1);
	}

	print("found proc %d\n", pid);
	print("calling\n");
	c->nr = Ssysr1;
	c->ret = 12345;
	h = &c->hc;
	if(!ReleaseSemaphore(h->hserversig, 1, nil)){
		osrerrstr(err, sizeof err);
		print("ReleaseSemaphore: %s\n", err);
	}
	/* BUG: wait for server proc too in case it dies */
	if(WaitForSingleObject(h->hclientsig, INFINITE) != WAIT_OBJECT_0){
		osrerrstr(err, sizeof err);
		print("WaitForSingleObject: %s\n", err);
	}
	print("response: %d\n", c->ret);
	ExitProcess(111);
}
