// 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 {
	String() string
}

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

func (e ErrorString) String() 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])
	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)
