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

// TODO: move to using fd_unix for fuchsia?

package net

import (
	"errors"
	"internal/poll"
	"os"
	"runtime"
	"syscall"
	"syscall/zx/mxnet"
	"syscall/zx/zxsocket"
	"time"
)

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

	// immutable until Close
	sock        *zxsocket.Socket
	net         string
	family      int
	sotype      int
	isStream    bool
	isConnected bool
	laddr       Addr
	raddr       Addr
}

func newFD(sock *zxsocket.Socket, family, sotype int, net string) *netFD {
	netfd := &netFD{
		pfd: poll.FD{
			Sysfd: syscall.OpenFDIO(sock),
		},
		sock:   sock,
		family: family,
		sotype: sotype,
		net:    net,
	}
	return netfd
}

func (fd *netFD) init() error {
	// TODO: flip to true after implementing netpoller for real
	return fd.pfd.Init(fd.net, false)
}

func (fd *netFD) isTCP() bool {
	return len(fd.net) >= 3 && fd.net[:3] == "tcp"
}

func (fd *netFD) Read(b []byte) (n int, err error) {
	n, err = fd.pfd.Read(b)
	runtime.KeepAlive(fd)
	return n, err
}

func (fd *netFD) Write(b []byte) (n int, err error) {
	n, err = fd.pfd.Write(b)
	runtime.KeepAlive(fd)
	return n, err
}

func (fd *netFD) readMsg(b []byte) (n, flags int, addr string, port uint16, err error) {
	// TODO: move call to pfd
	data, flags, addr, port, err := fd.sock.RecvMsg(len(b))
	runtime.KeepAlive(fd)
	n = copy(b, data)
	return n, flags, addr, port, err
}

func (fd *netFD) sendMsg(b []byte, addr string, port uint16) (n int, err error) {
	// TODO: move call to pfd
	n, err = fd.sock.SendMsg(b, addr, port)
	runtime.KeepAlive(fd)
	return n, err
}

func (fd *netFD) closeRead() error {
	return errors.New("net: closeRead not implemented on fuchsia")
}

func (fd *netFD) closeWrite() error {
	return errors.New("net: closeWrite not implemented on fuchsia")
}

func (fd *netFD) Close() error {
	return fd.pfd.Close()
}

func (fd *netFD) dup() (*os.File, error) {
	// TODO(mknyszek): fd.sock is an FDIO so one can make an FD from it to
	// implement this.
	return nil, errors.New("net: dup not implemented on fuchsia")
}

func (fd *netFD) accept() (*netFD, error) {
	newm, err := fd.pfd.Accept()
	if err != nil {
		return nil, err
	}
	netfd := newFD(newm, fd.family, fd.sotype, fd.net)
	if err := netfd.init(); err != nil {
		fd.Close()
		return nil, err
	}
	netfd.setAddr()
	return netfd, nil
}

func (fd *netFD) asAddr(code int16, b []byte, err error) sockaddr {
	if err != nil {
		return nil
	}
	if code != 0 {
		return nil
	}
	addr, port, err := mxnet.DecodeSockaddr(b)
	if err != nil {
		return nil
	}
	ip := IP(addr)
	if isZeros(ip) && port == 0 {
		return nil
	}
	switch fd.sotype {
	case syscall.SOCK_STREAM:
		return &TCPAddr{IP: ip, Port: int(port)}
	case syscall.SOCK_DGRAM:
		return &UDPAddr{IP: ip, Port: int(port)}
	}
	return nil
}

func (fd *netFD) setAddr() {
	fd.laddr = fd.asAddr(fd.sock.GetSockName())
	fd.raddr = fd.asAddr(fd.sock.GetPeerName())
	runtime.SetFinalizer(fd, (*netFD).Close)
}

func (fd *netFD) SetDeadline(t time.Time) error {
	return fd.pfd.SetDeadline(t)
}

func (fd *netFD) SetReadDeadline(t time.Time) error {
	return fd.pfd.SetReadDeadline(t)
}

func (fd *netFD) SetWriteDeadline(t time.Time) error {
	return fd.pfd.SetWriteDeadline(t)
}
