// Copyright 2012 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.

// These #ifdefs are being used as a substitute for
// build configuration, so that on any system, this
// tool can be built with the local equivalent of
//	cc *.c
//
#ifdef WIN32

// Portability layer implemented for Windows.
// See unix.c for doc comments about exported functions.

#include "a.h"
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>

/*
 * Windows uses 16-bit rune strings in the APIs.
 * Define conversions between Rune* and UTF-8 char*.
 */

typedef unsigned char uchar;
typedef unsigned short Rune;  // same as Windows

// encoderune encodes the rune r into buf and returns
// the number of bytes used.
static int
encoderune(char *buf, Rune r)
{
	if(r < 0x80) {  // 7 bits
		buf[0] = r;
		return 1;
	}
	if(r < 0x800) {  // 5+6 bits
		buf[0] = 0xc0 | (r>>6);
		buf[1] = 0x80 | (r&0x3f);
		return 2;
	}
	buf[0] = 0xe0 | (r>>12);
	buf[1] = 0x80 | ((r>>6)&0x3f);
	buf[2] = 0x80 | (r&0x3f);
	return 3;
}

// decoderune decodes the rune encoding at sbuf into r
// and returns the number of bytes used.
static int
decoderune(Rune *r, char *sbuf)
{
	uchar *buf;

	buf = (uchar*)sbuf;
	if(buf[0] < 0x80) {
		*r = buf[0];
		return 1;
	}
	if((buf[0]&0xe0) == 0xc0 && (buf[1]&0xc0) == 0x80) {
		*r = (buf[0]&~0xc0)<<6 | (buf[1]&~0x80);
		if(*r < 0x80)
			goto err;
		return 2;
	}
	if((buf[0]&0xf0) == 0xe0 && (buf[1]&0xc0) == 0x80 && (buf[2]&0xc0) == 0x80) {
		*r = (buf[0]&~0xc0)<<12 | (buf[1]&~0x80)<<6 | (buf[2]&~0x80);
		if(*r < 0x800)
			goto err;
		return 3;
	}
err:
	*r = 0xfffd;
	return 1;
}

// toutf replaces b with the UTF-8 encoding of the rune string r.	
static void
toutf(Buf *b, Rune *r)
{
	int i, n;
	char buf[4];

	breset(b);
	for(i=0; r[i]; i++) {
		n = encoderune(buf, r[i]);
		bwrite(b, buf, n);
	}
}

// torune replaces *rp with a pointer to a newly allocated
// rune string equivalent of the UTF-8 string p.
static void
torune(Rune **rp, char *p)
{
	Rune *r, *w;

	r = xmalloc((strlen(p)+1) * sizeof r[0]);
	w = r;
	while(*p)
		p += decoderune(w++, p);
	*w = 0;
	*rp = r;
}

// errstr returns the most recent Windows error, in string form.
static char*
errstr(void)
{
	DWORD code;
	Rune *r;
	Buf b;

	binit(&b);
	code = GetLastError();
	r = nil;
	FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM,
		nil, code, 0, (Rune*)&r, 0, nil);
	toutf(&b, r);
	return bstr(&b);  // leak but we're dying anyway
}

void
xgetenv(Buf *b, char *name)
{
	Rune *buf;
	int n;
	Rune *r;

	breset(b);
	torune(&r, name);
	n = GetEnvironmentVariableW(r, NULL, 0);
	if(n > 0) {
		buf = xmalloc((n+1)*sizeof buf[0]);
		GetEnvironmentVariableW(r, buf, n+1);
		buf[n] = '\0';
		toutf(b, buf);
		xfree(buf);
	}
	xfree(r);
}

void
xsetenv(char *name, char *value)
{
	Rune *rname, *rvalue;

	torune(&rname, name);
	torune(&rvalue, value);
	SetEnvironmentVariableW(rname, rvalue);
	xfree(rname);
	xfree(rvalue);
}

char*
bprintf(Buf *b, char *fmt, ...)
{
	va_list arg;
	char buf[4096];
	
	breset(b);
	va_start(arg, fmt);
	vsnprintf(buf, sizeof buf, fmt, arg);
	va_end(arg);
	bwritestr(b, buf);
	return bstr(b);
}

