package processor

import (
	"encoding/csv"
	"encoding/json"
	"fmt"
	"os"
	"testing"
	"time"

	"github.com/stretchr/testify/assert"
	"github.com/tidbcloud/observability/data-collector/pkg/common"
)

func TestSaveCheckPoint(t *testing.T) {
	t.Run("success", func(t *testing.T) {
		SaveCheckPoint("./test/checkpoint.json", time.Now().Unix())
		defer deleteData("./test")
	})
}

func TestSaveClusterIDMap(t *testing.T) {
	t.Run("success", func(t *testing.T) {
		SaveClusterIDMap("./test/cluster_id.json", map[string]map[string]bool{
			"test": {
				"default": true,
			},
		})
		defer deleteData("./test")
	})
}

func TestWriteJsonFile(t *testing.T) {
	t.Run("success", func(t *testing.T) {
		path := "test.json"
		WriteJsonFile(path, "test data")
		defer os.Remove(path)
		file, err := os.Open(path)
		assert.NoError(t, err)
		defer file.Close()
		var data string
		decoder := json.NewDecoder(file)
		err = decoder.Decode(&data)
		assert.NoError(t, err)
		assert.Equal(t, data, "test data")
	})
}

func TestGetCheckPoint(t *testing.T) {
	t.Run("success", func(t *testing.T) {
		path := "test.json"
		ts := time.Now().Unix()
		cp := common.CheckPoint{
			Timestamp: ts,
		}
		WriteJsonFile(path, cp)
		defer os.Remove(path)
		newCp, err := GetCheckPoint(path)
		assert.NoError(t, err)
		assert.Equal(t, newCp.Timestamp, ts)
	})
	t.Run("file doesn't exist", func(t *testing.T) {
		path := "test.json"
		cp, err := GetCheckPoint(path)
		assert.Error(t, err)
		assert.Nil(t, cp)
	})
}

func TestGetClusterIDMap(t *testing.T) {
	os.MkdirAll("test", 0700)
	defer deleteData("./test")
	t.Run("success", func(t *testing.T) {
		SaveClusterIDMap("test/cluster_id.json", map[string]map[string]bool{
			"test": {
				"default": true,
			},
		})
		mp, err := GetClusterIDMap("test/cluster_id.json")
		assert.NoError(t, err)
		assert.NotEmpty(t, mp)
	})
	t.Run("no file", func(t *testing.T) {
		mp, err := GetClusterIDMap("test/cluster_id1.json")
		assert.Error(t, err)
		assert.Empty(t, mp)
	})
}

func TestWriteCsvFile(t *testing.T) {
	t.Run("success", func(t *testing.T) {
		path := "test.csv"
		file, err := os.Create(path)
		defer os.Remove(path)
		assert.NoError(t, err)
		assert.NotEmpty(t, file)
		writer := csv.NewWriter(file)
		assert.NotEmpty(t, writer)
		data := []string{"id", "question"}
		err = WriteCsvFile(writer, data)
		assert.NoError(t, err)

		file, _ = os.Open(path)
		r := csv.NewReader(file)
		row, err := r.Read()
		assert.NoError(t, err)
		assert.Equal(t, row, data)
	})
	t.Run("wrong writer comma", func(t *testing.T) {
		path := "test.csv"
		file, err := os.Create(path)
		defer os.Remove(path)
		assert.NoError(t, err)
		assert.NotEmpty(t, file)
		writer := csv.NewWriter(file)
		writer.Comma = '"'
		data := []string{"test"}
		err = WriteCsvFile(writer, data)
		assert.Error(t, err)
	})
}

func TestDeleteFiles(t *testing.T) {
	t.Run("success", func(t *testing.T) {
		pt := "test.csv"
		os.Create(pt)
		err := DeleteFiles(pt)
		assert.NoError(t, err)
	})

}

func TestInitAWSConfig(t *testing.T) {
	cfg, err := InitAWSConfig("")
	fmt.Println(cfg)
	assert.Error(t, err)
}

func TestNewDataProcessor(t *testing.T) {
	p := NewDataProcessor("")
	assert.Nil(t, p)
}
