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

//go:build js && wasm
// +build js,wasm

package syscall

import (
	"errors"
	"sync"
	"syscall/js"
)

// Provided by package runtime.
func now() (sec int64, nsec int32)

var jsProcess = js.Global().Get("process")
var jsFS = js.Global().Get("fs")
var constants = jsFS.Get("constants")

var uint8Array = js.Global().Get("Uint8Array")

var (
	nodeWRONLY = constants.Get("O_WRONLY").Int()
	nodeRDWR   = constants.Get("O_RDWR").Int()
	nodeCREATE = constants.Get("O_CREAT").Int()
	nodeTRUNC  = constants.Get("O_TRUNC").Int()
	nodeAPPEND = constants.Get("O_APPEND").Int()
	nodeEXCL   = constants.Get("O_EXCL").Int()
)

type jsFile struct {
	path    string
	entries []string
	dirIdx  int // entries[:dirIdx] have already been returned in ReadDirent
	pos     int64
	seeked  bool
}

var filesMu sync.Mutex
var files = map[int]*jsFile{
	0: {},
	1: {},
	2: {},
}

func fdToFile(fd int) (*jsFile, error) {
	filesMu.Lock()
	f, ok := files[fd]
	filesMu.Unlock()
	if !ok {
		return nil, EBADF
	}
	return f, nil
}

func Open(path string, openmode int, perm uint32) (int, error) {
	if err := checkPath(path); err != nil {
		return 0, err
	}

	flags := 0
	if openmode&O_WRONLY != 0 {
		flags |= nodeWRONLY
	}
	if openmode&O_RDWR != 0 {
		flags |= nodeRDWR
	}
	if openmode&O_CREATE != 0 {
		flags |= nodeCREATE
	}
	if openmode&O_TRUNC != 0 {
		flags |= nodeTRUNC
	}
	if openmode&O_APPEND != 0 {
		flags |= nodeAPPEND
	}
	if openmode&O_EXCL != 0 {
		flags |= nodeEXCL
	}
	if openmode&O_SYNC != 0 {
		return 0, errors.New("syscall.Open: O_SYNC is not supported by js/wasm")
	}

	jsFD, err := fsCall("open", path, flags, perm)
	if err != nil {
		return 0, err
	}
	fd := jsFD.Int()

	var entries []string
	if stat, err := fsCall("fstat", fd); err == nil && stat.Call("isDirectory").Bool() {
		dir, err := fsCall("readdir", path)
		if err != nil {
			return 0, err
		}
		entries = make([]string, dir.Length())
		for i := range entries {
			entries[i] = dir.Index(i).String()
		}
	}

	if path[0] != '/' {
		cwd := jsProcess.Call("cwd").String()
		path = cwd + "/" + path
	}
	f := &jsFile{
		path:    path,
		entries: entries,
	}
	filesMu.Lock()
	files[fd] = f
	filesMu.Unlock()
	return fd, nil
}

func Close(fd int) error {
	filesMu.Lock()
	delete(files, fd)
	filesMu.Unlock()
	_, err := fsCall("close", fd)
	return err
}

func CloseOnExec(fd int) {
	// nothing to do - no exec
}

func Mkdir(path string, perm uint32) error {
	if err := checkPath(path); err != nil {
		return err
	}
	_, err := fsCall("mkdir", path, perm)
	return err
}

func ReadDirent(fd int, buf []byte) (int, error) {
	f, err := fdToFile(fd)
	if err != nil {
		return 0, err
	}
	if f.entries == nil {
		return 0, EINVAL
	}

	n := 0
	for f.dirIdx < len(f.entries) {
		entry := f.entries[f.dirIdx]
		l := 2 + len(entry)
		if l > len(buf) {
			break
		}
		buf[0] = byte(l)
		buf[1] = byte(l >> 8)
		copy(buf[2:], entry)
		buf = buf[l:]
		n += l
		f.dirIdx++
	}

	return n, nil
}

func setStat(st *Stat_t, jsSt js.Value) {
	st.Dev = int64(jsSt.Get("dev").Int())
	st.Ino = uint64(jsSt.Get("ino").Int())
	st.Mode = uint32(jsSt.Get("mode").Int())
	st.Nlink = uint32(jsSt.Get("nlink").Int())
	st.Uid = uint32(jsSt.Get("uid").Int())
	st.Gid = uint32(jsSt.Get("gid").Int())
	st.Rdev = int64(jsSt.Get("rdev").Int())
	st.Size = int64(jsSt.Get("size").Int())
	st.Blksize = int32(jsSt.Get("blksize").Int())
	st.Blocks = int32(jsSt.Get("blocks").Int())
	atime := int64(jsSt.Get("atimeMs").Int())
	st.Atime = atime / 1000
	st.AtimeNsec = (atime % 1000) * 1000000
	mtime := int64(jsSt.Get("mtimeMs").Int())
	st.Mtime = mtime / 1000
	st.MtimeNsec = (mtime % 1000) * 1000000
	ctime := int64(jsSt.Get("ctimeMs").Int())
	st.Ctime = ctime / 1000
	st.CtimeNsec = (ctime % 1000) * 1000000
}

