// Copyright 2016 The Netstack 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 queue

import (
	"encoding/binary"
	"reflect"
	"testing"

	"github.com/google/netstack/tcpip/link/sharedmem/pipe"
)

func TestBasicTxQueue(t *testing.T) {
	// Tests that a basic transmit on a queue works, and that completion
	// gets properly reported as well.
	pb1 := make([]byte, 100)
	pb2 := make([]byte, 100)

	var rxp pipe.Rx
	rxp.Init(pb1)

	var txp pipe.Tx
	txp.Init(pb2)

	var q Tx
	q.Init(pb1, pb2)

	// Enqueue two buffers.
	b := []TxBuffer{
		{nil, 100, 60},
		{nil, 200, 40},
	}

	b[0].Next = &b[1]

	const usedID = 1002
	const usedTotalSize = 100
	if !q.Enqueue(usedID, usedTotalSize, 2, &b[0]) {
		t.Fatalf("Enqueue failed on empty queue")
	}

	// Check the contents of the pipe.
	d := rxp.Pull()
	if d == nil {
		t.Fatalf("Tx pipe is empty after Enqueue")
	}

	want := []byte{
		234, 3, 0, 0, 0, 0, 0, 0, // id
		100, 0, 0, 0, // total size
		0, 0, 0, 0, // reserved
		100, 0, 0, 0, 0, 0, 0, 0, // offset 1
		60, 0, 0, 0, // size 1
		200, 0, 0, 0, 0, 0, 0, 0, // offset 2
		40, 0, 0, 0, // size 2
	}

	if !reflect.DeepEqual(want, d) {
		t.Fatalf("Bad posted packet: got %v, want %v", d, want)
	}

	rxp.Flush()

	// Check that there are no completions yet.
	if _, ok := q.CompletedPacket(); ok {
		t.Fatalf("Packet reported as completed too soon")
	}

	// Post a completion.
	d = txp.Push(8)
	if d == nil {
		t.Fatalf("Unable to push to rx pipe")
	}
	binary.LittleEndian.PutUint64(d, usedID)
	txp.Flush()

	// Check that completion is properly reported.
	id, ok := q.CompletedPacket()
	if !ok {
		t.Fatalf("Completion not reported")
	}

	if id != usedID {
		t.Fatalf("Bad completion id: got %v, want %v", id, usedID)
	}
}

func TestBasicRxQueue(t *testing.T) {
	// Tests that a basic receive on a queue works.
	pb1 := make([]byte, 100)
	pb2 := make([]byte, 100)

	var rxp pipe.Rx
	rxp.Init(pb1)

	var txp pipe.Tx
	txp.Init(pb2)

	var q Rx
	q.Init(pb1, pb2, nil)

	// Post two buffers.
	b := []RxBuffer{
		{100, 60, 1077, 0},
		{200, 40, 2123, 0},
	}

	if !q.PostBuffers(b) {
		t.Fatalf("PostBuffers failed on empty queue")
	}

	// Check the contents of the pipe.
	want := [][]byte{
		{
			100, 0, 0, 0, 0, 0, 0, 0, // Offset1
			60, 0, 0, 0, // Size1
			0, 0, 0, 0, // Remaining in group 1
			0, 0, 0, 0, 0, 0, 0, 0, // User data 1
			53, 4, 0, 0, 0, 0, 0, 0, // ID 1
		},
		{
			200, 0, 0, 0, 0, 0, 0, 0, // Offset2
			40, 0, 0, 0, // Size2
			0, 0, 0, 0, // Remaining in group 2
			0, 0, 0, 0, 0, 0, 0, 0, // User data 2
			75, 8, 0, 0, 0, 0, 0, 0, // ID 2
		},
	}

	for i := range b {
		d := rxp.Pull()
		if d == nil {
			t.Fatalf("Tx pipe is empty after PostBuffers")
		}

		if !reflect.DeepEqual(want[i], d) {
			t.Fatalf("Bad posted packet: got %v, want %v", d, want[i])
		}

		rxp.Flush()
	}

	// Check that there are no completions.
	if _, n := q.Dequeue(nil); n != 0 {
		t.Fatalf("Packet reported as received too soon")
	}

	// Post a completion.
	d := txp.Push(sizeOfConsumedPacketHeader + 2*sizeOfConsumedBuffer)
	if d == nil {
		t.Fatalf("Unable to push to rx pipe")
	}

	copy(d, []byte{
		100, 0, 0, 0, // packet size
		0, 0, 0, 0, // reserved

		100, 0, 0, 0, 0, 0, 0, 0, // offset 1
		60, 0, 0, 0, // size 1
		0, 0, 0, 0, 0, 0, 0, 0, // user data 1
		53, 4, 0, 0, 0, 0, 0, 0, // ID 1

		200, 0, 0, 0, 0, 0, 0, 0, // offset 2
		40, 0, 0, 0, // size 2
		0, 0, 0, 0, 0, 0, 0, 0, // user data 2
		75, 8, 0, 0, 0, 0, 0, 0, // ID 2
	})

	txp.Flush()

	// Check that completion is properly reported.
	bufs, n := q.Dequeue(nil)
	if n != 100 {
		t.Fatalf("Bad packet size: got %v, want %v", n, 100)
	}

	if !reflect.DeepEqual(bufs, b) {
		t.Fatalf("Bad returned buffers: got %v, want %v", bufs, b)
	}
}

