package utils

import (
	"context"
	"testing"

	. "github.com/onsi/gomega"
	"github.com/tidbcloud/serverless-service/idl/pbgen/proto/console"
	"github.com/tidbcloud/serverless-service/internal/domain/constant"
)

func TestMultiFileMatcher(t *testing.T) {
	g := NewGomegaWithT(t)
	testCases := []struct {
		infos       *console.ImportTargetTableInfo
		names       []string
		expectedErr error
		expectedUri string
		d           constant.DataFormat
	}{
		{
			names: []string{"gs://bucket/path/to/test.a.csv"},
			infos: &console.ImportTargetTableInfo{
				TargetTable: &console.Table{
					Database: "test",
					Table:    "b",
				},
				CustomFile: "",
			},
			expectedErr: nil,
			expectedUri: "",
			d:           constant.ImportDataFormatCsv,
		},
		{
			names: []string{"gs://bucket/path/to/test.a.csv"},
			infos: &console.ImportTargetTableInfo{
				TargetTable: &console.Table{
					Database: "test",
					Table:    "a",
				},
				CustomFile: "",
			},
			expectedErr: nil,
			expectedUri: "gs://bucket/path/to/test.a.csv",
			d:           constant.ImportDataFormatCsv,
		},
		{
			names: []string{"gs://bucket/path/to/test.a.csv"},
			infos: &console.ImportTargetTableInfo{
				TargetTable: &console.Table{
					Database: "test",
					Table:    "a",
				},
				CustomFile: "",
			},
			expectedErr: nil,
			expectedUri: "",
			d:           constant.ImportDataFormatSql,
		},
	}

	for _, tc := range testCases {
		m := NewDefaultMultiFileMatcher(tc.d)
		u, err := m.Match(context.Background(), tc.infos, tc.names)
		if tc.expectedErr == nil {
			g.Expect(err).To(BeNil())
			g.Expect(u).To(Equal(tc.expectedUri))
		} else {
			g.Expect(err).To(Equal(tc.expectedErr))
		}
	}
}

func TestCustomMatcher(t *testing.T) {
	g := NewGomegaWithT(t)
	testCases := []struct {
		infos       *console.ImportTargetTableInfo
		names       []string
		expectedErr error
		expectedUri string
		d           constant.DataFormat
	}{
		{
			names: []string{"gs://bucket/path/to/test.a.csv"},
			infos: &console.ImportTargetTableInfo{
				TargetTable: &console.Table{
					Database: "test",
					Table:    "a",
				},
				CustomFile: "gs://bucket/path/to/test.a.csv",
			},
			expectedErr: nil,
			expectedUri: "gs://bucket/path/to/test.a.csv",
			d:           constant.ImportDataFormatCsv,
		},
		{
			names: []string{"gs://bucket/path/to/test.a.csv"},
			infos: &console.ImportTargetTableInfo{
				TargetTable: &console.Table{
					Database: "test",
					Table:    "b",
				},
				CustomFile: "gs://bucket/path/to/test.a.csv",
			},
			expectedErr: nil,
			expectedUri: "gs://bucket/path/to/test.a.csv",
			d:           constant.ImportDataFormatCsv,
		},
		{
			names: []string{"gs://bucket/path/to/ewrwer.csv"},
			infos: &console.ImportTargetTableInfo{
				TargetTable: &console.Table{
					Database: "test",
					Table:    "a",
				},
				CustomFile: "gs://bucket/path/to/ewrwer.*",
			},
			expectedErr: nil,
			expectedUri: "gs://bucket/path/to/ewrwer.csv",
			d:           constant.ImportDataFormatCsv,
		},
		{
			names: []string{"gs://bucket/path/to/ewrwer.csv"},
			infos: &console.ImportTargetTableInfo{
				TargetTable: &console.Table{
					Database: "test",
					Table:    "a",
				},
				CustomFile: "gs://bucket/path/to/ewrwer.?",
			},
			expectedErr: nil,
			expectedUri: "",
			d:           constant.ImportDataFormatCsv,
		},
		{
			names: []string{"gs://bucket/path/to/test.a.csv"},
			infos: &console.ImportTargetTableInfo{
				TargetTable: &console.Table{
					Database: "test",
					Table:    "a",
				},
				CustomFile: "gs://bucket/path/to/test.a.csv",
			},
			expectedErr: nil,
			expectedUri: "",
			d:           constant.ImportDataFormatSql,
		},
	}

	for _, tc := range testCases {
		m := NewCustomMatcher(tc.d)
		u, err := m.Match(context.Background(), tc.infos, tc.names)
		if tc.expectedErr == nil {
			g.Expect(err).To(BeNil())
			g.Expect(u).To(Equal(tc.expectedUri))
		} else {
			g.Expect(err).To(Equal(tc.expectedErr))
		}
	}
}