func Stat(path string, st *Stat_t) error {
	if err := checkPath(path); err != nil {
		return err
	}
	jsSt, err := fsCall("stat", path)
	if err != nil {
		return err
	}
	setStat(st, jsSt)
	return nil
}

func Lstat(path string, st *Stat_t) error {
	if err := checkPath(path); err != nil {
		return err
	}
	jsSt, err := fsCall("lstat", path)
	if err != nil {
		return err
	}
	setStat(st, jsSt)
	return nil
}

func Fstat(fd int, st *Stat_t) error {
	jsSt, err := fsCall("fstat", fd)
	if err != nil {
		return err
	}
	setStat(st, jsSt)
	return nil
}

func Unlink(path string) error {
	if err := checkPath(path); err != nil {
		return err
	}
	_, err := fsCall("unlink", path)
	return err
}

func Rmdir(path string) error {
	if err := checkPath(path); err != nil {
		return err
	}
	_, err := fsCall("rmdir", path)
	return err
}

func Chmod(path string, mode uint32) error {
	if err := checkPath(path); err != nil {
		return err
	}
	_, err := fsCall("chmod", path, mode)
	return err
}

func Fchmod(fd int, mode uint32) error {
	_, err := fsCall("fchmod", fd, mode)
	return err
}

func Chown(path string, uid, gid int) error {
	if err := checkPath(path); err != nil {
		return err
	}
	_, err := fsCall("chown", path, uint32(uid), uint32(gid))
	return err
}

func Fchown(fd int, uid, gid int) error {
	_, err := fsCall("fchown", fd, uint32(uid), uint32(gid))
	return err
}

func Lchown(path string, uid, gid int) error {
	if err := checkPath(path); err != nil {
		return err
	}
	if jsFS.Get("lchown").IsUndefined() {
		// fs.lchown is unavailable on Linux until Node.js 10.6.0
		// TODO(neelance): remove when we require at least this Node.js version
		return ENOSYS
	}
	_, err := fsCall("lchown", path, uint32(uid), uint32(gid))
	return err
}

func UtimesNano(path string, ts []Timespec) error {
	if err := checkPath(path); err != nil {
		return err
	}
	if len(ts) != 2 {
		return EINVAL
	}
	atime := ts[0].Sec
	mtime := ts[1].Sec
	_, err := fsCall("utimes", path, atime, mtime)
	return err
}

func Rename(from, to string) error {
	if err := checkPath(from); err != nil {
		return err
	}
	if err := checkPath(to); err != nil {
		return err
	}
	_, err := fsCall("rename", from, to)
	return err
}

func Truncate(path string, length int64) error {
	if err := checkPath(path); err != nil {
		return err
	}
	_, err := fsCall("truncate", path, length)
	return err
}

func Ftruncate(fd int, length int64) error {
	_, err := fsCall("ftruncate", fd, length)
	return err
}

func Getcwd(buf []byte) (n int, err error) {
	defer recoverErr(&err)
	cwd := jsProcess.Call("cwd").String()
	n = copy(buf, cwd)
	return
}

func Chdir(path string) (err error) {
	if err := checkPath(path); err != nil {
		return err
	}
	defer recoverErr(&err)
	jsProcess.Call("chdir", path)
	return
}

func Fchdir(fd int) error {
	f, err := fdToFile(fd)
	if err != nil {
		return err
	}
	return Chdir(f.path)
}

func Readlink(path string, buf []byte) (n int, err error) {
	if err := checkPath(path); err != nil {
		return 0, err
	}
	dst, err := fsCall("readlink", path)
	if err != nil {
		return 0, err
	}
	n = copy(buf, dst.String())
	return n, nil
}

func Link(path, link string) error {
	if err := checkPath(path); err != nil {
		return err
	}
	if err := checkPath(link); err != nil {
		return err
	}
	_, err := fsCall("link", path, link)
	return err
}

