package buckets

import (
	"github.com/stretchr/testify/assert"
	"idun/pkg/storage"
	"testing"
	"time"
)

func TestCalculator(t *testing.T) {
	tt := []struct {
		Name   string
		Config Config
		Plan   []string
		Start  time.Time
	}{
		{
			Name:   "empty config",
			Config: Config{},
			Plan:   []string{"2023-09-27 15:00:00 +0000 UTC to 2023-09-27 15:18:03.000000004 +0000 UTC (Unlimit)", "0001-01-01 00:00:00 +0000 UTC to 2023-09-27 14:59:59.999999999 +0000 UTC (Delete)"},
			Start:  time.Date(2023, 9, 27, 15, 18, 3, 4, time.UTC),
		},
		{
			Name:   "keep last 2 hour, delete everything else",
			Config: Config{Unlimit: 2},
			Plan:   []string{"2023-09-27 15:00:00 +0000 UTC to 2023-09-27 15:18:03.000000004 +0000 UTC (Unlimit)", "2023-09-27 14:00:00 +0000 UTC to 2023-09-27 14:59:59.999999999 +0000 UTC (Unlimit)", "2023-09-27 13:00:00 +0000 UTC to 2023-09-27 13:59:59.999999999 +0000 UTC (Unlimit)", "0001-01-01 00:00:00 +0000 UTC to 2023-09-27 12:59:59.999999999 +0000 UTC (Delete)"},
			Start:  time.Date(2023, 9, 27, 15, 18, 3, 4, time.UTC),
		},
		{
			Name:   "keep one for the last 2 hour, delete everything else",
			Config: Config{Hourly: 2},
			Plan:   []string{"2023-09-27 15:00:00 +0000 UTC to 2023-09-27 15:18:03.000000004 +0000 UTC (Unlimit)", "2023-09-27 14:00:00 +0000 UTC to 2023-09-27 14:59:59.999999999 +0000 UTC", "2023-09-27 13:00:00 +0000 UTC to 2023-09-27 13:59:59.999999999 +0000 UTC", "0001-01-01 00:00:00 +0000 UTC to 2023-09-27 12:59:59.999999999 +0000 UTC (Delete)"},
			Start:  time.Date(2023, 9, 27, 15, 18, 3, 4, time.UTC),
		},
		{
			Name:   "keep one houre everything, one for the last 2 hour, delete everything else",
			Config: Config{Unlimit: 1, Hourly: 2},
			Plan:   []string{"2023-09-27 15:00:00 +0000 UTC to 2023-09-27 15:18:03.000000004 +0000 UTC (Unlimit)", "2023-09-27 14:00:00 +0000 UTC to 2023-09-27 14:59:59.999999999 +0000 UTC (Unlimit)", "2023-09-27 13:00:00 +0000 UTC to 2023-09-27 13:59:59.999999999 +0000 UTC", "2023-09-27 12:00:00 +0000 UTC to 2023-09-27 12:59:59.999999999 +0000 UTC", "0001-01-01 00:00:00 +0000 UTC to 2023-09-27 11:59:59.999999999 +0000 UTC (Delete)"},
			Start:  time.Date(2023, 9, 27, 15, 18, 3, 4, time.UTC),
		},
		{
			Name:   "keep two daily",
			Config: Config{Daily: 2},
			Start:  time.Date(2023, 9, 27, 2, 18, 3, 4, time.UTC),
			Plan:   []string{"2023-09-27 02:00:00 +0000 UTC to 2023-09-27 02:18:03.000000004 +0000 UTC (Unlimit)", "2023-09-27 01:00:00 +0000 UTC to 2023-09-27 01:59:59.999999999 +0000 UTC", "2023-09-27 00:00:00 +0000 UTC to 2023-09-27 00:59:59.999999999 +0000 UTC", "2023-09-26 00:00:00 +0000 UTC to 2023-09-26 23:59:59.999999999 +0000 UTC", "2023-09-25 00:00:00 +0000 UTC to 2023-09-25 23:59:59.999999999 +0000 UTC", "0001-01-01 00:00:00 +0000 UTC to 2023-09-24 23:59:59.999999999 +0000 UTC (Delete)"},
		},
		{
			Name:   "keep two daily and one weekly",
			Config: Config{Daily: 1, Weekly: 1},
			Start:  time.Date(2023, 9, 13, 2, 18, 3, 4, time.UTC),
			Plan:   []string{"2023-09-13 02:00:00 +0000 UTC to 2023-09-13 02:18:03.000000004 +0000 UTC (Unlimit)", "2023-09-13 01:00:00 +0000 UTC to 2023-09-13 01:59:59.999999999 +0000 UTC", "2023-09-13 00:00:00 +0000 UTC to 2023-09-13 00:59:59.999999999 +0000 UTC", "2023-09-12 00:00:00 +0000 UTC to 2023-09-12 23:59:59.999999999 +0000 UTC", "2023-09-11 00:00:00 +0000 UTC to 2023-09-11 23:59:59.999999999 +0000 UTC", "2023-09-04 00:00:00 +0000 UTC to 2023-09-10 23:59:59.999999999 +0000 UTC", "0001-01-01 00:00:00 +0000 UTC to 2023-09-03 23:59:59.999999999 +0000 UTC (Delete)"},
		},
		{
			Name:   "keep ones for 2 month",
			Config: Config{Monthly: 2},
			Start:  time.Date(2023, 9, 13, 2, 18, 3, 4, time.UTC),
			Plan:   []string{"2023-09-13 02:00:00 +0000 UTC to 2023-09-13 02:18:03.000000004 +0000 UTC (Unlimit)", "2023-09-13 01:00:00 +0000 UTC to 2023-09-13 01:59:59.999999999 +0000 UTC", "2023-09-13 00:00:00 +0000 UTC to 2023-09-13 00:59:59.999999999 +0000 UTC", "2023-09-12 00:00:00 +0000 UTC to 2023-09-12 23:59:59.999999999 +0000 UTC", "2023-09-11 00:00:00 +0000 UTC to 2023-09-11 23:59:59.999999999 +0000 UTC", "2023-09-04 00:00:00 +0000 UTC to 2023-09-10 23:59:59.999999999 +0000 UTC", "2023-09-01 00:00:00 +0000 UTC to 2023-09-03 23:59:59.999999999 +0000 UTC", "2023-08-01 00:00:00 +0000 UTC to 2023-08-31 23:59:59.999999999 +0000 UTC", "2023-07-01 00:00:00 +0000 UTC to 2023-07-31 23:59:59.999999999 +0000 UTC", "0001-01-01 00:00:00 +0000 UTC to 2023-06-30 23:59:59.999999999 +0000 UTC (Delete)"},
		},
	}

	for _, ts := range tt {
		t.Run(ts.Name, func(t *testing.T) {

			buckets, err := GenerateBuckets(ts.Start, ts.Config, time.UTC)
			assert.Nil(t, err, "should return no error")

			plan := []string{}
			for _, b := range buckets {
				plan = append(plan, b.ToString())
			}

			assert.Equal(t, ts.Plan, plan, "should return right plan")
		})
	}
}

func TestInsertFilesInBuckets(t *testing.T) {
	bucketTime := time.Date(2023, 10, 11, 0, 0, 0, 0, time.UTC)

	bucket1, _ := NewTimeBucket(bucketTime, bucketTime.Add(1*time.Hour))
	bucket2, _ := NewTimeBucket(bucketTime.Add(1*time.Hour), bucketTime.Add(2*time.Hour))

	buckets := []Bucket{&bucket1, &bucket2}

	file1 := TestFile{time: bucketTime.Add(5 * time.Minute)}
	file2 := TestFile{time: bucketTime.Add(65 * time.Minute)}
	file3 := TestFile{time: bucketTime.Add(75 * time.Minute)}

	files := []storage.File{file1, file2, file3}

	err := InsertFilesInBuckets(&buckets, files)
	assert.Nil(t, err, "should insert file in buckets without error")

	bucket1DeleteFiles, _ := buckets[0].GetFilesToDelete()
	assert.Equal(t, []storage.File{}, bucket1DeleteFiles)

	bucket2DeleteFiles, _ := buckets[1].GetFilesToDelete()
	assert.Equal(t, []storage.File{file2}, bucket2DeleteFiles)
}