// Copyright 2014 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 probe

import (
	"bufio"
	"io"
	"net"
	"os"
	"testing"
	"unsafe"

	"golang.org/x/debug/ogle/socket"
)

// traceThisFunction turns on tracing and returns a function to turn it off.
// It is intended for use as "defer traceThisFunction()()".
func traceThisFunction() func() {
	// TODO: This should be done atomically to guarantee the probe can see the update.
	tracing = true
	return func() {
		tracing = false
	}
}

type Conn struct {
	conn   net.Conn
	input  *bufio.Reader
	output *bufio.Writer
}

func (c *Conn) close() {
	c.output.Flush()
	c.conn.Close()
}

// newConn makes a connection.
func newConn(t *testing.T) *Conn {
	// defer traceThisFunction()()
	<-listening
	conn, err := socket.Dial(os.Getuid(), os.Getpid())
	if err != nil {
		t.Fatal(err)
	}
	return &Conn{
		conn:   conn,
		input:  bufio.NewReader(conn),
		output: bufio.NewWriter(conn),
	}
}

// bytesToUint64 returns the uint64 stored in the 8 bytes of buf.
func bytesToUint64(buf []byte) uint64 {
	// We're using same machine here, so byte order is the same.
	// We can just fetch it, but on some architectures it
	// must be aligned so copy first.
	var tmp [8]byte
	copy(tmp[:], buf)
	return *(*uint64)(unsafe.Pointer(&tmp[0]))
}

// Test that we get an error back for a request to read an illegal address.
func TestReadBadAddress(t *testing.T) {
	//defer traceThisFunction()()

	conn := newConn(t)
	defer conn.close()

	// Read the elements in pseudo-random order.
	var tmp [100]byte
	// Request a read of a bad address.
	conn.output.WriteByte('r')
	// Address.
	n := putUvarint(tmp[:], 0)
	conn.output.Write(tmp[:n])
	// Length. Any length will do.
	n = putUvarint(tmp[:], 8)
	conn.output.Write(tmp[:n])
	// Send it.
	err := conn.output.Flush()
	if err != nil {
		t.Fatal(err)
	}
	// Read result.
	// We expect an initial non-zero value, the number of bytes of the error message.
	u, err := readUvarint(conn.input)
	if err != nil {
		t.Fatal(err)
	}
	if u == 0 {
		t.Fatalf("expected error return; got none")
	}
	// We expect a particular error.
	const expect = "invalid read address"
	if u != uint64(len(expect)) {
		t.Fatalf("got %d bytes; expected %d", u, len(expect))
	}
	_, err = io.ReadFull(conn.input, tmp[:u])
	if err != nil {
		t.Fatal(err)
	}
	msg := string(tmp[:u])
	if msg != expect {
		t.Fatalf("got %q; expected %q", msg, expect)
	}
}

// Test that we can read some data from the address space on the other side of the connection.
func TestReadUint64(t *testing.T) {
	//defer traceThisFunction()()

	conn := newConn(t)
	defer conn.close()

	// Some data to send over the wire.
	data := make([]uint64, 10)
	for i := range data {
		data[i] = 0x1234567887654321 + 12345*uint64(i)
	}
	// TODO: To be righteous we should put a memory barrier here.

	// Read the elements in pseudo-random order.
	var tmp [100]byte
	which := 0
	for i := 0; i < 100; i++ {
		which = (which + 7) % len(data)
		// Request a read of data[which].
		conn.output.WriteByte('r')
		// Address.
		n := putUvarint(tmp[:], uint64(addr(&data[which])))
		conn.output.Write(tmp[:n])
		// Length
		n = putUvarint(tmp[:], 8)
		conn.output.Write(tmp[:n])
		// Send it.
		err := conn.output.Flush()
		if err != nil {
			t.Fatal(err)
		}
		// Read result.
		// We expect 10 bytes: the initial zero, followed by 8 (the count), followed by 8 bytes of data.
		u, err := readUvarint(conn.input)
		if err != nil {
			t.Fatal(err)
		}
		if u != 0 {
			t.Fatalf("expected leading zero byte; got %#x\n", u)
		}
		// N bytes of data.
		u, err = readUvarint(conn.input)
		if err != nil {
			t.Fatal(err)
		}
		if u != 8 {
			t.Fatalf("got %d bytes of data; expected 8", u)
		}
		_, err = io.ReadFull(conn.input, tmp[:u])
		if err != nil {
			t.Fatal(err)
		}
		u = bytesToUint64(tmp[:u])
		if u != data[which] {
			t.Fatalf("got %#x; expected %#x", u, data[which])
		}
	}
}

// Test that we can read an array bigger than the pipe's buffer size.
func TestBigRead(t *testing.T) {
	// defer traceThisFunction()()

	conn := newConn(t)
	defer conn.close()

	// A big slice.
	data := make([]byte, 3*len(pipe{}.buf))
	noise := 17
	for i := range data {
		data[i] = byte(noise)
		noise += 23
	}
	// TODO: To be righteous we should put a memory barrier here.

	// Read the elements in one big call.
	tmp := make([]byte, len(data))
	conn.output.WriteByte('r')
	// Address.
	n := putUvarint(tmp[:], uint64(addr(&data[0])))
	conn.output.Write(tmp[:n])
	// Length.
	n = putUvarint(tmp[:], uint64(len(data)))
	conn.output.Write(tmp[:n])
	// Send it.
	err := conn.output.Flush()
	if err != nil {
		t.Fatal(err)
	}
	// Read result.
	// We expect the full data back.
	u, err := readUvarint(conn.input)
	if err != nil {
		t.Fatal(err)
	}
	if u != 0 {
		t.Fatalf("expected leading zero byte; got %#x\n", u)
	}
	// N bytes of data.
	u, err = readUvarint(conn.input)
	if err != nil {
		t.Fatal(err)
	}
	if u != uint64(len(data)) {
		t.Fatalf("got %d bytes of data; expected 8", u)
	}
	_, err = io.ReadFull(conn.input, tmp)
	if err != nil {
		t.Fatal(err)
	}
	for i, c := range data {
		if tmp[i] != c {
			t.Fatalf("at offset %d expected %#x; got %#x", i, c, tmp[i])
		}
	}
}

// TestCollectGarbage doesn't actually test anything, but it does collect any
// garbage sockets that are no longer used. It is a courtesy for computers that
// run this test suite often.
func TestCollectGarbage(t *testing.T) {
	socket.CollectGarbage()
}
