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

package poll

import (
	"sync/atomic"
	"syscall"
	"unsafe"
)

type SysFile struct {
	// Cache for the file type, lazily initialized when Seek is called.
	Filetype uint32

	// If the file represents a directory, this field contains the current
	// readdir position. It is reset to zero if the program calls Seek(0, 0).
	Dircookie uint64

	// Absolute path of the file, as returned by syscall.PathOpen;
	// this is used by Fchdir to emulate setting the current directory
	// to an open file descriptor.
	Path string

	// TODO(achille): it could be meaningful to move isFile from FD to a method
	// on this struct type, and expose it as `IsFile() bool` which derives the
	// result from the Filetype field. We would need to ensure that Filetype is
	// always set instead of being lazily initialized.
}

// dupCloseOnExecOld always errors on wasip1 because there is no mechanism to
// duplicate file descriptors.
func dupCloseOnExecOld(fd int) (int, string, error) {
	return -1, "dup", syscall.ENOSYS
}

// Fchdir wraps syscall.Fchdir.
func (fd *FD) Fchdir() error {
	if err := fd.incref(); err != nil {
		return err
	}
	defer fd.decref()
	return syscall.Chdir(fd.Path)
}

// ReadDir wraps syscall.ReadDir.
// We treat this like an ordinary system call rather than a call
// that tries to fill the buffer.
func (fd *FD) ReadDir(buf []byte, cookie syscall.Dircookie) (int, error) {
	if err := fd.incref(); err != nil {
		return 0, err
	}
	defer fd.decref()
	for {
		n, err := syscall.ReadDir(fd.Sysfd, buf, cookie)
		if err != nil {
			n = 0
			if err == syscall.EAGAIN && fd.pd.pollable() {
				if err = fd.pd.waitRead(fd.isFile); err == nil {
					continue
				}
			}
		}
		// Do not call eofError; caller does not expect to see io.EOF.
		return n, err
	}
}

func (fd *FD) ReadDirent(buf []byte) (int, error) {
	n, err := fd.ReadDir(buf, fd.Dircookie)
	if err != nil {
		return 0, err
	}
	if n <= 0 {
		return n, nil // EOF
	}

	// We assume that the caller of ReadDirent will consume the entire buffer
	// up to the last full entry, so we scan through the buffer looking for the
	// value of the last next cookie.
	b := buf[:n]

	for len(b) > 0 {
		next, ok := direntNext(b)
		if !ok {
			break
		}
		size, ok := direntReclen(b)
		if !ok {
			break
		}
		if size > uint64(len(b)) {
			break
		}
		fd.Dircookie = syscall.Dircookie(next)
		b = b[size:]
	}

	// Trim a potentially incomplete trailing entry; this is necessary because
	// the code in src/os/dir_unix.go does not deal well with partial values in
	// calls to direntReclen, etc... and ends up causing an early EOF before all
	// directory entries were consumed. ReadDirent is called with a large enough
	// buffer (8 KiB) that at least one entry should always fit, tho this seems
	// a bit brittle but cannot be addressed without a large change of the
	// algorithm in the os.(*File).readdir method.
	return n - len(b), nil
}

// Seek wraps syscall.Seek.
func (fd *FD) Seek(offset int64, whence int) (int64, error) {
	if err := fd.incref(); err != nil {
		return 0, err
	}
	defer fd.decref()
	// syscall.Filetype is a uint8 but we store it as a uint32 in SysFile in
	// order to use atomic load/store on the field, which is why we have to
	// perform this type conversion.
	fileType := syscall.Filetype(atomic.LoadUint32(&fd.Filetype))

	if fileType == syscall.FILETYPE_UNKNOWN {
		var stat syscall.Stat_t
		if err := fd.Fstat(&stat); err != nil {
			return 0, err
		}
		fileType = stat.Filetype
		atomic.StoreUint32(&fd.Filetype, uint32(fileType))
	}

	if fileType == syscall.FILETYPE_DIRECTORY {
		// If the file descriptor is opened on a directory, we reset the readdir
		// cookie when seeking back to the beginning to allow reusing the file
		// descriptor to scan the directory again.
		if offset == 0 && whence == 0 {
			fd.Dircookie = 0
			return 0, nil
		} else {
			return 0, syscall.EINVAL
		}
	}

	return syscall.Seek(fd.Sysfd, offset, whence)
}

// https://github.com/WebAssembly/WASI/blob/main/legacy/preview1/docs.md#-dirent-record
const sizeOfDirent = 24

func direntReclen(buf []byte) (uint64, bool) {
	namelen, ok := direntNamlen(buf)
	return sizeOfDirent + namelen, ok
}

func direntNamlen(buf []byte) (uint64, bool) {
	return readInt(buf, unsafe.Offsetof(syscall.Dirent{}.Namlen), unsafe.Sizeof(syscall.Dirent{}.Namlen))
}

func direntNext(buf []byte) (uint64, bool) {
	return readInt(buf, unsafe.Offsetof(syscall.Dirent{}.Next), unsafe.Sizeof(syscall.Dirent{}.Next))
}

// readInt returns the size-bytes unsigned integer in native byte order at offset off.
func readInt(b []byte, off, size uintptr) (u uint64, ok bool) {
	if len(b) < int(off+size) {
		return 0, false
	}
	return readIntLE(b[off:], size), true
}

func readIntLE(b []byte, size uintptr) uint64 {
	switch size {
	case 1:
		return uint64(b[0])
	case 2:
		_ = b[1] // bounds check hint to compiler; see golang.org/issue/14808
		return uint64(b[0]) | uint64(b[1])<<8
	case 4:
		_ = b[3] // bounds check hint to compiler; see golang.org/issue/14808
		return uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24
	case 8:
		_ = b[7] // bounds check hint to compiler; see golang.org/issue/14808
		return uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 |
			uint64(b[4])<<32 | uint64(b[5])<<40 | uint64(b[6])<<48 | uint64(b[7])<<56
	default:
		panic("internal/poll: readInt with unsupported size")
	}
}
