package ircclient

import (
	"bytes"
	"log"
	"os"
	"strings"
	"testing"
	"time"
)

func TestFloodTrack(t *testing.T) {
	var Flood FloodTrack
	Flood.Init(3, 1)

	if Flood.Full() {
		t.Error("Expected Track to be empty")
	}

	for x := 1; x < 3; x++ {
		Flood.Save()
		if Flood.Pos != x {
			t.Errorf("Expected Track Pos to be %d", x)
		}
		if Flood.Full() {
			t.Error("Expected Track to be empty")
		}
	}

	Flood.Save()
	if Flood.Pos != 3 {
		t.Error("Expected Track Pos to be 3")
	}
	if !Flood.Full() {
		t.Error("Expected Track to be full")
	}
	time.Sleep(time.Second)
	Flood.Expire()
	if Flood.Pos != 0 {
		t.Error("Expected Track Pos to be 0")
	}
}

func TestThrottleOnly(t *testing.T) {
	// eat log output
	var logbuffer bytes.Buffer
	log.SetOutput(&logbuffer)
	defer func() {
		log.SetOutput(os.Stderr)
	}()

	var buff ThrottleBuffer
	buff.init()
	buff.push("#chat", "msg1")
	if !buff.Life_sucks {
		t.Error("Flood control should be enabled here.")
	}
	buff.push("#chat", "msg2")
	buff.push("#chat", "msg3")
	if !buff.Life_sucks {
		t.Error("Flood control should be enabled here.")
	}
	buff.delete("#chat")
	if buff.Life_sucks {
		t.Error("Flood control should not be enabled here.")
	}
}

func TestThrottleDelete(t *testing.T) {
	// eat log output
	var logbuff bytes.Buffer
	log.SetOutput(&logbuff)
	defer func() {
		log.SetOutput(os.Stderr)
	}()

	var expect, line string
	var buff ThrottleBuffer
	buff.init()
	buff.push("#chat", "msg1")
	buff.push("#chat", "msg2")

	if !buff.Life_sucks {
		t.Error("Flood control should be enabled here.")
	}
	buff.push("#test", "test1")
	buff.push("#test", "test2")

	buff.push("#another", "msg3")
	if !buff.Life_sucks {
		t.Error("Flood control should be enabled here.")
	}
	expect = "#chat,#test,#another"
	line = strings.Join(buff.targets, ",")
	if line != expect {
		t.Errorf("Got %s, Expected %s", line, expect)
	}
	if buff.last != 0 {
		t.Errorf("Expected last=0, got %d", buff.last)
	}

	line = buff.pop()
	expect = "msg1"
	if line != expect {
		t.Errorf("Got %s, Expected %s", line, expect)
	}
	if buff.last != 1 {
		t.Errorf("Expected last=1, got %d", buff.last)
	}
	line = buff.pop()
	expect = "test1"
	if line != expect {
		t.Errorf("Got %s, Expected %s", line, expect)
	}
	if buff.last != 2 {
		t.Errorf("Expected last=2, got %d", buff.last)
	}

	buff.delete("#chat")
	expect = "#test,#another"
	line = strings.Join(buff.targets, ",")
	if line != expect {
		t.Errorf("Got %s, Expected %s", line, expect)
	}
	if buff.last != 1 {
		t.Errorf("Expected last=1, got %d", buff.last)
	}
	buff.delete("missing")
	if buff.last != 1 {
		t.Errorf("Expected last=1, got %d", buff.last)
	}
}

func TestThrottlePopDelete(t *testing.T) {
	// eat log output
	var logbuff bytes.Buffer
	log.SetOutput(&logbuff)
	defer func() {
		log.SetOutput(os.Stderr)
	}()

	var buff ThrottleBuffer
	buff.init()
	buff.push("#chat", "m1")
	buff.push("#chat", "m2")
	buff.push("#chat", "m3")
	buff.push("#test", "t1")
	buff.push("#other", "o1")
	buff.push("#other", "o2")
	buff.push("#other", "o3")

	// When we pop from #test, it needs to be deleted.

	var line, expect string

	expect = "#chat,#test,#other"
	line = strings.Join(buff.targets, ",")
	if line != expect {
		t.Errorf("Got %s, Expected %s", line, expect)
	}
	if buff.last != 0 {
		t.Errorf("Expected last=0, got %d", buff.last)
	}

	line = buff.pop()
	expect = "m1"
	if line != expect {
		t.Errorf("Got %s, Expected %s", line, expect)
	}
	if buff.last != 1 {
		t.Errorf("Expected last=1, got %d", buff.last)
	}

	line = buff.pop()
	expect = "t1"
	if line != expect {
		t.Errorf("Got %s, Expected %s", line, expect)
	}

	expect = "#chat,#other"
	line = strings.Join(buff.targets, ",")
	if line != expect {
		t.Errorf("Got %s, Expected %s", line, expect)
	}
	if buff.last != 1 {
		t.Errorf("Expected last=1, got %d", buff.last)
	}
	line = buff.pop()
	expect = "o1"
	if line != expect {
		t.Errorf("Got %s, Expected %s", line, expect)
	}
	if buff.last != 0 {
		t.Errorf("Expected last=0, got %d", buff.last)
	}

}
func TestThrottleBuffer(t *testing.T) {
	// eat log output
	var logbuff bytes.Buffer
	log.SetOutput(&logbuff)
	defer func() {
		log.SetOutput(os.Stderr)
	}()

	var buff ThrottleBuffer
	buff.init()
	buff.push("#chat", "msg1")
	if !buff.Life_sucks {
		t.Error("Flood control should be enabled here.")
	}
	buff.push("#chat", "msg2")
	buff.push("user", "msg3")

	// verify output order

	var str string
	var expect string
	for _, expect = range []string{"msg1", "msg3", "msg2"} {
		str = buff.pop()
		if str != expect {
			t.Errorf("Expected %s, got %s", expect, str)
		}
	}

	if buff.Life_sucks {
		t.Error("Flood control should not be enabled here.")
	}

	// verify deleting 1st item works

	buff.push("#chat", "msg1")
	if !buff.Life_sucks {
		t.Error("Flood control should be enabled here.")
	}
	buff.push("#chat", "msg2")
	buff.push("user", "msg3")
	buff.delete("#chat")

	str = buff.pop()
	expect = "msg3"
	if str != expect {
		t.Errorf("Expected %s, got %s", expect, str)
	}

	if buff.Life_sucks {
		t.Error("Flood control should not be enabled here.")
	}

	// verify deleting 2nd item works

	buff.push("#chat", "txt1")
	buff.push("user", "txt2")
	buff.delete("user")
	str = buff.pop()
	expect = "txt1"
	if str != expect {
		t.Errorf("Expected %s, got %s", expect, str)
	}

	if buff.Life_sucks {
		t.Error("Flood control should not be enabled here.")
	}

}