func TestBadTxCompletion(t *testing.T) {
	// Check that tx completions with bad sizes are properly ignored.
	pb1 := make([]byte, 100)
	pb2 := make([]byte, 100)

	var rxp pipe.Rx
	rxp.Init(pb1)

	var txp pipe.Tx
	txp.Init(pb2)

	var q Tx
	q.Init(pb1, pb2)

	// Post a completion that is too short, and check that it is ignored.
	if d := txp.Push(7); d == nil {
		t.Fatalf("Unable to push to rx pipe")
	}
	txp.Flush()

	if _, ok := q.CompletedPacket(); ok {
		t.Fatalf("Bad completion not ignored")
	}

	// Post a completion that is too long, and check that it is ignored.
	if d := txp.Push(10); d == nil {
		t.Fatalf("Unable to push to rx pipe")
	}
	txp.Flush()

	if _, ok := q.CompletedPacket(); ok {
		t.Fatalf("Bad completion not ignored")
	}
}

func TestBadRxCompletion(t *testing.T) {
	// Check that bad rx completions are properly ignored.
	pb1 := make([]byte, 100)
	pb2 := make([]byte, 100)

	var rxp pipe.Rx
	rxp.Init(pb1)

	var txp pipe.Tx
	txp.Init(pb2)

	var q Rx
	q.Init(pb1, pb2, nil)

	// Post a completion that is too short, and check that it is ignored.
	if d := txp.Push(7); d == nil {
		t.Fatalf("Unable to push to rx pipe")
	}
	txp.Flush()

	if b, _ := q.Dequeue(nil); b != nil {
		t.Fatalf("Bad completion not ignored")
	}

	// Post a completion whose buffer sizes add up to less than the total
	// size.
	d := txp.Push(sizeOfConsumedPacketHeader + 2*sizeOfConsumedBuffer)
	if d == nil {
		t.Fatalf("Unable to push to rx pipe")
	}

	copy(d, []byte{
		100, 0, 0, 0, // packet size
		0, 0, 0, 0, // reserved

		100, 0, 0, 0, 0, 0, 0, 0, // offset 1
		10, 0, 0, 0, // size 1
		0, 0, 0, 0, 0, 0, 0, 0, // user data 1
		53, 4, 0, 0, 0, 0, 0, 0, // ID 1

		200, 0, 0, 0, 0, 0, 0, 0, // offset 2
		10, 0, 0, 0, // size 2
		0, 0, 0, 0, 0, 0, 0, 0, // user data 2
		75, 8, 0, 0, 0, 0, 0, 0, // ID 2
	})

	txp.Flush()
	if b, _ := q.Dequeue(nil); b != nil {
		t.Fatalf("Bad completion not ignored")
	}

	// Post a completion whose buffer sizes will cause a 32-bit overflow,
	// but adds up to the right number.
	d = txp.Push(sizeOfConsumedPacketHeader + 2*sizeOfConsumedBuffer)
	if d == nil {
		t.Fatalf("Unable to push to rx pipe")
	}

	copy(d, []byte{
		100, 0, 0, 0, // packet size
		0, 0, 0, 0, // reserved

		100, 0, 0, 0, 0, 0, 0, 0, // offset 1
		255, 255, 255, 255, // size 1
		0, 0, 0, 0, 0, 0, 0, 0, // user data 1
		53, 4, 0, 0, 0, 0, 0, 0, // ID 1

		200, 0, 0, 0, 0, 0, 0, 0, // offset 2
		101, 0, 0, 0, // size 2
		0, 0, 0, 0, 0, 0, 0, 0, // user data 2
		75, 8, 0, 0, 0, 0, 0, 0, // ID 2
	})

	txp.Flush()
	if b, _ := q.Dequeue(nil); b != nil {
		t.Fatalf("Bad completion not ignored")
	}
}

func TestFillTxPipe(t *testing.T) {
	// Check that transmitting a new buffer when the buffer pipe is full
	// fails gracefully.
	pb1 := make([]byte, 104)
	pb2 := make([]byte, 104)

	var rxp pipe.Rx
	rxp.Init(pb1)

	var txp pipe.Tx
	txp.Init(pb2)

	var q Tx
	q.Init(pb1, pb2)

	// Transmit twice, which should fill the tx pipe.
	b := []TxBuffer{
		{nil, 100, 60},
		{nil, 200, 40},
	}

	b[0].Next = &b[1]

	const usedID = 1002
	const usedTotalSize = 100
	for i := uint64(0); i < 2; i++ {
		if !q.Enqueue(usedID+i, usedTotalSize, 2, &b[0]) {
			t.Fatalf("Failed to transmit buffer")
		}
	}

	// Transmit another packet now that the tx pipe is full.
	if q.Enqueue(usedID+2, usedTotalSize, 2, &b[0]) {
		t.Fatalf("Enqueue succeeded when tx pipe is full")
	}
}

