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

//+build fuchsia

// TODO: move to using fd_unix for fuchsia?

package net

import (
	"errors"
	"fmt"
	"internal/poll"
	"os"
	"runtime"
	"syscall"
	"syscall/zx/net"
	"syscall/zx/posix/socket"
	"syscall/zx/zxsocket"
	"time"
)

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

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

func domainToFamily(domain socket.Domain) int {
	switch domain {
	case socket.DomainIpv4:
		return syscall.AF_INET
	case socket.DomainIpv6:
		return syscall.AF_INET6
	default:
		panic(fmt.Sprintf("unrecognized socket domain %s(%d)", domain, domain))
	}
}

func familyToDomain(family int) socket.Domain {
	switch family {
	case syscall.AF_INET:
		return socket.DomainIpv4
	case syscall.AF_INET6:
		return socket.DomainIpv6
	default:
		panic(fmt.Sprintf("unrecognized socket family %d", family))
	}
}

func newFD(sock zxsocket.Socket, domain socket.Domain, net string) *netFD {
	return &netFD{
		pfd: poll.FD{
			Sysfd: syscall.OpenFDIO(sock),
		},
		sock:   sock,
		family: domainToFamily(domain),
		net:    net,
	}
}

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 net.SocketAddress, err error) {
	// TODO: move call to pfd
	data, addr, err := fd.sock.(*zxsocket.DatagramSocket).RecvMsg(len(b))
	runtime.KeepAlive(fd)
	n = copy(b, data)
	return n, 0, addr, err
}

func (fd *netFD) sendMsg(b []byte, addr net.SocketAddress) (n int, err error) {
	// TODO: move call to pfd
	n, err = fd.sock.(*zxsocket.DatagramSocket).SendMsg(b, addr)
	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) {
	fdio, err := fd.sock.Clone()
	if err != nil {
		return nil, err
	}
	return os.NewFile(uintptr(syscall.OpenFDIO(fdio)), fd.name()), nil
}

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

func socketAddrToIpPort(addr net.SocketAddress) (IP, int) {
	switch addr.Which() {
	case net.SocketAddressIpv4:
		return addr.Ipv4.Address.Addr[:], int(addr.Ipv4.Port)
	case net.SocketAddressIpv6:
		return addr.Ipv6.Address.Addr[:], int(addr.Ipv6.Port)
	default:
		panic(fmt.Sprintf("unrecognized SocketAddress variant %d", addr.Which()))
	}
}

func (fd *netFD) asAddr(addr net.SocketAddress, err error) sockaddr {
	if err != nil {
		return nil
	}

	ip, port := socketAddrToIpPort(addr)
	if isZeros(ip) && port == 0 {
		return nil
	}

	switch fd.sock.(type) {
	case *zxsocket.DatagramSocket:
		return &UDPAddr{IP: ip, Port: port}
	case *zxsocket.StreamSocket:
		return &TCPAddr{IP: ip, Port: port}
	default:
		panic(fmt.Sprintf("unrecognized socket type %T", fd.sock))
	}
}

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

func (fd *netFD) name() string {
	var ls, rs string
	if fd.laddr != nil {
		ls = fd.laddr.String()
	}
	if fd.raddr != nil {
		rs = fd.raddr.String()
	}
	return fd.net + ":" + ls + "->" + rs
}

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)
}
