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

// Fork, exec, wait, etc.

package syscall

import (
	"sync"
	"utf16"
)

// Windows doesn't have a good concept of just Exec in the documented API.
// However, the kernel32 CreateProcess does a good job with
// ForkExec.

var ForkLock sync.RWMutex

// Joins an array of string with sep
// From the "strings" package.  Modified.
func stringJoin(a []string, sep string, escape escapeFunc) string {
	if len(a) == 0 {
		return ""
	}
	if len(a) == 1 {
		return a[0]
	}
	n := len(sep) * (len(a) - 1)
	for i := 0; i < len(a); i++ {
		a[i] = escape(a[i])
		n += len(a[i])
	}

	b := make([]byte, n)
	bp := 0
	for i := 0; i < len(a); i++ {
		s := a[i]
		for j := 0; j < len(s); j++ {
			b[bp] = s[j]
			bp++
		}
		if i+1 < len(a) {
			s = sep
			for j := 0; j < len(s); j++ {
				b[bp] = s[j]
				bp++
			}
		}
	}
	return string(b)
}

//Env block is a sequence of null terminated strings followed by a null.
//Last bytes are two unicode nulls, or four null bytes.
func createEnvBlock(envv []string) *uint16 {
	if len(envv) == 0 {
		return &utf16.Encode([]int("\x00\x00"))[0]
	}
	length := 0
	for _, s := range envv {
		length += len(s) + 1
	}
	length += 1

	b := make([]byte, length)
	i := 0
	for _, s := range envv {
		l := len(s)
		copy(b[i:i+l], []byte(s))
		copy(b[i+l:i+l+1], []byte{0})
		i = i + l + 1
	}
	copy(b[i:i+1], []byte{0})

	return &utf16.Encode([]int(string(b)))[0]
}

type escapeFunc func(s string) string

//escapes quotes by " -> ""
//Also string -> "string"
func escapeAddQuotes(s string) string {
	//normal ascii char, one byte wide
	rune := byte('"')
	l := len(s)
	n := 0
	for i := 0; i < l; i++ {
		if s[i] == rune {
			n++
		}
	}
	qs := make([]byte, l+n+2)

	qs[0] = rune
	j := 1
	for i := 0; i < l; i++ {
		qs[i+j] = s[i]
		if s[i] == rune {
			j++
			qs[i+j] = rune
		}
	}
	qs[len(qs)-1] = rune
	return string(qs)
}


func CloseOnExec(fd int) {
	return
}

func SetNonblock(fd int, nonblocking bool) (errno int) {
	return 0
}


// TODO(kardia): Add trace
//The command and arguments are passed via the Command line parameter.
//Thus, repeating the exec name in the first argument is unneeded.
func forkExec(argv0 string, argv []string, envv []string, traceme bool, dir string, fd []int) (pid int, err int) {
	if traceme == true {
		return 0, EWINDOWS
	}

	if len(fd) > 3 {
		return 0, EWINDOWS
	}

	//CreateProcess will throw an error if the dir is not set to a valid dir
	//  thus get the working dir if dir is empty.
	if len(dir) == 0 {
		if wd, ok := Getwd(); ok == 0 {
			dir = wd
		}
	}

	startupInfo := new(StartupInfo)
	processInfo := new(ProcessInformation)

	GetStartupInfo(startupInfo)

	startupInfo.Flags = STARTF_USESTDHANDLES
	startupInfo.StdInput = 0
	startupInfo.StdOutput = 0
	startupInfo.StdErr = 0

	var currentProc, _ = GetCurrentProcess()
	if len(fd) > 0 && fd[0] > 0 {
		if ok, err := DuplicateHandle(currentProc, int32(fd[0]), currentProc, &startupInfo.StdInput, 0, true, DUPLICATE_SAME_ACCESS); !ok {
			return 0, err
		}
	}
	if len(fd) > 1 && fd[1] > 0 {
		if ok, err := DuplicateHandle(currentProc, int32(fd[1]), currentProc, &startupInfo.StdOutput, 0, true, DUPLICATE_SAME_ACCESS); !ok {
			return 0, err
		}
	}
	if len(fd) > 2 && fd[2] > 0 {
		if ok, err := DuplicateHandle(currentProc, int32(fd[2]), currentProc, &startupInfo.StdErr, 0, true, DUPLICATE_SAME_ACCESS); !ok {
			return 0, err
		}
	}

	// argv0 must not be longer then 256 chars
	// but the entire cmd line can have up to 32k chars (msdn)
	ok, err := CreateProcess(
		nil,
		StringToUTF16Ptr(escapeAddQuotes(argv0)+" "+stringJoin(argv, " ", escapeAddQuotes)),
		nil,  //ptr to struct lpProcessAttributes
		nil,  //ptr to struct lpThreadAttributes
		true, //bInheritHandles
		CREATE_UNICODE_ENVIRONMENT, //Flags
		createEnvBlock(envv),       //env block, NULL uses parent env
		StringToUTF16Ptr(dir),
		startupInfo,
		processInfo)

	if ok {
		pid = int(processInfo.ProcessId)
		CloseHandle(processInfo.Process)
		CloseHandle(processInfo.Thread)
	}
	return
}

func ForkExec(argv0 string, argv []string, envv []string, dir string, fd []int) (pid int, err int) {
	return forkExec(argv0, argv, envv, false, dir, fd)
}

// PtraceForkExec is like ForkExec, but starts the child in a traced state.
func PtraceForkExec(argv0 string, argv []string, envv []string, dir string, fd []int) (pid int, err int) {
	return forkExec(argv0, argv, envv, true, dir, fd)
}

// Ordinary exec.
func Exec(argv0 string, argv []string, envv []string) (err int) {
	return EWINDOWS
}
