// Copyright 2013 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 darwin dragonfly freebsd linux netbsd openbsd

package net

import (
	"fmt"
	"os"
	"os/exec"
	"runtime"
	"strings"
	"testing"
	"time"
)

type testInterface struct {
	name         string
	local        string
	remote       string
	setupCmds    []*exec.Cmd
	teardownCmds []*exec.Cmd
}

func (ti *testInterface) setup() error {
	for _, cmd := range ti.setupCmds {
		if out, err := cmd.CombinedOutput(); err != nil {
			return fmt.Errorf("args=%v out=%q err=%v", cmd.Args, string(out), err)
		}
	}
	return nil
}

func (ti *testInterface) teardown() error {
	for _, cmd := range ti.teardownCmds {
		if out, err := cmd.CombinedOutput(); err != nil {
			return fmt.Errorf("args=%v out=%q err=%v ", cmd.Args, string(out), err)
		}
	}
	return nil
}

func TestPointToPointInterface(t *testing.T) {
	if testing.Short() {
		t.Skip("avoid external network")
	}
	if runtime.GOOS == "darwin" || runtime.GOOS == "ios" {
		t.Skipf("not supported on %s", runtime.GOOS)
	}
	if os.Getuid() != 0 {
		t.Skip("must be root")
	}

	// We suppose that using IPv4 link-local addresses doesn't
	// harm anyone.
	local, remote := "169.254.0.1", "169.254.0.254"
	ip := ParseIP(remote)
	for i := 0; i < 3; i++ {
		ti := &testInterface{local: local, remote: remote}
		if err := ti.setPointToPoint(5963 + i); err != nil {
			t.Skipf("test requires external command: %v", err)
		}
		if err := ti.setup(); err != nil {
			if e := err.Error(); strings.Contains(e, "No such device") && strings.Contains(e, "gre0") {
				t.Skip("skipping test; no gre0 device. likely running in container?")
			}
			t.Fatal(err)
		} else {
			time.Sleep(3 * time.Millisecond)
		}
		ift, err := Interfaces()
		if err != nil {
			ti.teardown()
			t.Fatal(err)
		}
		for _, ifi := range ift {
			if ti.name != ifi.Name {
				continue
			}
			ifat, err := ifi.Addrs()
			if err != nil {
				ti.teardown()
				t.Fatal(err)
			}
			for _, ifa := range ifat {
				if ip.Equal(ifa.(*IPNet).IP) {
					ti.teardown()
					t.Fatalf("got %v", ifa)
				}
			}
		}
		if err := ti.teardown(); err != nil {
			t.Fatal(err)
		} else {
			time.Sleep(3 * time.Millisecond)
		}
	}
}

func TestInterfaceArrivalAndDeparture(t *testing.T) {
	if testing.Short() {
		t.Skip("avoid external network")
	}
	if os.Getuid() != 0 {
		t.Skip("must be root")
	}

	// We suppose that using IPv4 link-local addresses and the
	// dot1Q ID for Token Ring and FDDI doesn't harm anyone.
	local, remote := "169.254.0.1", "169.254.0.254"
	ip := ParseIP(remote)
	for _, vid := range []int{1002, 1003, 1004, 1005} {
		ift1, err := Interfaces()
		if err != nil {
			t.Fatal(err)
		}
		ti := &testInterface{local: local, remote: remote}
		if err := ti.setBroadcast(vid); err != nil {
			t.Skipf("test requires external command: %v", err)
		}
		if err := ti.setup(); err != nil {
			t.Fatal(err)
		} else {
			time.Sleep(3 * time.Millisecond)
		}
		ift2, err := Interfaces()
		if err != nil {
			ti.teardown()
			t.Fatal(err)
		}
		if len(ift2) <= len(ift1) {
			for _, ifi := range ift1 {
				t.Logf("before: %v", ifi)
			}
			for _, ifi := range ift2 {
				t.Logf("after: %v", ifi)
			}
			ti.teardown()
			t.Fatalf("got %v; want gt %v", len(ift2), len(ift1))
		}
		for _, ifi := range ift2 {
			if ti.name != ifi.Name {
				continue
			}
			ifat, err := ifi.Addrs()
			if err != nil {
				ti.teardown()
				t.Fatal(err)
			}
			for _, ifa := range ifat {
				if ip.Equal(ifa.(*IPNet).IP) {
					ti.teardown()
					t.Fatalf("got %v", ifa)
				}
			}
		}
		if err := ti.teardown(); err != nil {
			t.Fatal(err)
		} else {
			time.Sleep(3 * time.Millisecond)
		}
		ift3, err := Interfaces()
		if err != nil {
			t.Fatal(err)
		}
		if len(ift3) >= len(ift2) {
			for _, ifi := range ift2 {
				t.Logf("before: %v", ifi)
			}
			for _, ifi := range ift3 {
				t.Logf("after: %v", ifi)
			}
			t.Fatalf("got %v; want lt %v", len(ift3), len(ift2))
		}
	}
}

func TestInterfaceArrivalAndDepartureZoneCache(t *testing.T) {
	if testing.Short() {
		t.Skip("avoid external network")
	}
	if os.Getuid() != 0 {
		t.Skip("must be root")
	}

	// Ensure zoneCache is filled:
	_, _ = Listen("tcp", "[fe80::1%nonexistent]:0")

	ti := &testInterface{local: "fe80::1"}
	if err := ti.setLinkLocal(0); err != nil {
		t.Skipf("test requires external command: %v", err)
	}
	if err := ti.setup(); err != nil {
		t.Fatal(err)
	}
	defer ti.teardown()

	time.Sleep(3 * time.Millisecond)

	// If Listen fails (on Linux with “bind: invalid argument”), zoneCache was
	// not updated when encountering a nonexistent interface:
	ln, err := Listen("tcp", "[fe80::1%"+ti.name+"]:0")
	if err != nil {
		t.Fatal(err)
	}
	ln.Close()
	if err := ti.teardown(); err != nil {
		t.Fatal(err)
	}
}
