// Copyright 2009 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 (
	"reflect"
	"testing"
)

// The full stack test cases for IPConn have been moved to the
// following:
//	golang.org/x/net/ipv4
//	golang.org/x/net/ipv6
//	golang.org/x/net/icmp

type resolveIPAddrTest struct {
	network       string
	litAddrOrName string
	addr          *IPAddr
	err           error
}

var resolveIPAddrTests = []resolveIPAddrTest{
	{"ip", "127.0.0.1", &IPAddr{IP: IPv4(127, 0, 0, 1)}, nil},
	{"ip4", "127.0.0.1", &IPAddr{IP: IPv4(127, 0, 0, 1)}, nil},
	{"ip4:icmp", "127.0.0.1", &IPAddr{IP: IPv4(127, 0, 0, 1)}, nil},

	{"ip", "::1", &IPAddr{IP: ParseIP("::1")}, nil},
	{"ip6", "::1", &IPAddr{IP: ParseIP("::1")}, nil},
	{"ip6:ipv6-icmp", "::1", &IPAddr{IP: ParseIP("::1")}, nil},
	{"ip6:IPv6-ICMP", "::1", &IPAddr{IP: ParseIP("::1")}, nil},

	{"ip", "::1%en0", &IPAddr{IP: ParseIP("::1"), Zone: "en0"}, nil},
	{"ip6", "::1%911", &IPAddr{IP: ParseIP("::1"), Zone: "911"}, nil},

	{"", "127.0.0.1", &IPAddr{IP: IPv4(127, 0, 0, 1)}, nil}, // Go 1.0 behavior
	{"", "::1", &IPAddr{IP: ParseIP("::1")}, nil},           // Go 1.0 behavior

	{"l2tp", "127.0.0.1", nil, UnknownNetworkError("l2tp")},
	{"l2tp:gre", "127.0.0.1", nil, UnknownNetworkError("l2tp:gre")},
	{"tcp", "1.2.3.4:123", nil, UnknownNetworkError("tcp")},
}

func TestResolveIPAddr(t *testing.T) {
	if !testableNetwork("ip+nopriv") {
		t.Skip("ip+nopriv test")
	}

	origTestHookLookupIP := testHookLookupIP
	defer func() { testHookLookupIP = origTestHookLookupIP }()
	testHookLookupIP = lookupLocalhost

	for i, tt := range resolveIPAddrTests {
		addr, err := ResolveIPAddr(tt.network, tt.litAddrOrName)
		if err != tt.err {
			t.Errorf("#%d: %v", i, err)
		} else if !reflect.DeepEqual(addr, tt.addr) {
			t.Errorf("#%d: got %#v; want %#v", i, addr, tt.addr)
		}
		if err != nil {
			continue
		}
		rtaddr, err := ResolveIPAddr(addr.Network(), addr.String())
		if err != nil {
			t.Errorf("#%d: %v", i, err)
		} else if !reflect.DeepEqual(rtaddr, addr) {
			t.Errorf("#%d: got %#v; want %#v", i, rtaddr, addr)
		}
	}
}

var ipConnLocalNameTests = []struct {
	net   string
	laddr *IPAddr
}{
	{"ip4:icmp", &IPAddr{IP: IPv4(127, 0, 0, 1)}},
	{"ip4:icmp", &IPAddr{}},
	{"ip4:icmp", nil},
}

func TestIPConnLocalName(t *testing.T) {
	for _, tt := range ipConnLocalNameTests {
		if !testableNetwork(tt.net) {
			t.Logf("skipping %s test", tt.net)
			continue
		}
		c, err := ListenIP(tt.net, tt.laddr)
		if err != nil {
			t.Fatalf("ListenIP failed: %v", err)
		}
		defer c.Close()
		if la := c.LocalAddr(); la == nil {
			t.Fatal("IPConn.LocalAddr failed")
		}
	}
}

func TestIPConnRemoteName(t *testing.T) {
	if !testableNetwork("ip:tcp") {
		t.Skip("ip:tcp test")
	}

	raddr := &IPAddr{IP: IPv4(127, 0, 0, 1).To4()}
	c, err := DialIP("ip:tcp", &IPAddr{IP: IPv4(127, 0, 0, 1)}, raddr)
	if err != nil {
		t.Fatalf("DialIP failed: %v", err)
	}
	defer c.Close()
	if !reflect.DeepEqual(raddr, c.RemoteAddr()) {
		t.Fatalf("got %#v, expected %#v", c.RemoteAddr(), raddr)
	}
}
