package grpc

import (
	"regexp"
	"testing"

	"github.com/stretchr/testify/require"
	"github.com/tidbcloud/dataflow-service/idl/pbgen/proto/agent"
	"github.com/tidbcloud/pkgv2/import/precheck"
)

func TestGenerateCustomFilePattern(t *testing.T) {
	tests := []struct {
		name       string
		pattern    string
		wantRegexp string
		matches    []string
		notMatches []string
	}{
		{
			name:       "asterisk wildcard",
			pattern:    "test/*.csv",
			wantRegexp: `^test/.*\.csv$`,
			matches:    []string{"test/part-000001.csv", "test/.csv"},
			notMatches: []string{"test/part-000001.sql", "other/part-000001.csv"},
		},
		{
			name:       "question mark wildcard",
			pattern:    "data?.csv",
			wantRegexp: `^data.\.csv$`,
			matches:    []string{"data1.csv", "data-.csv"},
			notMatches: []string{"data.csv", "data12.csv"},
		},
		{
			name:       "customer pattern",
			pattern:    "actionpoint*.csv",
			wantRegexp: `^actionpoint.*\.csv$`,
			matches:    []string{"actionpoint.entries.000001.csv", "actionpoint.entries.001231.csv"},
			notMatches: []string{"consent.consents.000001.csv", "actionpoin.csv"},
		},
		{
			name:       "regexp metacharacters are escaped",
			pattern:    "db+name.(table)|x.csv",
			wantRegexp: `^db\+name\.\(table\)\|x\.csv$`,
			matches:    []string{"db+name.(table)|x.csv"},
			notMatches: []string{"dbbbname.tablex.csv"},
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			got := (&AgentServer{}).generateCustomFilePattern(tt.pattern, "schema", "table", agent.ImportFileType_CSV)
			require.Equal(t, tt.wantRegexp, got)

			re, err := regexp.Compile(got)
			require.NoError(t, err)
			for _, fileName := range tt.matches {
				require.True(t, re.MatchString(fileName), fileName)
			}
			for _, fileName := range tt.notMatches {
				require.False(t, re.MatchString(fileName), fileName)
			}
		})
	}
}

func TestConvertToPrecheckRespPreservesIncompleteStatusWithoutMatchedTables(t *testing.T) {
	tests := map[string]struct {
		status          precheck.PrecheckStatus
		wantStatus      agent.ImportPrecheckStatusType_Enum
		wantIsTruncated bool
	}{
		"truncated": {
			status:          precheck.PrecheckStatusTruncated,
			wantStatus:      agent.ImportPrecheckStatusType_TRUNCATED,
			wantIsTruncated: true,
		},
		"timeout": {
			status:     precheck.PrecheckStatusTimeout,
			wantStatus: agent.ImportPrecheckStatusType_TIMEOUT,
		},
		"completed preserves legacy default response": {
			status:     precheck.PrecheckStatusCompleted,
			wantStatus: agent.ImportPrecheckStatusType_UNSPECIFIED,
		},
	}

	for name, tt := range tests {
		t.Run(name, func(t *testing.T) {
			resp := convertToPrecheckResp(&precheck.PrecheckResult{Status: tt.status})

			require.Equal(t, tt.wantStatus, resp.Status)
			require.Equal(t, tt.wantIsTruncated, resp.IsTruncated)
			require.Empty(t, resp.TargetTables)
		})
	}
}
