package plist

import (
	"testing"

	"github.com/emirpasic/gods/trees/avltree"

	"github.com/emirpasic/gods/utils"

	"github.com/Pallinder/go-randomdata"

	"github.com/emirpasic/gods/trees/binaryheap"
)

<<<<<<< HEAD
func TestPList(t *testing.T) {
	pl := &PriorityList{}
	for i := 0; i < 10; i++ {
		pl.nodeInsert(nil, randomdata.Number(0, 10))
	}
	t.Error(pl.String())

	cur := pl.head
	for i := 0; i < 5; i++ {
		cur = cur.next
	}
	pl.nodeInsert(cur, 11)

	t.Error(pl.String())
}

func TestPQ(t *testing.T) {

	pq := NewWithIntComparator()
	for i := 0; i < 1; i++ {
		pq.Push(i)
	}

	iter := pq.avl.Iterator()
	iter.Next()
	pl := iter.Value().(*PriorityList)
	t.Error(pq.size, pq.avl.Size(), pl.Size(), pl.head == nil, pl.head)
}

func BenchmarkPQ(b *testing.B) {
	pq := NewWithIntComparator()

	b.N = 1000000
	for i := b.N; i > 0; i-- {
		pq.Push(i)
=======
func TestPriorityQueueGet(t *testing.T) {
	p := NewWithInt()

	var l []int
	for i := 0; i < 10; i++ {
		l = append(l, randomdata.Number(0, 1000))
	}

	for _, v := range l {
		p.Push(v)
		t.Log(p.String())
	}

	t.Error(p.data.Values())

}

func TestPriorityQueuePush(t *testing.T) {
	p := NewWithInt()

	var l []int
	for i := 0; i < 20; i++ {
		l = append(l, randomdata.Number(0, 5))
	}

	for _, v := range l {
		p.Push(v)
		t.Log(p.String())
	}

	t.Error(l)
	t.Error(p.data.Values(), p.Head, p.Tail)

	cur := p.Head
	for cur != nil {
		t.Error(cur.Value)
		cur = cur.Prev()
	}

	t.Error("-----")

	cur = p.Tail
	for cur != nil {
		t.Error(cur.Value)
		cur = cur.Next()
	}
}

func TestPriorityQueueRemove(t *testing.T) {
	p := NewWithInt()

	for i := 0; i < 20; i++ {
		p.Push(randomdata.Number(0, 10))
>>>>>>> 86a8ee11986ed2002b8beb5420349f350594efd7
	}
	t.Error(p.Values())
	n, ok := p.GetNode(0)
	t.Error(n, ok, p.Head, p.Tail)

<<<<<<< HEAD
	iter := pq.avl.Iterator()
	iter.Next()

	pl := iter.Value().(*PriorityList)
	b.Log(pq.size, pq.avl.Size(), pl.Size(), pl.head)
	b.Log(pl.head.value)
	if pl.head.next != nil {
		b.Log(pl.head.next.value)
	}

	// b.Log("all:", pq.avl.Size(), pq.avl.Values())
}

func BenchmarkPList(b *testing.B) {

	for i := 0; i < b.N; i++ {
		pl := &PriorityList{}
		for i2 := 0; i2 < 5; i2++ {
			cur := pl.head
			for n := 0; n < i2; n++ {
				cur = cur.next
			}
			pl.nodeInsert(cur, i2)
		}
	}
}

func TestAvl(t *testing.T) {

	comparator := func(v1, v2 interface{}) int {
		if v1.(int) > v2.(int) {
			return 1
		} else if v1.(int) < v2.(int) {
			return -1
		}
		return 0
	}

	avl := avltree.NewWith(comparator)
	for _, v := range []int{9, 2, 3, 4, 5, 6, 8, 1} {
		avl.Put(v, v)
	}

	iter := avl.Iterator()
	iter.Next()
	t.Error(avl.Values(), iter.Value())

	f, ok := avl.Floor(10)
	if ok {
		t.Error("Floor", f)
	}

	f, ok = avl.Ceiling(10)
	if ok {
		t.Error("Ceiling", f)
	}
=======
	for i := 0; i < 20; i++ {
		t.Error(p.Remove(0), p.data.Size())
		t.Error(p.Values())
	}
}

func BenchmarkPriorityQueuePush(b *testing.B) {
	p := NewWithInt()

	b.N = 1000000
	for i := 0; i < b.N; i++ {
		p.Push(randomdata.Number(0, 100000))
	}
}

func BenchmarkPriorityQueueRemove(b *testing.B) {
	p := NewWithInt()

	for i := 0; i < 1000000; i++ {
		p.Push(randomdata.Number(0, 100000))
	}

	b.StartTimer()
	b.N = 1000000
	for i := 0; i < b.N-100; i++ {
		p.Remove(randomdata.Number(0, 100))
	}
	for p.Remove(0) != nil {

	}
}

func BenchmarkPriorityQueueGet(b *testing.B) {
	p := NewWithInt()

	for i := 0; i < 500000; i++ {
		p.Push(randomdata.Number(0, 100000))
		// p.Values()
	}

	b.ResetTimer()
	b.StartTimer()
	b.N = 100000
	for i := 0; i < b.N; i++ {
		p.Get(randomdata.Number(0, 1000))
	}
	b.StopTimer()

}

func TestAVL(t *testing.T) {
	avl := NewWithIntComparator()
	for i := 0; i < 100; i++ {
		v := randomdata.Number(0, 100)
		avl.Put(v)
	}

	t.Error(avl.size)
	t.Error(avl.Values())
	f, ok := avl.Ceiling(1000)
	t.Error(f, ok)
	if ok {
		t.Error(f.Next().Value)
	}

	f, ok = avl.Floor(-1)
	t.Error(f, ok)
	if ok {
		t.Error(f.Next().Value)
	}

	root := avl.Root
	for root != nil {
		root = root.Next()
	}

	root = avl.Root
	for root != nil {
		root = root.Prev()
	}
}

func BenchmarkAVL(b *testing.B) {
	avl := NewWithIntComparator()
	b.N = 1000000

	b.StartTimer()
	for i := 0; i < b.N; i++ {
		v := randomdata.Number(0, 100000000)
		avl.Put(v)
	}

	for i := 0; i < b.N; i++ {
		avl.Find(i)
	}

	b.StopTimer()
>>>>>>> 86a8ee11986ed2002b8beb5420349f350594efd7
}

func TestHeap(t *testing.T) {

	heap := binaryheap.NewWithIntComparator()

	for i := 0; i < 10; i++ {
		heap.Push(randomdata.Number(0, 1000))
	}

	t.Error(heap.Peek())
	t.Error(heap.Values())

	utils.Sort(heap.Values(), utils.IntComparator)

}
