package import_svc

import (
	"testing"

	. "github.com/onsi/gomega"
	"github.com/tidbcloud/dataflow-service/idl/pbgen/proto/agent"
	"github.com/tidbcloud/pkgv2/bizerr"
	"github.com/tidbcloud/serverless-service/internal/domain/entity"
)

func TestParseColumns(t *testing.T) {
	g := NewGomegaWithT(t)
	testCases := []struct {
		table    *agent.Table
		expected []*entity.ColumnInfo
	}{
		{
			table: &agent.Table{
				RowHeaders:   []string{"", ""},
				RowDataTypes: []string{"VARCHAR(64)", "BIGINT(20)"},
			},
			expected: []*entity.ColumnInfo{
				{ColumnName: "column_1", ColumnType: "VARCHAR(64)"},
				{ColumnName: "column_2", ColumnType: "BIGINT(20)"},
			},
		}, {
			table: &agent.Table{
				RowHeaders:   []string{"name", "info"},
				RowDataTypes: []string{"VARCHAR(64)", "JSON"},
			},
			expected: []*entity.ColumnInfo{
				{ColumnName: "name", ColumnType: "VARCHAR(64)"},
				{ColumnName: "info", ColumnType: "JSON"},
			},
		},
	}

	for _, tc := range testCases {
		columns := ParseColumns(tc.table)
		g.Expect(columns).To(Equal(tc.expected))
	}
}

func TestValidateColumns(t *testing.T) {
	g := NewGomegaWithT(t)
	testCases := []struct {
		fileColumns   []*entity.ColumnInfo
		targetColumns []*entity.ColumnInfo
		expectedErr   bizerr.BizError
	}{
		{
			fileColumns: []*entity.ColumnInfo{
				{ColumnName: "col1", ColumnType: "VARCHAR(64)"},
				{ColumnName: "col2", ColumnType: "BIGINT(20)"},
			},
			targetColumns: []*entity.ColumnInfo{
				{ColumnName: "col1", ColumnType: "VARCHAR(64)"},
				{ColumnName: "col2", ColumnType: "BIGINT(20)"},
			},
			expectedErr: nil,
		}, {
			fileColumns: []*entity.ColumnInfo{
				{ColumnName: "col1", ColumnType: "VARCHAR(64)"},
				{ColumnName: "col2", ColumnType: "BIGINT(20)"},
			},
			targetColumns: []*entity.ColumnInfo{
				{ColumnName: "col1", ColumnType: "VARCHAR(256)"},
				{ColumnName: "col2", ColumnType: "VARCHAR(256)"},
			},
			expectedErr: nil,
		}, {
			fileColumns: []*entity.ColumnInfo{
				{ColumnName: "col1", ColumnType: "VARCHAR(64)"},
				{ColumnName: "col2", ColumnType: "BIGINT(20)"},
			},
			targetColumns: []*entity.ColumnInfo{
				{ColumnName: "col1", ColumnType: "TEXT"},
				{ColumnName: "col2", ColumnType: "BIGINT(20)"},
				{ColumnName: "col3", ColumnType: "TEXT"},
			},
			expectedErr: bizerr.New(bizerr.ErrCodeParams, ErrColumnsCountNotMatch, 2, 3),
		}, {
			fileColumns: []*entity.ColumnInfo{
				{ColumnName: "col1", ColumnType: "VARCHAR(64)"},
				{ColumnName: "col2", ColumnType: "BIGINT(20)"},
				{ColumnName: "col3", ColumnType: "TEXT"},
			},
			targetColumns: []*entity.ColumnInfo{
				{ColumnName: "col2", ColumnType: "TEXT"},
				{ColumnName: "col4", ColumnType: "TIME"},
				{ColumnName: "col6", ColumnType: "TEXT"},
			},
			expectedErr: bizerr.New(bizerr.ErrCodeParams, ErrColumnsMissingInFile+" \n"+ErrColumnsMissingInTarget,
				"col4,col6", "col1,col3"),
		},
	}

	for _, tc := range testCases {
		err := ValidateColumns(tc.fileColumns, tc.targetColumns)
		if tc.expectedErr == nil {
			g.Expect(err).To(BeNil())
		} else {
			g.Expect(err.ErrCode()).To(Equal(tc.expectedErr.ErrCode()))
			g.Expect(err.ErrMsg()).To(Equal(tc.expectedErr.ErrMsg()))
		}
	}
}