func Symlink(path, link string) error {
	if err := checkPath(path); err != nil {
		return err
	}
	if err := checkPath(link); err != nil {
		return err
	}
	_, err := fsCall("symlink", path, link)
	return err
}

func Fsync(fd int) error {
	_, err := fsCall("fsync", fd)
	return err
}

func Read(fd int, b []byte) (int, error) {
	f, err := fdToFile(fd)
	if err != nil {
		return 0, err
	}

	if f.seeked {
		n, err := Pread(fd, b, f.pos)
		f.pos += int64(n)
		return n, err
	}

	buf := uint8Array.New(len(b))
	n, err := fsCall("read", fd, buf, 0, len(b), nil)
	if err != nil {
		return 0, err
	}
	js.CopyBytesToGo(b, buf)

	n2 := n.Int()
	f.pos += int64(n2)
	return n2, err
}

func Write(fd int, b []byte) (int, error) {
	f, err := fdToFile(fd)
	if err != nil {
		return 0, err
	}

	if f.seeked {
		n, err := Pwrite(fd, b, f.pos)
		f.pos += int64(n)
		return n, err
	}

	if faketime && (fd == 1 || fd == 2) {
		n := faketimeWrite(fd, b)
		if n < 0 {
			return 0, errnoErr(Errno(-n))
		}
		return n, nil
	}

	buf := uint8Array.New(len(b))
	js.CopyBytesToJS(buf, b)
	n, err := fsCall("write", fd, buf, 0, len(b), nil)
	if err != nil {
		return 0, err
	}
	n2 := n.Int()
	f.pos += int64(n2)
	return n2, err
}

func Pread(fd int, b []byte, offset int64) (int, error) {
	buf := uint8Array.New(len(b))
	n, err := fsCall("read", fd, buf, 0, len(b), offset)
	if err != nil {
		return 0, err
	}
	js.CopyBytesToGo(b, buf)
	return n.Int(), nil
}

func Pwrite(fd int, b []byte, offset int64) (int, error) {
	buf := uint8Array.New(len(b))
	js.CopyBytesToJS(buf, b)
	n, err := fsCall("write", fd, buf, 0, len(b), offset)
	if err != nil {
		return 0, err
	}
	return n.Int(), nil
}

func Seek(fd int, offset int64, whence int) (int64, error) {
	f, err := fdToFile(fd)
	if err != nil {
		return 0, err
	}

	var newPos int64
	switch whence {
	case 0:
		newPos = offset
	case 1:
		newPos = f.pos + offset
	case 2:
		var st Stat_t
		if err := Fstat(fd, &st); err != nil {
			return 0, err
		}
		newPos = st.Size + offset
	default:
		return 0, errnoErr(EINVAL)
	}

	if newPos < 0 {
		return 0, errnoErr(EINVAL)
	}

	f.seeked = true
	f.dirIdx = 0 // Reset directory read position. See issue 35767.
	f.pos = newPos
	return newPos, nil
}

func Dup(fd int) (int, error) {
	return 0, ENOSYS
}

func Dup2(fd, newfd int) error {
	return ENOSYS
}

func Pipe(fd []int) error {
	return ENOSYS
}

func fsCall(name string, args ...interface{}) (js.Value, error) {
	type callResult struct {
		val js.Value
		err error
	}

	c := make(chan callResult, 1)
	f := js.FuncOf(func(this js.Value, args []js.Value) interface{} {
		var res callResult

		if len(args) >= 1 { // on Node.js 8, fs.utimes calls the callback without any arguments
			if jsErr := args[0]; !jsErr.IsNull() {
				res.err = mapJSError(jsErr)
			}
		}

		res.val = js.Undefined()
		if len(args) >= 2 {
			res.val = args[1]
		}

		c <- res
		return nil
	})
	defer f.Release()
	jsFS.Call(name, append(args, f)...)
	res := <-c
	return res.val, res.err
}

// checkPath checks that the path is not empty and that it contains no null characters.
func checkPath(path string) error {
	if path == "" {
		return EINVAL
	}
	for i := 0; i < len(path); i++ {
		if path[i] == '\x00' {
			return EINVAL
		}
	}
	return nil
}

func recoverErr(errPtr *error) {
	if err := recover(); err != nil {
		jsErr, ok := err.(js.Error)
		if !ok {
			panic(err)
		}
		*errPtr = mapJSError(jsErr.Value)
	}
}

// mapJSError maps an error given by Node.js to the appropriate Go error
func mapJSError(jsErr js.Value) error {
	errno, ok := errnoByCode[jsErr.Get("code").String()]
	if !ok {
		panic(jsErr)
	}
	return errnoErr(Errno(errno))
}
