// Copyright 2011 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 !js

package net

import (
	"os"
	"reflect"
	"runtime"
	"sync"
	"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

var fileConnTests = []struct {
	network string
}{
	{"tcp"},
	{"udp"},
	{"unix"},
	{"unixpacket"},
}

func TestFileConn(t *testing.T) {
	switch runtime.GOOS {
	case "plan9", "windows":
		t.Skipf("not supported on %s", runtime.GOOS)
	}

	for _, tt := range fileConnTests {
		if !testableNetwork(tt.network) {
			t.Logf("skipping %s test", tt.network)
			continue
		}

		var network, address string
		switch tt.network {
		case "udp":
			c, err := newLocalPacketListener(tt.network)
			if err != nil {
				t.Fatal(err)
			}
			defer c.Close()
			network = c.LocalAddr().Network()
			address = c.LocalAddr().String()
		default:
			handler := func(ls *localServer, ln Listener) {
				c, err := ln.Accept()
				if err != nil {
					return
				}
				defer c.Close()
				var b [1]byte
				c.Read(b[:])
			}
			ls, err := newLocalServer(tt.network)
			if err != nil {
				t.Fatal(err)
			}
			defer ls.teardown()
			if err := ls.buildup(handler); err != nil {
				t.Fatal(err)
			}
			network = ls.Listener.Addr().Network()
			address = ls.Listener.Addr().String()
		}

		c1, err := Dial(network, address)
		if err != nil {
			if perr := parseDialError(err); perr != nil {
				t.Error(perr)
			}
			t.Fatal(err)
		}
		addr := c1.LocalAddr()

		var f *os.File
		switch c1 := c1.(type) {
		case *TCPConn:
			f, err = c1.File()
		case *UDPConn:
			f, err = c1.File()
		case *UnixConn:
			f, err = c1.File()
		}
		if err := c1.Close(); err != nil {
			if perr := parseCloseError(err, false); perr != nil {
				t.Error(perr)
			}
			t.Error(err)
		}
		if err != nil {
			if perr := parseCommonError(err); perr != nil {
				t.Error(perr)
			}
			t.Fatal(err)
		}

		c2, err := FileConn(f)
		if err := f.Close(); err != nil {
			t.Error(err)
		}
		if err != nil {
			if perr := parseCommonError(err); perr != nil {
				t.Error(perr)
			}
			t.Fatal(err)
		}
		defer c2.Close()

		if _, err := c2.Write([]byte("FILECONN TEST")); err != nil {
			if perr := parseWriteError(err); perr != nil {
				t.Error(perr)
			}
			t.Fatal(err)
		}
		if !reflect.DeepEqual(c2.LocalAddr(), addr) {
			t.Fatalf("got %#v; want %#v", c2.LocalAddr(), addr)
		}
	}
}

var fileListenerTests = []struct {
	network string
}{
	{"tcp"},
	{"unix"},
	{"unixpacket"},
}

func TestFileListener(t *testing.T) {
	switch runtime.GOOS {
	case "plan9", "windows":
		t.Skipf("not supported on %s", runtime.GOOS)
	}

	for _, tt := range fileListenerTests {
		if !testableNetwork(tt.network) {
			t.Logf("skipping %s test", tt.network)
			continue
		}

		ln1, err := newLocalListener(tt.network)
		if err != nil {
			t.Fatal(err)
		}
		switch tt.network {
		case "unix", "unixpacket":
			defer os.Remove(ln1.Addr().String())
		}
		addr := ln1.Addr()

		var f *os.File
		switch ln1 := ln1.(type) {
		case *TCPListener:
			f, err = ln1.File()
		case *UnixListener:
			f, err = ln1.File()
		}
		switch tt.network {
		case "unix", "unixpacket":
			defer ln1.Close() // UnixListener.Close calls syscall.Unlink internally
		default:
			if err := ln1.Close(); err != nil {
				t.Error(err)
			}
		}
		if err != nil {
			if perr := parseCommonError(err); perr != nil {
				t.Error(perr)
			}
			t.Fatal(err)
		}

		ln2, err := FileListener(f)
		if err := f.Close(); err != nil {
			t.Error(err)
		}
		if err != nil {
			if perr := parseCommonError(err); perr != nil {
				t.Error(perr)
			}
			t.Fatal(err)
		}
		defer ln2.Close()

		var wg sync.WaitGroup
		wg.Add(1)
		go func() {
			defer wg.Done()
			c, err := Dial(ln2.Addr().Network(), ln2.Addr().String())
			if err != nil {
				if perr := parseDialError(err); perr != nil {
					t.Error(perr)
				}
				t.Error(err)
				return
			}
			c.Close()
		}()
		c, err := ln2.Accept()
		if err != nil {
			if perr := parseAcceptError(err); perr != nil {
				t.Error(perr)
			}
			t.Fatal(err)
		}
		c.Close()
		wg.Wait()
		if !reflect.DeepEqual(ln2.Addr(), addr) {
			t.Fatalf("got %#v; want %#v", ln2.Addr(), addr)
		}
	}
}

var filePacketConnTests = []struct {
	network string
}{
	{"udp"},
	{"unixgram"},
}

func TestFilePacketConn(t *testing.T) {
	switch runtime.GOOS {
	case "plan9", "windows":
		t.Skipf("not supported on %s", runtime.GOOS)
	}

	for _, tt := range filePacketConnTests {
		if !testableNetwork(tt.network) {
			t.Logf("skipping %s test", tt.network)
			continue
		}

		c1, err := newLocalPacketListener(tt.network)
		if err != nil {
			t.Fatal(err)
		}
		switch tt.network {
		case "unixgram":
			defer os.Remove(c1.LocalAddr().String())
		}
		addr := c1.LocalAddr()

		var f *os.File
		switch c1 := c1.(type) {
		case *UDPConn:
			f, err = c1.File()
		case *UnixConn:
			f, err = c1.File()
		}
		if err := c1.Close(); err != nil {
			if perr := parseCloseError(err, false); perr != nil {
				t.Error(perr)
			}
			t.Error(err)
		}
		if err != nil {
			if perr := parseCommonError(err); perr != nil {
				t.Error(perr)
			}
			t.Fatal(err)
		}

		c2, err := FilePacketConn(f)
		if err := f.Close(); err != nil {
			t.Error(err)
		}
		if err != nil {
			if perr := parseCommonError(err); perr != nil {
				t.Error(perr)
			}
			t.Fatal(err)
		}
		defer c2.Close()

		if _, err := c2.WriteTo([]byte("FILEPACKETCONN TEST"), addr); err != nil {
			if perr := parseWriteError(err); perr != nil {
				t.Error(perr)
			}
			t.Fatal(err)
		}
		if !reflect.DeepEqual(c2.LocalAddr(), addr) {
			t.Fatalf("got %#v; want %#v", c2.LocalAddr(), addr)
		}
	}
}

// Issue 24483.
func TestFileCloseRace(t *testing.T) {
	switch runtime.GOOS {
	case "plan9", "windows":
		t.Skipf("not supported on %s", runtime.GOOS)
	}
	if !testableNetwork("tcp") {
		t.Skip("tcp not supported")
	}

	handler := func(ls *localServer, ln Listener) {
		c, err := ln.Accept()
		if err != nil {
			return
		}
		defer c.Close()
		var b [1]byte
		c.Read(b[:])
	}

	ls, err := newLocalServer("tcp")
	if err != nil {
		t.Fatal(err)
	}
	defer ls.teardown()
	if err := ls.buildup(handler); err != nil {
		t.Fatal(err)
	}

	const tries = 100
	for i := 0; i < tries; i++ {
		c1, err := Dial(ls.Listener.Addr().Network(), ls.Listener.Addr().String())
		if err != nil {
			t.Fatal(err)
		}
		tc := c1.(*TCPConn)

		var wg sync.WaitGroup
		wg.Add(2)
		go func() {
			defer wg.Done()
			f, err := tc.File()
			if err == nil {
				f.Close()
			}
		}()
		go func() {
			defer wg.Done()
			c1.Close()
		}()
		wg.Wait()
	}
}