void
bwritef(Buf *b, char *fmt, ...)
{
	va_list arg;
	char buf[4096];
	
	// no reset
	va_start(arg, fmt);
	vsnprintf(buf, sizeof buf, fmt, arg);
	va_end(arg);
	bwritestr(b, buf);
}

// bpathf is like bprintf but replaces / with \ in the result,
// to make it a canonical windows file path.
char*
bpathf(Buf *b, char *fmt, ...)
{
	int i;
	va_list arg;
	char buf[4096];
	
	breset(b);
	va_start(arg, fmt);
	vsnprintf(buf, sizeof buf, fmt, arg);
	va_end(arg);
	bwritestr(b, buf);

	for(i=0; i<b->len; i++)
		if(b->p[i] == '/')
			b->p[i] = '\\';

	return bstr(b);
}


static void
breadfrom(Buf *b, HANDLE h)
{
	DWORD n;

	for(;;) {
		if(b->len > 1<<22)
			fatal("unlikely file size in readfrom");
		bgrow(b, 4096);
		n = 0;
		if(!ReadFile(h, b->p+b->len, 4096, &n, nil)) {
			// Happens for pipe reads.
			break;
		}
		if(n == 0)
			break;
		b->len += n;
	}
}

void
run(Buf *b, char *dir, int mode, char *cmd, ...)
{
	va_list arg;
	Vec argv;
	char *p;
	
	vinit(&argv);
	vadd(&argv, cmd);
	va_start(arg, cmd);
	while((p = va_arg(arg, char*)) != nil)
		vadd(&argv, p);
	va_end(arg);
	
	runv(b, dir, mode, &argv);
	
	vfree(&argv);
}

static void genrun(Buf*, char*, int, Vec*, int);

void
runv(Buf *b, char *dir, int mode, Vec *argv)
{
	genrun(b, dir, mode, argv, 1);
}

void
bgrunv(char *dir, int mode, Vec *argv)
{
	genrun(nil, dir, mode, argv, 0);
}

#define MAXBG 4 /* maximum number of jobs to run at once */

static struct {
	PROCESS_INFORMATION pi;
	int mode;
	char *cmd;
} bg[MAXBG];

static int nbg;

static void bgwait1(void);

static void
genrun(Buf *b, char *dir, int mode, Vec *argv, int wait)
{
	int i, j, nslash;
	Buf cmd;
	char *q;
	Rune *rcmd, *rexe, *rdir;
	STARTUPINFOW si;
	PROCESS_INFORMATION pi;
	HANDLE p[2];

	while(nbg >= nelem(bg))
		bgwait1();

	binit(&cmd);

	for(i=0; i<argv->len; i++) {
		if(i > 0)
			bwritestr(&cmd, " ");
		q = argv->p[i];
		if(contains(q, " ") || contains(q, "\t") || contains(q, "\"") || contains(q, "\\\\") || hassuffix(q, "\\")) {
			bwritestr(&cmd, "\"");
			nslash = 0;
			for(; *q; q++) {
				if(*q == '\\') {
					nslash++;
					continue;
				}
				if(*q == '"') {
					for(j=0; j<2*nslash+1; j++)
						bwritestr(&cmd, "\\");
					nslash = 0;
				}
				for(j=0; j<nslash; j++)
					bwritestr(&cmd, "\\");
				nslash = 0;
				bwrite(&cmd, q, 1);
			}
			for(j=0; j<2*nslash; j++)
				bwritestr(&cmd, "\\");
			bwritestr(&cmd, "\"");
		} else {
			bwritestr(&cmd, q);
		}
	}
	if(vflag > 1)
		xprintf("%s\n", bstr(&cmd));

	torune(&rcmd, bstr(&cmd));
	rexe = nil;
	rdir = nil;
	if(dir != nil)
		torune(&rdir, dir);

	memset(&si, 0, sizeof si);
	si.cb = sizeof si;
	si.dwFlags = STARTF_USESTDHANDLES;
	si.hStdInput = INVALID_HANDLE_VALUE;
	if(b == nil) {
		si.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
		si.hStdError = GetStdHandle(STD_ERROR_HANDLE);
	} else {
		SECURITY_ATTRIBUTES seci;

		memset(&seci, 0, sizeof seci);
		seci.nLength = sizeof seci;
		seci.bInheritHandle = 1;
		breset(b);
		if(!CreatePipe(&p[0], &p[1], &seci, 0))
			fatal("CreatePipe: %s", errstr());
		si.hStdOutput = p[1];
		si.hStdError = p[1];
	}

	if(!CreateProcessW(rexe, rcmd, nil, nil, TRUE, 0, nil, rdir, &si, &pi)) {
		if(mode!=CheckExit)
			return;
		fatal("%s: %s", argv->p[0], errstr());
	}
	if(rexe != nil)
		xfree(rexe);
	xfree(rcmd);
	if(rdir != nil)
		xfree(rdir);
	if(b != nil) {
		CloseHandle(p[1]);
		breadfrom(b, p[0]);
		CloseHandle(p[0]);
	}

	if(nbg < 0)
		fatal("bad bookkeeping");
	bg[nbg].pi = pi;
	bg[nbg].mode = mode;
	bg[nbg].cmd = btake(&cmd);
	nbg++;

	if(wait)
		bgwait();

	bfree(&cmd);
}

