package util

import (
	"bytes"
	"encoding/gob"
	"fmt"
	"testing"

	"github.com/stretchr/testify/assert"
	"go.skia.org/infra/go/deepequal"
	"go.skia.org/infra/go/testutils/unittest"
)

type Item struct {
	Id    string
	Map   map[string]string
	Slice []string
}

func TestGobEncoder(t *testing.T) {
	unittest.SmallTest(t)
	// TODO(benjaminwagner): Is there any way to cause an error?
	e := GobEncoder{}
	expectedItems := map[*Item][]byte{}
	for i := 0; i < 25; i++ {
		item := &Item{}
		item.Id = fmt.Sprintf("Id-%d", i)
		item.Map = map[string]string{"PointA": "PointB"}
		item.Slice = []string{"bread"}
		var buf bytes.Buffer
		err := gob.NewEncoder(&buf).Encode(item)
		assert.NoError(t, err)
		expectedItems[item] = buf.Bytes()
		assert.True(t, e.Process(item))
	}

	actualItems := map[*Item][]byte{}
	for item, serialized, err := e.Next(); item != nil; item, serialized, err = e.Next() {
		assert.NoError(t, err)
		actualItems[item.(*Item)] = serialized
	}

	deepequal.AssertDeepEqual(t, expectedItems, actualItems)
}

func TestGobEncoderNoItems(t *testing.T) {
	unittest.SmallTest(t)
	e := GobEncoder{}
	item, serialized, err := e.Next()
	assert.NoError(t, err)
	assert.Nil(t, item)
	assert.Nil(t, serialized)
}

func TestGobDecoder(t *testing.T) {
	unittest.SmallTest(t)
	d := NewGobDecoder(func() interface{} {
		return &Item{}
	}, func(ch <-chan interface{}) interface{} {
		items := []*Item{}
		for item := range ch {
			items = append(items, item.(*Item))
		}
		return items
	})
	expectedItems := map[string]*Item{}
	for i := 0; i < 250; i++ {
		item := &Item{}
		item.Id = fmt.Sprintf("Id-%d", i)
		item.Map = map[string]string{"PointA": "PointB"}
		item.Slice = []string{"bread"}
		var buf bytes.Buffer
		err := gob.NewEncoder(&buf).Encode(item)
		assert.NoError(t, err)
		expectedItems[item.Id] = item
		assert.True(t, d.Process(buf.Bytes()))
	}

	actualItems := map[string]*Item{}
	iResult, err := d.Result()
	assert.NoError(t, err)
	result := iResult.([]*Item)
	assert.Equal(t, len(expectedItems), len(result))
	for _, item := range result {
		actualItems[item.Id] = item
	}
	deepequal.AssertDeepEqual(t, expectedItems, actualItems)
}

func TestGobDecoderNoItems(t *testing.T) {
	unittest.SmallTest(t)
	d := NewGobDecoder(func() interface{} {
		return &Item{}
	}, func(ch <-chan interface{}) interface{} {
		items := []*Item{}
		for item := range ch {
			items = append(items, item.(*Item))
		}
		return items
	})
	result, err := d.Result()
	assert.NoError(t, err)
	assert.Equal(t, 0, len(result.([]*Item)))
}

func TestGobDecoderError(t *testing.T) {
	unittest.SmallTest(t)
	item := &Item{}
	item.Id = "Id"
	var buf bytes.Buffer
	err := gob.NewEncoder(&buf).Encode(item)
	assert.NoError(t, err)
	serialized := buf.Bytes()
	invalid := append([]byte("Hi Mom!"), serialized...)

	d := NewGobDecoder(func() interface{} {
		return &Item{}
	}, func(ch <-chan interface{}) interface{} {
		items := []*Item{}
		for item := range ch {
			items = append(items, item.(*Item))
		}
		return items
	})
	// Process should return true before it encounters an invalid result.
	assert.True(t, d.Process(serialized))
	assert.True(t, d.Process(serialized))
	// Process may return true or false after encountering an invalid value.
	_ = d.Process(invalid)
	for i := 0; i < 250; i++ {
		_ = d.Process(serialized)
	}

	// Result should return error.
	result, err := d.Result()
	assert.Error(t, err)
	assert.Nil(t, result)
}
