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

// Plan 9 system calls.
// This file is compiled as ordinary Go code,
// but it is also input to mksyscall,
// which parses the //sys lines and generates system call stubs.
// Note that sometimes we use a lowercase //sys name and
// wrap it in our own nicer implementation.

package syscall

import "unsafe"

const OS = "plan9"

const ImplementsGetwd = true

// An Error can represent any printable error condition.
type Error interface {
	error
}

// ErrorString implements Error's String method by returning itself.
type ErrorString string

func (e ErrorString) Error() string { return string(e) }

// NewError converts s to an ErrorString, which satisfies the Error interface.
func NewError(s string) Error { return ErrorString(s) }

var (
	Stdin  = 0
	Stdout = 1
	Stderr = 2

	EAFNOSUPPORT = NewError("address family not supported by protocol")
	EISDIR       = NewError("file is a directory")
)

// For testing: clients can set this flag to force
// creation of IPv6 sockets to return EAFNOSUPPORT.
var SocketDisableIPv6 bool

func Syscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err string)
func Syscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err string)
func RawSyscall(trap, a1, a2, a3 uintptr) (r1, r2, err uintptr)
func RawSyscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr)

func atoi(b []byte) (n uint) {
	n = 0
	for i := 0; i < len(b); i++ {
		n = n*10 + uint(b[i]-'0')
	}
	return
}

func cstring(s []byte) string {
	for i := range s {
		if s[i] == 0 {
			return string(s[0:i])
		}
	}
	return string(s)
}

func errstr() string {
	var buf [ERRMAX]byte

	RawSyscall(SYS_ERRSTR, uintptr(unsafe.Pointer(&buf[0])), uintptr(len(buf)), 0)

	buf[len(buf)-1] = 0
	return cstring(buf[:])
}

func Getpagesize() int { return 4096 }

//sys	exits(msg *byte)
func Exits(msg *string) {
	if msg == nil {
		exits(nil)
	}

	exits(StringBytePtr(*msg))
}

func Exit(code int) {
	if code == 0 {
		Exits(nil)
	}

	msg := itoa(code)
	Exits(&msg)
}

func readnum(path string) (uint, Error) {
	var b [12]byte

	fd, e := Open(path, O_RDONLY)
	if e != nil {
		return 0, e
	}
	defer Close(fd)

	n, e := Pread(fd, b[:], 0)

	if e != nil {
		return 0, e
	}

	m := 0
	for ; m < n && b[m] == ' '; m++ {
	}

	return atoi(b[m : n-1]), nil
}

func Getpid() (pid int) {
	n, _ := readnum("#c/pid")
	return int(n)
}

func Getppid() (ppid int) {
	n, _ := readnum("#c/ppid")
	return int(n)
}

func Read(fd int, p []byte) (n int, err Error) {
	return Pread(fd, p, -1)
}

func Write(fd int, p []byte) (n int, err Error) {
	return Pwrite(fd, p, -1)
}

func Getwd() (wd string, err Error) {
	fd, e := Open(".", O_RDONLY)

	if e != nil {
		return "", e
	}
	defer Close(fd)

	return Fd2path(fd)
}

//sys	fd2path(fd int, buf []byte) (err Error)
func Fd2path(fd int) (path string, err Error) {
	var buf [512]byte

	e := fd2path(fd, buf[:])
	if e != nil {
		return "", e
	}
	return cstring(buf[:]), nil
}

//sys	pipe(p *[2]_C_int) (err Error)
func Pipe(p []int) (err Error) {
	if len(p) != 2 {
		return NewError("bad arg in system call")
	}
	var pp [2]_C_int
	err = pipe(&pp)
	p[0] = int(pp[0])
	p[1] = int(pp[1])
	return
}

//sys	sleep(millisecs int32) (err Error)
func Sleep(nsec int64) (err Error) {
	return sleep(int32((nsec + 999) / 1e6)) // round up to microsecond
}

// Underlying system call writes to newoffset via pointer.
// Implemented in assembly to avoid allocation.
func seek(placeholder uintptr, fd int, offset int64, whence int) (newoffset int64, err string)

func Seek(fd int, offset int64, whence int) (newoffset int64, err Error) {
	newoffset, e := seek(0, fd, offset, whence)

	err = nil
	if newoffset == -1 {
		err = NewError(e)
	}
	return
}

func Mkdir(path string, mode uint32) (err Error) {
	fd, err := Create(path, O_RDONLY, DMDIR|mode)

	if fd != -1 {
		Close(fd)
	}

	return
}

type Waitmsg struct {
	Pid  int
	Time [3]uint32
	Msg  string
}