// closes the background job for bgwait1
static void
bgwaitclose(int i)
{
	if(i < 0 || i >= nbg)
		return;

	CloseHandle(bg[i].pi.hProcess);
	CloseHandle(bg[i].pi.hThread);
	
	bg[i] = bg[--nbg];
}

// bgwait1 waits for a single background job
static void
bgwait1(void)
{
	int i, mode;
	char *cmd;
	HANDLE bgh[MAXBG];
	DWORD code;

	if(nbg == 0)
		fatal("bgwait1: nothing left");

	for(i=0; i<nbg; i++)
		bgh[i] = bg[i].pi.hProcess;
	i = WaitForMultipleObjects(nbg, bgh, FALSE, INFINITE);
	if(i < 0 || i >= nbg)
		fatal("WaitForMultipleObjects: %s", errstr());

	cmd = bg[i].cmd;
	mode = bg[i].mode;
	if(!GetExitCodeProcess(bg[i].pi.hProcess, &code)) {
		bgwaitclose(i);
		fatal("GetExitCodeProcess: %s", errstr());
		return;
	}

	if(mode==CheckExit && code != 0) {
		bgwaitclose(i);
		fatal("FAILED: %s", cmd);
		return;
	}

	bgwaitclose(i);
}

void
bgwait(void)
{
	while(nbg > 0)
		bgwait1();
}

// rgetwd returns a rune string form of the current directory's path.
static Rune*
rgetwd(void)
{
	int n;
	Rune *r;

	n = GetCurrentDirectoryW(0, nil);
	r = xmalloc((n+1)*sizeof r[0]);
	GetCurrentDirectoryW(n+1, r);
	r[n] = '\0';
	return r;
}

void
xgetwd(Buf *b)
{
	Rune *r;

	r = rgetwd();
	breset(b);
	toutf(b, r);
	xfree(r);
}

void
xrealwd(Buf *b, char *path)
{
	Rune *old;
	Rune *rnew;

	old = rgetwd();
	torune(&rnew, path);
	if(!SetCurrentDirectoryW(rnew))
		fatal("chdir %s: %s", path, errstr());
	free(rnew);
	xgetwd(b);
	if(!SetCurrentDirectoryW(old)) {
		breset(b);
		toutf(b, old);
		fatal("chdir %s: %s", bstr(b), errstr());
	}
}

bool
isdir(char *p)
{
	DWORD attr;
	Rune *r;

	torune(&r, p);
	attr = GetFileAttributesW(r);
	xfree(r);
	return attr != INVALID_FILE_ATTRIBUTES && (attr & FILE_ATTRIBUTE_DIRECTORY);
}

bool
isfile(char *p)
{
	DWORD attr;
	Rune *r;

	torune(&r, p);
	attr = GetFileAttributesW(r);
	xfree(r);
	return attr != INVALID_FILE_ATTRIBUTES && !(attr & FILE_ATTRIBUTE_DIRECTORY);
}

Time
mtime(char *p)
{
	HANDLE h;
	WIN32_FIND_DATAW data;
	Rune *r;
	FILETIME *ft;

	torune(&r, p);
	h = FindFirstFileW(r, &data);
	xfree(r);
	if(h == INVALID_HANDLE_VALUE)
		return 0;
	FindClose(h);
	ft = &data.ftLastWriteTime;
	return (Time)ft->dwLowDateTime + ((Time)ft->dwHighDateTime<<32);
}

