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

package net

import (
	"context"
	"io"
	"os"
	"syscall/zx/net"
	"syscall/zx/posix/socket"
)

func (a *TCPAddr) domain() socket.Domain {
	if a == nil || len(a.IP) <= IPv4len {
		return socket.DomainIpv4
	}
	if a.IP.To4() != nil {
		return socket.DomainIpv4
	}
	return socket.DomainIpv6
}

func (a *TCPAddr) family() int {
	return domainToFamily(a.domain())
}

func (a *TCPAddr) sockaddr(domain socket.Domain) (address net.SocketAddress, err error) {
	if a == nil {
		return net.SocketAddressWithIpv4(net.Ipv4SocketAddress{}), nil
	}
	return ipToSockaddr(domain, a.IP, a.Port, a.Zone)
}

func (c *TCPConn) readFrom(r io.Reader) (int64, error) {
	return genericReadFrom(c, r)
}

func (sd *sysDialer) dialTCP(ctx context.Context, laddr, raddr *TCPAddr) (*TCPConn, error) {
	if testHookDialTCP != nil {
		return testHookDialTCP(ctx, sd.network, laddr, raddr)
	}
	return sd.doDialTCP(ctx, laddr, raddr)
}

func (sd *sysDialer) doDialTCP(ctx context.Context, laddr, raddr *TCPAddr) (*TCPConn, error) {
	switch sd.network {
	case "tcp", "tcp4", "tcp6":
	default:
		return nil, UnknownNetworkError(sd.network)
	}
	if raddr == nil {
		return nil, errMissingAddress
	}
	fd, err := dialFuchsia(ctx, sd.network, laddr, raddr)
	if err != nil {
		return nil, err
	}
	return newTCPConn(fd), nil
}

func (ln *TCPListener) ok() bool { return ln != nil && ln.fd != nil }

func (ln *TCPListener) accept() (*TCPConn, error) {
	fd, err := ln.fd.accept()
	if err != nil {
		return nil, err
	}
	return newTCPConn(fd), nil
}

func (ln *TCPListener) close() error { return ln.fd.Close() }

func (ln *TCPListener) file() (*os.File, error) { return ln.fd.dup() }

func (sl *sysListener) listenTCP(ctx context.Context, laddr *TCPAddr) (*TCPListener, error) {
	fd, err := dialFuchsia(ctx, sl.network, laddr, nil)
	if err != nil {
		return nil, err
	}
	return &TCPListener{fd: fd, lc: sl.ListenConfig}, nil
}