func TestFillRxPipe(t *testing.T) {
	// Check that posting a new buffer when the buffer pipe is full fails
	// gracefully.
	pb1 := make([]byte, 100)
	pb2 := make([]byte, 100)

	var rxp pipe.Rx
	rxp.Init(pb1)

	var txp pipe.Tx
	txp.Init(pb2)

	var q Rx
	q.Init(pb1, pb2, nil)

	// Post a buffer twice, it should fill the tx pipe.
	b := []RxBuffer{
		{100, 60, 1077, 0},
	}

	for i := 0; i < 2; i++ {
		if !q.PostBuffers(b) {
			t.Fatalf("PostBuffers failed on non-full queue")
		}
	}

	// Post another buffer now that the tx pipe is full.
	if q.PostBuffers(b) {
		t.Fatalf("PostBuffers succeeded on full queue")
	}
}

func TestLotsOfTransmissions(t *testing.T) {
	// Make sure pipes are being properly flushed when transmitting packets.
	pb1 := make([]byte, 100)
	pb2 := make([]byte, 100)

	var rxp pipe.Rx
	rxp.Init(pb1)

	var txp pipe.Tx
	txp.Init(pb2)

	var q Tx
	q.Init(pb1, pb2)

	// Prepare packet with two buffers.
	b := []TxBuffer{
		{nil, 100, 60},
		{nil, 200, 40},
	}

	b[0].Next = &b[1]

	const usedID = 1002
	const usedTotalSize = 100

	// Post 100000 packets and completions.
	for i := 100000; i > 0; i-- {
		if !q.Enqueue(usedID, usedTotalSize, 2, &b[0]) {
			t.Fatalf("Enqueue failed on non-full queue")
		}

		if d := rxp.Pull(); d == nil {
			t.Fatalf("Tx pipe is empty after Enqueue")
		}
		rxp.Flush()

		d := txp.Push(8)
		if d == nil {
			t.Fatalf("Unable to write to rx pipe")
		}
		binary.LittleEndian.PutUint64(d, usedID)
		txp.Flush()
		if _, ok := q.CompletedPacket(); !ok {
			t.Fatalf("Completion not returned")
		}
	}
}

func TestLotsOfReceptions(t *testing.T) {
	// Make sure pipes are being properly flushed when receiving packets.
	pb1 := make([]byte, 100)
	pb2 := make([]byte, 100)

	var rxp pipe.Rx
	rxp.Init(pb1)

	var txp pipe.Tx
	txp.Init(pb2)

	var q Rx
	q.Init(pb1, pb2, nil)

	// Prepare for posting two buffers.
	b := []RxBuffer{
		{100, 60, 1077, 0},
		{200, 40, 2123, 0},
	}

	// Post 100000 buffers and completions.
	for i := 100000; i > 0; i-- {
		if !q.PostBuffers(b) {
			t.Fatalf("PostBuffers failed on non-full queue")
		}

		if d := rxp.Pull(); d == nil {
			t.Fatalf("Tx pipe is empty after PostBuffers")
		}
		rxp.Flush()

		if d := rxp.Pull(); d == nil {
			t.Fatalf("Tx pipe is empty after PostBuffers")
		}
		rxp.Flush()

		d := txp.Push(sizeOfConsumedPacketHeader + 2*sizeOfConsumedBuffer)
		if d == nil {
			t.Fatalf("Unable to push to rx pipe")
		}

		copy(d, []byte{
			100, 0, 0, 0, // packet size
			0, 0, 0, 0, // reserved

			100, 0, 0, 0, 0, 0, 0, 0, // offset 1
			60, 0, 0, 0, // size 1
			0, 0, 0, 0, 0, 0, 0, 0, // user data 1
			53, 4, 0, 0, 0, 0, 0, 0, // ID 1

			200, 0, 0, 0, 0, 0, 0, 0, // offset 2
			40, 0, 0, 0, // size 2
			0, 0, 0, 0, 0, 0, 0, 0, // user data 2
			75, 8, 0, 0, 0, 0, 0, 0, // ID 2
		})

		txp.Flush()

		if _, n := q.Dequeue(nil); n == 0 {
			t.Fatalf("Dequeue failed when there is a completion")
		}
	}
}

func TestRxEnableNotification(t *testing.T) {
	// Check that enabling nofifications results in properly updated state.
	pb1 := make([]byte, 100)
	pb2 := make([]byte, 100)

	var state uint32
	var q Rx
	q.Init(pb1, pb2, &state)

	q.EnableNotification()
	if state != eventFDEnabled {
		t.Fatalf("Bad value in shared state: got %v, want %v", state, eventFDEnabled)
	}
}

func TestRxDisableNotification(t *testing.T) {
	// Check that disabling nofifications results in properly updated state.
	pb1 := make([]byte, 100)
	pb2 := make([]byte, 100)

	var state uint32
	var q Rx
	q.Init(pb1, pb2, &state)

	q.DisableNotification()
	if state != eventFDDisabled {
		t.Fatalf("Bad value in shared state: got %v, want %v", state, eventFDDisabled)
	}
}