bool
isabs(char *p)
{
	// c:/ or c:\ at beginning
	if(('A' <= p[0] && p[0] <= 'Z') || ('a' <= p[0] && p[0] <= 'z'))
		return p[1] == ':' && (p[2] == '/' || p[2] == '\\');
	// / or \ at beginning
	return p[0] == '/' || p[0] == '\\';
}

void
readfile(Buf *b, char *file)
{
	HANDLE h;
	Rune *r;

	if(vflag > 2)
		xprintf("read %s\n", file);
	torune(&r, file);
	h = CreateFileW(r, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, nil, OPEN_EXISTING, 0, 0);
	if(h == INVALID_HANDLE_VALUE)
		fatal("open %s: %s", file, errstr());
	breadfrom(b, h);
	CloseHandle(h);
}

void
writefile(Buf *b, char *file)
{
	HANDLE h;
	Rune *r;
	DWORD n;

	if(vflag > 2)
		xprintf("write %s\n", file);
	torune(&r, file);
	h = CreateFileW(r, GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, nil, CREATE_ALWAYS, 0, 0);
	if(h == INVALID_HANDLE_VALUE)
		fatal("create %s: %s", file, errstr());
	n = 0;
	if(!WriteFile(h, b->p, b->len, &n, 0))
		fatal("write %s: %s", file, errstr());
	CloseHandle(h);
}
	

void
xmkdir(char *p)
{
	Rune *r;

	torune(&r, p);
	if(!CreateDirectoryW(r, nil))
		fatal("mkdir %s: %s", p, errstr());
	xfree(r);
}

void
xmkdirall(char *p)
{
	int c;
	char *q, *q2;
	
	if(isdir(p))
		return;
	q = strrchr(p, '/');
	q2 = strrchr(p, '\\');
	if(q2 != nil && (q == nil || q < q2))
		q = q2;
	if(q != nil) {
		c = *q;
		*q = '\0';
		xmkdirall(p);
		*q = c;
	}
	xmkdir(p);
}

void
xremove(char *p)
{
	int attr;
	Rune *r;

	torune(&r, p);
	attr = GetFileAttributesW(r);
	if(attr >= 0) {
		if(attr & FILE_ATTRIBUTE_DIRECTORY)
			RemoveDirectoryW(r);
		else
			DeleteFileW(r);
	}
	xfree(r);
}

void
xreaddir(Vec *dst, char *dir)
{
	Rune *r;
	Buf b;
	HANDLE h;
	WIN32_FIND_DATAW data;
	char *p, *q;

	binit(&b);
	vreset(dst);

	bwritestr(&b, dir);
	bwritestr(&b, "\\*");
	torune(&r, bstr(&b));

	h = FindFirstFileW(r, &data);
	xfree(r);
	if(h == INVALID_HANDLE_VALUE)
		goto out;
	do{
		toutf(&b, data.cFileName);
		p = bstr(&b);
		q = xstrrchr(p, '\\');
		if(q != nil)
			p = q+1;
		if(!streq(p, ".") && !streq(p, ".."))
			vadd(dst, p);
	}while(FindNextFileW(h, &data));
	FindClose(h);

out:
	bfree(&b);
}

char*
xworkdir(void)
{
	Rune buf[1024];
	Rune tmp[MAX_PATH];
	Rune go[3] = {'g', 'o', '\0'};
	int n;
	Buf b;

	n = GetTempPathW(nelem(buf), buf);
	if(n <= 0)
		fatal("GetTempPath: %s", errstr());
	buf[n] = '\0';

	if(GetTempFileNameW(buf, go, 0, tmp) == 0)
		fatal("GetTempFileName: %s", errstr());
	DeleteFileW(tmp);
	if(!CreateDirectoryW(tmp, nil))
		fatal("create tempdir: %s", errstr());
	
	binit(&b);
	toutf(&b, tmp);
	return btake(&b);
}

void
xremoveall(char *p)
{
	int i;
	Buf b;
	Vec dir;
	Rune *r;

	binit(&b);
	vinit(&dir);

	torune(&r, p);
	if(isdir(p)) {
		xreaddir(&dir, p);
		for(i=0; i<dir.len; i++) {
			bprintf(&b, "%s/%s", p, dir.p[i]);
			xremoveall(bstr(&b));
		}
		RemoveDirectoryW(r);
	} else {
		DeleteFileW(r);
	}
	xfree(r);
	
	bfree(&b);
	vfree(&dir);	
}

