// Copyright 2018 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 (
	"bytes"
	"runtime"
	"testing"
	"time"
)

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

	t.Run("TCP", func(t *testing.T) {
		handler := func(ls *localServer, ln Listener) {
			c, err := ln.Accept()
			if err != nil {
				t.Error(err)
				return
			}
			defer c.Close()

			cc, err := ln.(*TCPListener).SyscallConn()
			if err != nil {
				t.Fatal(err)
			}
			called := false
			op := func(uintptr) bool {
				called = true
				return true
			}
			err = cc.Write(op)
			if err == nil {
				t.Error("Write should return an error")
			}
			if called {
				t.Error("Write shouldn't call op")
			}
			called = false
			err = cc.Read(op)
			if err == nil {
				t.Error("Read should return an error")
			}
			if called {
				t.Error("Read shouldn't call op")
			}

			var b [32]byte
			n, err := c.Read(b[:])
			if err != nil {
				t.Error(err)
				return
			}
			if _, err := c.Write(b[:n]); err != nil {
				t.Error(err)
				return
			}
		}
		ls, err := newLocalServer("tcp")
		if err != nil {
			t.Fatal(err)
		}
		defer ls.teardown()
		if err := ls.buildup(handler); err != nil {
			t.Fatal(err)
		}

		c, err := Dial(ls.Listener.Addr().Network(), ls.Listener.Addr().String())
		if err != nil {
			t.Fatal(err)
		}
		defer c.Close()

		cc, err := c.(*TCPConn).SyscallConn()
		if err != nil {
			t.Fatal(err)
		}
		data := []byte("HELLO-R-U-THERE")
		if err := writeRawConn(cc, data); err != nil {
			t.Fatal(err)
		}
		var b [32]byte
		n, err := readRawConn(cc, b[:])
		if err != nil {
			t.Fatal(err)
		}
		if bytes.Compare(b[:n], data) != 0 {
			t.Fatalf("got %q; want %q", b[:n], data)
		}
	})
	t.Run("Deadline", func(t *testing.T) {
		switch runtime.GOOS {
		case "windows":
			t.Skipf("not supported on %s", runtime.GOOS)
		}

		ln, err := newLocalListener("tcp")
		if err != nil {
			t.Fatal(err)
		}
		defer ln.Close()

		c, err := Dial(ln.Addr().Network(), ln.Addr().String())
		if err != nil {
			t.Fatal(err)
		}
		defer c.Close()

		cc, err := c.(*TCPConn).SyscallConn()
		if err != nil {
			t.Fatal(err)
		}
		var b [1]byte

		c.SetDeadline(noDeadline)
		if err := c.SetDeadline(time.Now().Add(-1)); err != nil {
			t.Fatal(err)
		}
		if err = writeRawConn(cc, b[:]); err == nil {
			t.Fatal("Write should fail")
		}
		if perr := parseWriteError(err); perr != nil {
			t.Error(perr)
		}
		if nerr, ok := err.(Error); !ok || !nerr.Timeout() {
			t.Errorf("got %v; want timeout", err)
		}
		if _, err = readRawConn(cc, b[:]); err == nil {
			t.Fatal("Read should fail")
		}
		if perr := parseReadError(err); perr != nil {
			t.Error(perr)
		}
		if nerr, ok := err.(Error); !ok || !nerr.Timeout() {
			t.Errorf("got %v; want timeout", err)
		}

		c.SetReadDeadline(noDeadline)
		if err := c.SetReadDeadline(time.Now().Add(-1)); err != nil {
			t.Fatal(err)
		}
		if _, err = readRawConn(cc, b[:]); err == nil {
			t.Fatal("Read should fail")
		}
		if perr := parseReadError(err); perr != nil {
			t.Error(perr)
		}
		if nerr, ok := err.(Error); !ok || !nerr.Timeout() {
			t.Errorf("got %v; want timeout", err)
		}

		c.SetWriteDeadline(noDeadline)
		if err := c.SetWriteDeadline(time.Now().Add(-1)); err != nil {
			t.Fatal(err)
		}
		if err = writeRawConn(cc, b[:]); err == nil {
			t.Fatal("Write should fail")
		}
		if perr := parseWriteError(err); perr != nil {
			t.Error(perr)
		}
		if nerr, ok := err.(Error); !ok || !nerr.Timeout() {
			t.Errorf("got %v; want timeout", err)
		}
	})
}

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

	t.Run("TCP", func(t *testing.T) {
		ln, err := newLocalListener("tcp")
		if err != nil {
			t.Fatal(err)
		}
		defer ln.Close()

		cc1, err := ln.(*TCPListener).SyscallConn()
		if err != nil {
			t.Fatal(err)
		}
		if err := controlRawConn(cc1, ln.Addr()); err != nil {
			t.Fatal(err)
		}

		c, err := Dial(ln.Addr().Network(), ln.Addr().String())
		if err != nil {
			t.Fatal(err)
		}
		defer c.Close()

		cc2, err := c.(*TCPConn).SyscallConn()
		if err != nil {
			t.Fatal(err)
		}
		if err := controlRawConn(cc2, c.LocalAddr()); err != nil {
			t.Fatal(err)
		}

		ln.Close()
		if err := controlRawConn(cc1, ln.Addr()); err == nil {
			t.Fatal("Control after Close should fail")
		}
		c.Close()
		if err := controlRawConn(cc2, c.LocalAddr()); err == nil {
			t.Fatal("Control after Close should fail")
		}
	})
}
