package writebehind

import (
	"encoding/json"
	"testing"
	"time"
)

func TestSync(t *testing.T) {
	m := MemoryIncrementer{}
	c := NewCache(&m, time.Millisecond)
	defer c.Stop()
	c.Sync() // test that unnecessary sync is a no-op
	c.Increment("test1", 10)
	c.Increment("test2", 100)
	time.Sleep(time.Millisecond)
	if m.Get("test1") != 10 {
		t.Errorf("Expected test1 to be %d, got %d", 10, m.values["test1"])
	}
	if m.Get("test2") != 100 {
		t.Errorf("Expected test2 to be %d, got %d", 100, m.values["test2"])
	}
	c.Increment("test1", 10)
	c.Increment("test2", 100)
	time.Sleep(time.Millisecond)
	if m.Get("test1") != 20 {
		t.Errorf("Expected test1 to be %d, got %d", 20, m.values["test1"])
	}
	if m.Get("test2") != 200 {
		t.Errorf("Expected test2 to be %d, got %d", 200, m.values["test2"])
	}
}

func TestString(t *testing.T) {
	m := MemoryIncrementer{}
	c := NewCache(&m, time.Millisecond)
	defer c.Stop()
	c.Increment("test1", 10)
	c.Increment("test2", 100)
	c.Increment(`"test3"`, 1000)
	str := c.String()
	var result map[string]int64
	err := json.Unmarshal([]byte(str), &result)
	if err != nil {
		t.Errorf("Error unmarshalling returned JSON: %#+v", err)
	}
	if result["test1"] != 10 {
		t.Errorf("Expected test1 to be %d, got %d", 10, result["test1"])
	}
	if result["test2"] != 100 {
		t.Errorf("Expected test2 to be %d, got %d", 100, result["test2"])
	}
	if result["\"test3\""] != 1000 {
		t.Errorf("Expected \"test3\" to be %d, got %d", 1000, result["\"test3\""])
	}
}

func BenchmarkSync(b *testing.B) {
	m := MemoryIncrementer{}
	c := NewCache(&m, time.Second*5)
	defer c.Stop()

	b.RunParallel(func(pb *testing.PB) {
		for pb.Next() {
			c.Increment("myvalue", 1)
			c.Increment("othervalue", 1)
			c.Increment("other other value", 1)
			c.Increment("weird value", 1)
		}
	})
}
