// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

#include "runtime.h"
#include "os.h"

#define stdcall stdcall_raw

extern void *get_kernel_module(void);

// Also referenced by external packages
void *CloseHandle;
void *ExitProcess;
void *GetStdHandle;
void *SetEvent;
void *WriteFile;
void *VirtualAlloc;
void *LoadLibraryEx;
void *GetProcAddress;
void *GetLastError;

static void *CreateEvent;
static void *CreateThread;
static void *GetModuleHandle;
static void *WaitForSingleObject;

static void*
get_proc_addr2(byte *base, byte *name)
{
	byte *pe_header, *exports;
	uint32 entries, *addr, *names, i;
	uint16 *ordinals;

	pe_header = base+*(uint32*)(base+0x3c);
	exports = base+*(uint32*)(pe_header+0x78);
	entries = *(uint32*)(exports+0x18);
	addr = (uint32*)(base+*(uint32*)(exports+0x1c));
	names = (uint32*)(base+*(uint32*)(exports+0x20));
	ordinals = (uint16*)(base+*(uint32*)(exports+0x24));
	for(i=0; i<entries; i++) {
		byte *s = base+names[i];
		if(!strcmp(name, s))
			break;
	}
	if(i == entries)
		return 0;
	return base+addr[ordinals[i]];
}

void
osinit(void)
{
	void *base;

	base = get_kernel_module();
	GetProcAddress = get_proc_addr2(base, (byte*)"GetProcAddress");
	LoadLibraryEx = get_proc_addr2(base, (byte*)"LoadLibraryExA");
	CloseHandle = get_proc_addr("kernel32.dll", "CloseHandle");
	CreateEvent = get_proc_addr("kernel32.dll", "CreateEventA");
	CreateThread = get_proc_addr("kernel32.dll", "CreateThread");
	ExitProcess = get_proc_addr("kernel32.dll", "ExitProcess");
	GetModuleHandle = get_proc_addr("kernel32.dll", "GetModuleHandleA");
	GetStdHandle = get_proc_addr("kernel32.dll", "GetStdHandle");
	SetEvent = get_proc_addr("kernel32.dll", "SetEvent");
	VirtualAlloc = get_proc_addr("kernel32.dll", "VirtualAlloc");
	WaitForSingleObject = get_proc_addr("kernel32.dll", "WaitForSingleObject");
	WriteFile = get_proc_addr("kernel32.dll", "WriteFile");
	GetLastError = get_proc_addr("kernel32.dll", "GetLastError");
}

// The arguments are strings.
void*
get_proc_addr(void *library, void *name)
{
	void *base;

	base = stdcall(LoadLibraryEx, library, 0, 0);
	return stdcall(GetProcAddress, base, name);
}

void
mingw_goargs(void)
{
	extern Slice os·Args;
	extern Slice os·Envs;

	void *gcl, *clta, *ges;
	uint16 *cmd, *env, **argv;
	String *gargv;
	String *genvv;
	int32 i, argc, envc;
	uint16 *envp;

	gcl = get_proc_addr("kernel32.dll", "GetCommandLineW");
	clta = get_proc_addr("shell32.dll", "CommandLineToArgvW");
	ges = get_proc_addr("kernel32.dll", "GetEnvironmentStringsW");

	cmd = stdcall(gcl);
	env = stdcall(ges);
	argv = stdcall(clta, cmd, &argc);

	envc = 0;
	for(envp=env; *envp; envc++)
		envp += findnullw(envp)+1;

	gargv = malloc(argc*sizeof gargv[0]);
	genvv = malloc(envc*sizeof genvv[0]);

	for(i=0; i<argc; i++)
		gargv[i] = gostringw(argv[i]);
	os·Args.array = (byte*)gargv;
	os·Args.len = argc;
	os·Args.cap = argc;

	envp = env;
	for(i=0; i<envc; i++) {
		genvv[i] = gostringw(envp);
		envp += findnullw(envp)+1;
	}
	os·Envs.array = (byte*)genvv;
	os·Envs.len = envc;
	os·Envs.cap = envc;
}

void
exit(int32 code)
{
	stdcall(ExitProcess, code);
}

int32
write(int32 fd, void *buf, int32 n)
{
	void *handle;
	uint32 written;

	written = 0;
	switch(fd) {
	case 1:
		handle = stdcall(GetStdHandle, -11);
		break;
	case 2:
		handle = stdcall(GetStdHandle, -12);
		break;
	default:
		return -1;
	}
	stdcall(WriteFile, handle, buf, n, &written, 0);
	return written;
}

void*
get_symdat_addr(void)
{
	byte *mod, *p;
	uint32 peh, add;
	uint16 oph;

	mod = stdcall(GetModuleHandle, 0);
	peh = *(uint32*)(mod+0x3c);
	p = mod+peh+4;
	oph = *(uint16*)(p+0x10);
	p += 0x14+oph;
	while(strcmp(p, (byte*)".symdat"))
		p += 40;
	add = *(uint32*)(p+0x0c);
	return mod+add;
}

// Thread-safe allocation of an event.
static void
initevent(void **pevent)
{
	void *event;

	event = stdcall(CreateEvent, 0, 0, 0, 0);
	if(!casp(pevent, 0, event)) {
		// Someone else filled it in.  Use theirs.
		stdcall(CloseHandle, event);
	}
}

static void
eventlock(Lock *l)
{
	// Allocate event if needed.
	if(l->event == 0)
		initevent(&l->event);

	if(xadd(&l->key, 1) > 1)	// someone else has it; wait
		stdcall(WaitForSingleObject, l->event, -1);
}

static void
eventunlock(Lock *l)
{
	if(xadd(&l->key, -1) > 0)	// someone else is waiting
		stdcall(SetEvent, l->event);
}

void
lock(Lock *l)
{
	if(m->locks < 0)
		throw("lock count");
	m->locks++;
	eventlock(l);
}

void
unlock(Lock *l)
{
	m->locks--;
	if(m->locks < 0)
		throw("lock count");
	eventunlock(l);
}

void
destroylock(Lock *l)
{
}

void
noteclear(Note *n)
{
	eventlock(&n->lock);
}

void
notewakeup(Note *n)
{
	eventunlock(&n->lock);
}

void
notesleep(Note *n)
{
	eventlock(&n->lock);
	eventunlock(&n->lock);	// Let other sleepers find out too.
}

void
newosproc(M *m, G *g, void *stk, void (*fn)(void))
{
	struct {
		void *args;
		void *event_handle;
	} param = { &m };
	extern uint32 threadstart(void *p);

	USED(g, stk, fn);
	param.event_handle = stdcall(CreateEvent, 0, 0, 0, 0);
	stdcall(CreateThread, 0, 0, threadstart, &param, 0, 0);
	stdcall(WaitForSingleObject, param.event_handle, -1);
	stdcall(CloseHandle, param.event_handle);
}

// Called to initialize a new m (including the bootstrap m).
void
minit(void)
{
}
