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

//go:build wasip1

package net

import (
	"internal/poll"
	"runtime"
	"syscall"
	"time"
)

const (
	readSyscallName  = "fd_read"
	writeSyscallName = "fd_write"
)

// Network file descriptor.
type netFD struct {
	pfd poll.FD

	// immutable until Close
	family      int
	sotype      int
	isConnected bool // handshake completed or use of association with peer
	net         string
	laddr       Addr
	raddr       Addr

	// The only networking available in WASI preview 1 is the ability to
	// sock_accept on an pre-opened socket, and then fd_read, fd_write,
	// fd_close, and sock_shutdown on the resulting connection. We
	// intercept applicable netFD calls on this instance, and then pass
	// the remainder of the netFD calls to fakeNetFD.
	*fakeNetFD
}

func newFD(net string, sysfd int) *netFD {
	return newPollFD(net, poll.FD{
		Sysfd:         sysfd,
		IsStream:      true,
		ZeroReadIsEOF: true,
	})
}

func newPollFD(net string, pfd poll.FD) *netFD {
	var laddr Addr
	var raddr Addr
	// WASI preview 1 does not have functions like getsockname/getpeername,
	// so we cannot get access to the underlying IP address used by connections.
	//
	// However, listeners created by FileListener are of type *TCPListener,
	// which can be asserted by a Go program. The (*TCPListener).Addr method
	// documents that the returned value will be of type *TCPAddr, we satisfy
	// the documented behavior by creating addresses of the expected type here.
	switch net {
	case "tcp":
		laddr = new(TCPAddr)
		raddr = new(TCPAddr)
	case "udp":
		laddr = new(UDPAddr)
		raddr = new(UDPAddr)
	default:
		laddr = unknownAddr{}
		raddr = unknownAddr{}
	}
	return &netFD{
		pfd:   pfd,
		net:   net,
		laddr: laddr,
		raddr: raddr,
	}
}

func (fd *netFD) init() error {
	return fd.pfd.Init(fd.net, true)
}

func (fd *netFD) name() string {
	return "unknown"
}

func (fd *netFD) accept() (netfd *netFD, err error) {
	if fd.fakeNetFD != nil {
		return fd.fakeNetFD.accept()
	}
	d, _, errcall, err := fd.pfd.Accept()
	if err != nil {
		if errcall != "" {
			err = wrapSyscallError(errcall, err)
		}
		return nil, err
	}
	netfd = newFD("tcp", d)
	if err = netfd.init(); err != nil {
		netfd.Close()
		return nil, err
	}
	return netfd, nil
}

func (fd *netFD) setAddr(laddr, raddr Addr) {
	fd.laddr = laddr
	fd.raddr = raddr
	runtime.SetFinalizer(fd, (*netFD).Close)
}

func (fd *netFD) Close() error {
	if fd.fakeNetFD != nil {
		return fd.fakeNetFD.Close()
	}
	runtime.SetFinalizer(fd, nil)
	return fd.pfd.Close()
}

func (fd *netFD) shutdown(how int) error {
	if fd.fakeNetFD != nil {
		return nil
	}
	err := fd.pfd.Shutdown(how)
	runtime.KeepAlive(fd)
	return wrapSyscallError("shutdown", err)
}

func (fd *netFD) closeRead() error {
	if fd.fakeNetFD != nil {
		return fd.fakeNetFD.closeRead()
	}
	return fd.shutdown(syscall.SHUT_RD)
}

func (fd *netFD) closeWrite() error {
	if fd.fakeNetFD != nil {
		return fd.fakeNetFD.closeWrite()
	}
	return fd.shutdown(syscall.SHUT_WR)
}

func (fd *netFD) Read(p []byte) (n int, err error) {
	if fd.fakeNetFD != nil {
		return fd.fakeNetFD.Read(p)
	}
	n, err = fd.pfd.Read(p)
	runtime.KeepAlive(fd)
	return n, wrapSyscallError(readSyscallName, err)
}

func (fd *netFD) Write(p []byte) (nn int, err error) {
	if fd.fakeNetFD != nil {
		return fd.fakeNetFD.Write(p)
	}
	nn, err = fd.pfd.Write(p)
	runtime.KeepAlive(fd)
	return nn, wrapSyscallError(writeSyscallName, err)
}

func (fd *netFD) SetDeadline(t time.Time) error {
	if fd.fakeNetFD != nil {
		return fd.fakeNetFD.SetDeadline(t)
	}
	return fd.pfd.SetDeadline(t)
}

func (fd *netFD) SetReadDeadline(t time.Time) error {
	if fd.fakeNetFD != nil {
		return fd.fakeNetFD.SetReadDeadline(t)
	}
	return fd.pfd.SetReadDeadline(t)
}

func (fd *netFD) SetWriteDeadline(t time.Time) error {
	if fd.fakeNetFD != nil {
		return fd.fakeNetFD.SetWriteDeadline(t)
	}
	return fd.pfd.SetWriteDeadline(t)
}

type unknownAddr struct{}

func (unknownAddr) Network() string { return "unknown" }
func (unknownAddr) String() string  { return "unknown" }