void
fatal(char *msg, ...)
{
	static char buf1[1024];
	va_list arg;

	va_start(arg, msg);
	vsnprintf(buf1, sizeof buf1, msg, arg);
	va_end(arg);

	xprintf("go tool dist: %s\n", buf1);
	
	bgwait();
	ExitProcess(1);
}

// HEAP is the persistent handle to the default process heap.
static HANDLE HEAP = INVALID_HANDLE_VALUE;

void*
xmalloc(int n)
{
	void *p;

	if(HEAP == INVALID_HANDLE_VALUE)
		HEAP = GetProcessHeap();
	p = HeapAlloc(HEAP, 0, n);
	if(p == nil)
		fatal("out of memory allocating %d: %s", n, errstr());
	memset(p, 0, n);
	return p;
}

char*
xstrdup(char *p)
{
	char *q;

	q = xmalloc(strlen(p)+1);
	strcpy(q, p);
	return q;
}

void
xfree(void *p)
{
	if(HEAP == INVALID_HANDLE_VALUE)
		HEAP = GetProcessHeap();
	HeapFree(HEAP, 0, p);
}

void*
xrealloc(void *p, int n)
{
	if(p == nil)
		return xmalloc(n);
	if(HEAP == INVALID_HANDLE_VALUE)
		HEAP = GetProcessHeap();
	p = HeapReAlloc(HEAP, 0, p, n);
	if(p == nil)
		fatal("out of memory reallocating %d", n);
	return p;
}

bool
hassuffix(char *p, char *suffix)
{
	int np, ns;
	
	np = strlen(p);
	ns = strlen(suffix);
	return np >= ns && strcmp(p+np-ns, suffix) == 0;
}

bool
hasprefix(char *p, char *prefix)
{
	return strncmp(p, prefix, strlen(prefix)) == 0;
}

bool
contains(char *p, char *sep)
{
	return strstr(p, sep) != nil;
}

bool
streq(char *p, char *q)
{
	return strcmp(p, q) == 0;
}

char*
lastelem(char *p)
{
	char *out;

	out = p;
	for(; *p; p++)
		if(*p == '/' || *p == '\\')
			out = p+1;
	return out;
}

void
xmemmove(void *dst, void *src, int n)
{
	memmove(dst, src, n);
}

int
xmemcmp(void *a, void *b, int n)
{
	return memcmp(a, b, n);
}

int
xstrlen(char *p)
{
	return strlen(p);
}

void
xexit(int n)
{
	ExitProcess(n);
}

void
xatexit(void (*f)(void))
{
	atexit(f);
}

void
xprintf(char *fmt, ...)
{
	va_list arg;
	static char buf[1024];
	DWORD n;

	va_start(arg, fmt);
	vsnprintf(buf, sizeof buf, fmt, arg);
	va_end(arg);
	n = 0;
	WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), buf, strlen(buf), &n, 0);
}

int
main(int argc, char **argv)
{
	SYSTEM_INFO si;

	setvbuf(stdout, nil, _IOLBF, 0);
	setvbuf(stderr, nil, _IOLBF, 0);

	slash = "\\";
	gohostos = "windows";

	GetSystemInfo(&si);
	switch(si.wProcessorArchitecture) {
	case PROCESSOR_ARCHITECTURE_AMD64:
		gohostarch = "amd64";
		break;
	case PROCESSOR_ARCHITECTURE_INTEL:
		gohostarch = "386";
		break;
	default:
		fatal("unknown processor architecture");
	}

	init();

	xmain(argc, argv);
	return 0;
}

void
xqsort(void *data, int n, int elemsize, int (*cmp)(const void*, const void*))
{
	qsort(data, n, elemsize, cmp);
}

int
xstrcmp(char *a, char *b)
{
	return strcmp(a, b);
}

char*
xstrstr(char *a, char *b)
{
	return strstr(a, b);
}

char*
xstrrchr(char *p, int c)
{
	char *ep;
	
	ep = p+strlen(p);
	for(ep=p+strlen(p); ep >= p; ep--)
		if(*ep == c)
			return ep;
	return nil;
}

#endif // __WINDOWS__
