// Copyright 2015 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 (
	"internal/testenv"
	"os"
	"os/exec"
	"runtime"
	"strconv"
	"strings"
	"testing"
)

var unixEnabledOnAIX bool

func init() {
	if runtime.GOOS == "aix" {
		// Unix network isn't properly working on AIX 7.2 with
		// Technical Level < 2.
		// The information is retrieved only once in this init()
		// instead of everytime testableNetwork is called.
		out, _ := exec.Command("oslevel", "-s").Output()
		if len(out) >= len("7200-XX-ZZ-YYMM") { // AIX 7.2, Tech Level XX, Service Pack ZZ, date YYMM
			aixVer := string(out[:4])
			tl, _ := strconv.Atoi(string(out[5:7]))
			unixEnabledOnAIX = aixVer > "7200" || (aixVer == "7200" && tl >= 2)
		}
	}
}

// testableNetwork reports whether network is testable on the current
// platform configuration.
func testableNetwork(network string) bool {
	net, _, _ := strings.Cut(network, ":")
	switch net {
	case "ip+nopriv":
	case "ip", "ip4", "ip6":
		switch runtime.GOOS {
		case "plan9":
			return false
		default:
			if os.Getuid() != 0 {
				return false
			}
		}
	case "unix", "unixgram":
		switch runtime.GOOS {
		case "android", "ios", "plan9", "windows":
			return false
		case "aix":
			return unixEnabledOnAIX
		}
	case "unixpacket":
		switch runtime.GOOS {
		case "aix", "android", "darwin", "ios", "plan9", "windows":
			return false
		}
	}
	switch net {
	case "tcp4", "udp4", "ip4":
		if !supportsIPv4() {
			return false
		}
	case "tcp6", "udp6", "ip6":
		if !supportsIPv6() {
			return false
		}
	}
	return true
}

// testableAddress reports whether address of network is testable on
// the current platform configuration.
func testableAddress(network, address string) bool {
	switch net, _, _ := strings.Cut(network, ":"); net {
	case "unix", "unixgram", "unixpacket":
		// Abstract unix domain sockets, a Linux-ism.
		if address[0] == '@' && runtime.GOOS != "linux" {
			return false
		}
	}
	return true
}

// testableListenArgs reports whether arguments are testable on the
// current platform configuration.
func testableListenArgs(network, address, client string) bool {
	if !testableNetwork(network) || !testableAddress(network, address) {
		return false
	}

	var err error
	var addr Addr
	switch net, _, _ := strings.Cut(network, ":"); net {
	case "tcp", "tcp4", "tcp6":
		addr, err = ResolveTCPAddr("tcp", address)
	case "udp", "udp4", "udp6":
		addr, err = ResolveUDPAddr("udp", address)
	case "ip", "ip4", "ip6":
		addr, err = ResolveIPAddr("ip", address)
	default:
		return true
	}
	if err != nil {
		return false
	}
	var ip IP
	var wildcard bool
	switch addr := addr.(type) {
	case *TCPAddr:
		ip = addr.IP
		wildcard = addr.isWildcard()
	case *UDPAddr:
		ip = addr.IP
		wildcard = addr.isWildcard()
	case *IPAddr:
		ip = addr.IP
		wildcard = addr.isWildcard()
	}

	// Test wildcard IP addresses.
	if wildcard && !testenv.HasExternalNetwork() {
		return false
	}

	// Test functionality of IPv4 communication using AF_INET and
	// IPv6 communication using AF_INET6 sockets.
	if !supportsIPv4() && ip.To4() != nil {
		return false
	}
	if !supportsIPv6() && ip.To16() != nil && ip.To4() == nil {
		return false
	}
	cip := ParseIP(client)
	if cip != nil {
		if !supportsIPv4() && cip.To4() != nil {
			return false
		}
		if !supportsIPv6() && cip.To16() != nil && cip.To4() == nil {
			return false
		}
	}

	// Test functionality of IPv4 communication using AF_INET6
	// sockets.
	if !supportsIPv4map() && supportsIPv4() && (network == "tcp" || network == "udp" || network == "ip") && wildcard {
		// At this point, we prefer IPv4 when ip is nil.
		// See favoriteAddrFamily for further information.
		if ip.To16() != nil && ip.To4() == nil && cip.To4() != nil { // a pair of IPv6 server and IPv4 client
			return false
		}
		if (ip.To4() != nil || ip == nil) && cip.To16() != nil && cip.To4() == nil { // a pair of IPv4 server and IPv6 client
			return false
		}
	}

	return true
}

func condFatalf(t *testing.T, network string, format string, args ...any) {
	t.Helper()
	// A few APIs like File and Read/WriteMsg{UDP,IP} are not
	// fully implemented yet on Plan 9 and Windows.
	switch runtime.GOOS {
	case "windows", "js", "wasip1":
		if network == "file+net" {
			t.Logf(format, args...)
			return
		}
	case "plan9":
		t.Logf(format, args...)
		return
	}
	t.Fatalf(format, args...)
}
