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

// Windows environment variables.

package os

import (
	"syscall"
	"utf16"
	"unsafe"
)

// ENOENV is the Error indicating that an environment variable does not exist.
var ENOENV = NewError("no such environment variable")

// Getenverror retrieves the value of the environment variable named by the key.
// It returns the value and an error, if any.
func Getenverror(key string) (value string, err Error) {
	b := make([]uint16, 100)
	n, e := syscall.GetEnvironmentVariable(syscall.StringToUTF16Ptr(key), &b[0], uint32(len(b)))
	if n == 0 && e == syscall.ERROR_ENVVAR_NOT_FOUND {
		return "", ENOENV
	}
	if n > uint32(len(b)) {
		b = make([]uint16, n)
		n, e = syscall.GetEnvironmentVariable(syscall.StringToUTF16Ptr(key), &b[0], uint32(len(b)))
		if n > uint32(len(b)) {
			n = 0
		}
	}
	if n == 0 {
		return "", NewSyscallError("GetEnvironmentVariable", e)
	}
	return string(utf16.Decode(b[0:n])), nil
}

// Getenv retrieves the value of the environment variable named by the key.
// It returns the value, which will be empty if the variable is not present.
func Getenv(key string) string {
	v, _ := Getenverror(key)
	return v
}

// Setenv sets the value of the environment variable named by the key.
// It returns an Error, if any.
func Setenv(key, value string) Error {
	var v *uint16
	if len(value) > 0 {
		v = syscall.StringToUTF16Ptr(value)
	}
	ok, e := syscall.SetEnvironmentVariable(syscall.StringToUTF16Ptr(key), v)
	if !ok {
		return NewSyscallError("SetEnvironmentVariable", e)
	}
	return nil
}

// Clearenv deletes all environment variables.
func Clearenv() {
	for _, s := range Environ() {
		// Environment variables can begin with =
		// so start looking for the separator = at j=1.
		// http://blogs.msdn.com/b/oldnewthing/archive/2010/05/06/10008132.aspx
		for j := 1; j < len(s); j++ {
			if s[j] == '=' {
				Setenv(s[0:j], "")
				break
			}
		}
	}
}

// Environ returns an array of strings representing the environment,
// in the form "key=value".
func Environ() []string {
	s, e := syscall.GetEnvironmentStrings()
	if e != 0 {
		return nil
	}
	defer syscall.FreeEnvironmentStrings(s)
	r := make([]string, 0, 50) // Empty with room to grow.
	for from, i, p := 0, 0, (*[1 << 24]uint16)(unsafe.Pointer(s)); true; i++ {
		if p[i] == 0 {
			// empty string marks the end
			if i <= from {
				break
			}
			if len(r) == cap(r) {
				nr := make([]string, len(r), 2*len(r))
				for k := 0; k < len(r); k++ {
					nr[k] = r[k]
				}
				r = nr
			}
			r = r[0 : len(r)+1]
			r[len(r)-1] = string(utf16.Decode(p[from:i]))
			from = i + 1
		}
	}
	return r
}

// TempDir returns the default directory to use for temporary files.
func TempDir() string {
	const pathSep = '\\'
	dirw := make([]uint16, syscall.MAX_PATH)
	n, _ := syscall.GetTempPath(uint32(len(dirw)), &dirw[0])
	if n > uint32(len(dirw)) {
		dirw = make([]uint16, n)
		n, _ = syscall.GetTempPath(uint32(len(dirw)), &dirw[0])
		if n > uint32(len(dirw)) {
			n = 0
		}
	}
	if n > 0 && dirw[n-1] == pathSep {
		n--
	}
	return string(utf16.Decode(dirw[0:n]))
}
