// 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.

//go: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 := newLocalServer(t, "tcp")
		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 := newLocalListener(t, "tcp")
		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 !isDeadlineExceeded(err) {
			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 !isDeadlineExceeded(err) {
			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 !isDeadlineExceeded(err) {
			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 !isDeadlineExceeded(err) {
			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 := newLocalListener(t, "tcp")
		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")
		}
	})
}
