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

package net

import (
	"context"
	"errors"
	"strings"
	"sync"
	"syscall"
	"syscall/zx"
	"syscall/zx/fdio"
	"syscall/zx/fidl"
	"syscall/zx/mxnet"
	zxnet "syscall/zx/net"
	"syscall/zx/zxsocket"
	"time"
)

func (p *ipStackCapabilities) probe() {
	p.ipv4Enabled = true
	p.ipv6Enabled = true
	p.ipv4MappedIPv6Enabled = true
}

// A sockaddr represents a TCP, UDP, IP or Unix network endpoint
// address that can be converted into an fdio sockaddr message.
type sockaddr interface {
	Addr

	family() int
	isWildcard() bool
	sockaddr(family int) (addr mxnet.Addr, port uint16, err error)
}

func favoriteAddrFamily(net string, laddr, raddr sockaddr, mode string) (family int, ipv6only bool) {
	switch net[len(net)-1] {
	case '4':
		return syscall.AF_INET, false
	case '6':
		return syscall.AF_INET6, true
	}

	if mode == "listen" && (laddr == nil || laddr.isWildcard()) {
		if supportsIPv4map() || !supportsIPv4() {
			return syscall.AF_INET6, false
		}
		if laddr == nil {
			return syscall.AF_INET, false
		}
		return laddr.family(), false
	}

	if (laddr == nil || laddr.family() == syscall.AF_INET) &&
		(raddr == nil || raddr.family() == syscall.AF_INET) {
		return syscall.AF_INET, false
	}
	return syscall.AF_INET6, false
}

var socketProvider struct {
	mu sync.Mutex
	h  zx.Handle
}

func getSocketProvider() zx.Handle {
	socketProvider.mu.Lock()
	defer socketProvider.mu.Unlock()
	if socketProvider.h == zx.HandleInvalid {
		if c0, c1, err := zx.NewChannel(0); err == nil {
			if err := fdio.ServiceConnect("/svc/"+zxnet.SocketProviderName, zx.Handle(c0)); err == nil {
				socketProvider.h = zx.Handle(c1)
			}
		}
	}
	return socketProvider.h
}

func dialFuchsia(ctx context.Context, net string, laddr, raddr sockaddr) (fd *netFD, err error) {
	family, _ := favoriteAddrFamily(net, laddr, raddr, "dial")

	sotype := syscall.SOCK_STREAM
	if strings.HasPrefix(net, "udp") {
		sotype = syscall.SOCK_DGRAM
	}

	var sp zxnet.SocketProviderInterface
	// Wait for the network stack to publish the socket device.
	// See similar logic in zircon/system/ulib/fdio/bsdsocket.c.
	for i := 0; i < 40; i++ {
		if h := getSocketProvider(); h.IsValid() {
			sp = zxnet.SocketProviderInterface(fidl.ChannelProxy{Channel: zx.Channel(h)})
			break
		}
		time.Sleep(250 * time.Millisecond)
	}
	code, s, err := sp.Socket(int16(family), int16(sotype), syscall.IPPROTO_IP)
	if err != nil {
		return nil, err
	}
	if code != 0 {
		return nil, syscall.Errno(code)
	}
	sock := zxsocket.NewSocket(s)
	if sotype == syscall.SOCK_DGRAM {
		sock.SetDgram()
	}

	fd = newFD(sock, family, sotype, net)
	if laddr != nil {
		addr, port, err := laddr.sockaddr(family)
		if err != nil {
			return nil, err
		}
		if addr != "" || port != 0 {
			b := make([]byte, mxnet.SockaddrLen)
			addrlen, err := mxnet.EncodeSockaddr(b, addr, port)
			if err != nil {
				return nil, err
			}
			b = b[:addrlen]
			if code, err := fd.sock.Bind(b); err != nil {
				return nil, err
			} else if code != 0 {
				return nil, syscall.Errno(code)
			}
		}
		if raddr == nil {
			switch sotype {
			case syscall.SOCK_STREAM:
				code, err := fd.sock.Listen(int16(listenerBacklog()))
				if err != nil {
					return nil, err
				}
				if code != 0 {
					return nil, syscall.Errno(code)
				}
			case syscall.SOCK_DGRAM:
				return nil, errors.New("net: TODO listen datagram")
			}
		}
	}
	if raddr != nil {
		addr, port, err := raddr.sockaddr(family)
		if err != nil {
			return nil, err
		}
		b := make([]byte, mxnet.SockaddrLen)
		addrlen, err := mxnet.EncodeSockaddr(b, addr, port)
		if err != nil {
			return nil, err
		}
		b = b[:addrlen]
		code, err := fd.sock.Connect(b)
		if code == syscall.EINPROGRESS {
			if obs, err := fd.sock.Wait(mxnet.MXSIO_SIGNAL_OUTGOING|zx.SignalSocketPeerClosed, zx.TimensecInfinite); err != nil {
				return nil, err
			} else if obs&zx.SignalSocketPeerClosed != 0 {
				return nil, &zx.Error{Status: zx.ErrPeerClosed, Text: "zxsocket"}
			} else if obs&mxnet.MXSIO_SIGNAL_OUTGOING != 0 {
				// fallthrough
			} else {
				panic("unreachable")
			}
			// Call connect again to learn the result.
			code, err = fd.sock.Connect(b)
		}
		if err != nil {
			return nil, err
		}
		if code != 0 {
			return nil, syscall.Errno(code)
		}
		fd.isConnected = true
	}
	fd.setAddr()

	return fd, nil
}

func ipToSockaddr(family int, ip IP, port int, zone string) (addr mxnet.Addr, portres uint16, err error) {
	switch family {
	case syscall.AF_INET:
		if len(ip) == 0 {
			ip = IPv4zero
		}
		ip4 := ip.To4()
		if ip4 == nil {
			return "", 0, &AddrError{Err: "non-IPv4 address", Addr: ip.String()}
		}
		return mxnet.Addr(ip4)[:4], uint16(port), nil
	case syscall.AF_INET6:
		if len(ip) == 0 || ip.Equal(IPv4zero) {
			ip = IPv6zero
		}
		ip6 := ip.To16()
		if ip6 == nil {
			return "", 0, &AddrError{Err: "non-IPv6 address", Addr: ip.String()}
		}
		return mxnet.Addr(ip6), uint16(port), nil
	}
	return "", 0, &AddrError{Err: "invalid address family", Addr: ip.String()}
}