func (w Waitmsg) Exited() bool   { return true }
func (w Waitmsg) Signaled() bool { return false }

func (w Waitmsg) ExitStatus() int {
	if len(w.Msg) == 0 {
		// a normal exit returns no message
		return 0
	}
	return 1
}

//sys	await(s []byte) (n int, err Error)
func Await(w *Waitmsg) (err Error) {
	var buf [512]byte
	var f [5][]byte

	n, err := await(buf[:])

	if err != nil || w == nil {
		return
	}

	nf := 0
	p := 0
	for i := 0; i < n && nf < len(f)-1; i++ {
		if buf[i] == ' ' {
			f[nf] = buf[p:i]
			p = i + 1
			nf++
		}
	}
	f[nf] = buf[p:]
	nf++

	if nf != len(f) {
		return NewError("invalid wait message")
	}
	w.Pid = int(atoi(f[0]))
	w.Time[0] = uint32(atoi(f[1]))
	w.Time[1] = uint32(atoi(f[2]))
	w.Time[2] = uint32(atoi(f[3]))
	w.Msg = cstring(f[4])
	if w.Msg == "''" {
		// await() returns '' for no error
		w.Msg = ""
	}
	return
}

func Unmount(name, old string) (err Error) {
	oldp := uintptr(unsafe.Pointer(StringBytePtr(old)))

	var r0 uintptr
	var e string

	// bind(2) man page: If name is zero, everything bound or mounted upon old is unbound or unmounted.
	if name == "" {
		r0, _, e = Syscall(SYS_UNMOUNT, _zero, oldp, 0)
	} else {
		r0, _, e = Syscall(SYS_UNMOUNT, uintptr(unsafe.Pointer(StringBytePtr(name))), oldp, 0)
	}

	err = nil
	if int(r0) == -1 {
		err = NewError(e)
	}
	return
}

func Fchdir(fd int) (err Error) {
	path, err := Fd2path(fd)

	if err != nil {
		return
	}

	return Chdir(path)
}

type Timeval struct {
	Sec  int32
	Usec int32
}

func NsecToTimeval(nsec int64) (tv Timeval) {
	nsec += 999 // round up to microsecond
	tv.Usec = int32(nsec % 1e9 / 1e3)
	tv.Sec = int32(nsec / 1e9)
	return
}

func DecodeBintime(b []byte) (nsec int64, err Error) {
	if len(b) != 8 {
		return -1, NewError("bad /dev/bintime format")
	}
	err = nil
	nsec = int64(b[0])<<56 |
		int64(b[1])<<48 |
		int64(b[2])<<40 |
		int64(b[3])<<32 |
		int64(b[4])<<24 |
		int64(b[5])<<16 |
		int64(b[6])<<8 |
		int64(b[7])
	return
}

func Gettimeofday(tv *Timeval) (err Error) {
	// TODO(paulzhol): 
	// avoid reopening a file descriptor for /dev/bintime on each call,
	// use lower-level calls to avoid allocation.

	var b [8]byte
	var nsec int64

	fd, e := Open("/dev/bintime", O_RDONLY)
	if e != nil {
		return e
	}
	defer Close(fd)

	if _, e = Pread(fd, b[:], 0); e != nil {
		return e
	}

	if nsec, e = DecodeBintime(b[:]); e != nil {
		return e
	}
	*tv = NsecToTimeval(nsec)

	return e
}

func Getegid() (egid int) { return -1 }
func Geteuid() (euid int) { return -1 }
func Getgid() (gid int)   { return -1 }
func Getuid() (uid int)   { return -1 }

func Getgroups() (gids []int, err Error) {
	return make([]int, 0), nil
}

//sys	Dup(oldfd int, newfd int) (fd int, err Error)
//sys	Open(path string, mode int) (fd int, err Error)
//sys	Create(path string, mode int, perm uint32) (fd int, err Error)
//sys	Remove(path string) (err Error)
//sys	Pread(fd int, p []byte, offset int64) (n int, err Error)
//sys	Pwrite(fd int, p []byte, offset int64) (n int, err Error)
//sys	Close(fd int) (err Error)
//sys	Chdir(path string) (err Error)
//sys	Bind(name string, old string, flag int) (err Error)
//sys	Mount(fd int, afd int, old string, flag int, aname string) (err Error)
//sys	Stat(path string, edir []byte) (n int, err Error)
//sys	Fstat(fd int, edir []byte) (n int, err Error)
//sys	Wstat(path string, edir []byte) (err Error)
//sys	Fwstat(fd int, edir []byte) (err Error)
