// Copyright 2017 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 aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris
// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris

package socket

import (
	"net"
	"unsafe"

	"golang.org/x/sys/unix"
)

//go:linkname syscall_getsockopt syscall.getsockopt
func syscall_getsockopt(s, level, name int, val unsafe.Pointer, vallen *uint32) error

//go:linkname syscall_setsockopt syscall.setsockopt
func syscall_setsockopt(s, level, name int, val unsafe.Pointer, vallen uintptr) error

func getsockopt(s uintptr, level, name int, b []byte) (int, error) {
	l := uint32(len(b))
	err := syscall_getsockopt(int(s), level, name, unsafe.Pointer(&b[0]), &l)
	return int(l), err
}

func setsockopt(s uintptr, level, name int, b []byte) error {
	return syscall_setsockopt(int(s), level, name, unsafe.Pointer(&b[0]), uintptr(len(b)))
}

func recvmsg(s uintptr, buffers [][]byte, oob []byte, flags int, network string) (n, oobn int, recvflags int, from net.Addr, err error) {
	var unixFrom unix.Sockaddr
	n, oobn, recvflags, unixFrom, err = unix.RecvmsgBuffers(int(s), buffers, oob, flags)
	if unixFrom != nil {
		from = sockaddrToAddr(unixFrom, network)
	}
	return
}

func sendmsg(s uintptr, buffers [][]byte, oob []byte, to net.Addr, flags int) (int, error) {
	var unixTo unix.Sockaddr
	if to != nil {
		unixTo = addrToSockaddr(to)
	}
	return unix.SendmsgBuffers(int(s), buffers, oob, unixTo, flags)
}

// addrToSockaddr converts a net.Addr to a unix.Sockaddr.
func addrToSockaddr(a net.Addr) unix.Sockaddr {
	var (
		ip   net.IP
		port int
		zone string
	)
	switch a := a.(type) {
	case *net.TCPAddr:
		ip = a.IP
		port = a.Port
		zone = a.Zone
	case *net.UDPAddr:
		ip = a.IP
		port = a.Port
		zone = a.Zone
	case *net.IPAddr:
		ip = a.IP
		zone = a.Zone
	default:
		return nil
	}

	if ip4 := ip.To4(); ip4 != nil {
		sa := unix.SockaddrInet4{Port: port}
		copy(sa.Addr[:], ip4)
		return &sa
	}

	if ip6 := ip.To16(); ip6 != nil && ip.To4() == nil {
		sa := unix.SockaddrInet6{Port: port}
		copy(sa.Addr[:], ip6)
		if zone != "" {
			sa.ZoneId = uint32(zoneCache.index(zone))
		}
		return &sa
	}

	return nil
}

// sockaddrToAddr converts a unix.Sockaddr to a net.Addr.
func sockaddrToAddr(sa unix.Sockaddr, network string) net.Addr {
	var (
		ip   net.IP
		port int
		zone string
	)
	switch sa := sa.(type) {
	case *unix.SockaddrInet4:
		ip = make(net.IP, net.IPv4len)
		copy(ip, sa.Addr[:])
		port = sa.Port
	case *unix.SockaddrInet6:
		ip = make(net.IP, net.IPv6len)
		copy(ip, sa.Addr[:])
		port = sa.Port
		if sa.ZoneId > 0 {
			zone = zoneCache.name(int(sa.ZoneId))
		}
	default:
		return nil
	}

	switch network {
	case "tcp", "tcp4", "tcp6":
		return &net.TCPAddr{IP: ip, Port: port, Zone: zone}
	case "udp", "udp4", "udp6":
		return &net.UDPAddr{IP: ip, Port: port, Zone: zone}
	default:
		return &net.IPAddr{IP: ip, Zone: zone}
	}
}
