// 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 (
	"internal/byteorder"
	"sync/atomic"
	"syscall"
	"unsafe"
)

type SysFile struct {
	// RefCountPtr is a pointer to the reference count of Sysfd.
	//
	// WASI preview 1 lacks a dup(2) system call. When the os and net packages
	// need to share a file/socket, instead of duplicating the underlying file
	// descriptor, we instead provide a way to copy FD instances and manage the
	// underlying file descriptor with reference counting.
	RefCountPtr *int32

	// RefCount is the reference count of Sysfd. When a copy of an FD is made,
	// it points to the reference count of the original FD instance.
	RefCount int32

	// 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.
}

func (s *SysFile) init() {
	if s.RefCountPtr == nil {
		s.RefCount = 1
		s.RefCountPtr = &s.RefCount
	}
}

func (s *SysFile) ref() SysFile {
	atomic.AddInt32(s.RefCountPtr, +1)
	return SysFile{RefCountPtr: s.RefCountPtr}
}

func (s *SysFile) destroy(fd int) error {
	if s.RefCountPtr != nil && atomic.AddInt32(s.RefCountPtr, -1) > 0 {
		return nil
	}

	// We don't use ignoringEINTR here because POSIX does not define
	// whether the descriptor is closed if close returns EINTR.
	// If the descriptor is indeed closed, using a loop would race
	// with some other goroutine opening a new descriptor.
	// (The Linux kernel guarantees that it is closed on an EINTR error.)
	return CloseFunc(fd)
}

// Copy creates a copy of the FD.
//
// The FD instance points to the same underlying file descriptor. The file
// descriptor isn't closed until all FD instances that refer to it have been
// closed/destroyed.
func (fd *FD) Copy() FD {
	return FD{
		Sysfd:         fd.Sysfd,
		SysFile:       fd.SysFile.ref(),
		IsStream:      fd.IsStream,
		ZeroReadIsEOF: fd.ZeroReadIsEOF,
		isBlocking:    fd.isBlocking,
		isFile:        fd.isFile,
	}
}

// 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:
		return uint64(byteorder.LeUint16(b))
	case 4:
		return uint64(byteorder.LeUint32(b))
	case 8:
		return uint64(byteorder.LeUint64(b))
	default:
		panic("internal/poll: readInt with unsupported size")
	}
}
