package tidbxinstance

import (
	"testing"
	"time"

	"github.com/stretchr/testify/assert"
	"github.com/stretchr/testify/require"
	"google.golang.org/protobuf/types/known/timestamppb"

	bffv1beta2 "github.com/tidbcloud/tidb-management-service/api/spec/bff/cluster_management/v1beta2"
	openapicommonv1beta1 "github.com/tidbcloud/tidb-management-service/api/spec/tidb_cloud_open_api/common/v1beta1"
	openapingv1beta2 "github.com/tidbcloud/tidb-management-service/api/spec/tidb_cloud_open_api/nextgen/v1beta2"
	"github.com/tidbcloud/tidb-management-service/tidb-mgmt-service/domain/entity"
)

func TestNormalizeEngineType(t *testing.T) {
	t.Parallel()

	require.Equal(
		t,
		openapicommonv1beta1.EngineType_MYSQL_COMPATIBLE,
		normalizeEngineType(openapicommonv1beta1.EngineType_ENGINE_TYPE_UNSPECIFIED),
	)
	require.Equal(
		t,
		openapicommonv1beta1.EngineType_POSTGRESQL_COMPATIBLE,
		normalizeEngineType(openapicommonv1beta1.EngineType_POSTGRESQL_COMPATIBLE),
	)
}

func TestCvtTiDB_NextgenPremiumCompatiblePlans(t *testing.T) {
	ctx := t.Context()
	server := &TiDBServer{}

	tests := []struct {
		name       string
		plan       openapicommonv1beta1.ServicePlan
		assertTidb func(*testing.T, *bffv1beta2.Tidb)
	}{
		{
			name: "Premium",
			plan: openapicommonv1beta1.ServicePlan_Premium,
			assertTidb: func(t *testing.T, tidb *bffv1beta2.Tidb) {
				t.Helper()
				require.NotNil(t, tidb.GetPremiumInstance())
				assert.Equal(t, "test-tidb", tidb.GetPremiumInstance().GetDisplayName())
			},
		},
		{
			name: "Premium_Reserved",
			plan: openapicommonv1beta1.ServicePlan_Premium_Reserved,
			assertTidb: func(t *testing.T, tidb *bffv1beta2.Tidb) {
				t.Helper()
				require.NotNil(t, tidb.GetPremiumReservedInstance())
				assert.Equal(t, "test-tidb", tidb.GetPremiumReservedInstance().GetDisplayName())
			},
		},
		{
			name: "Essential_V2",
			plan: openapicommonv1beta1.ServicePlan_Essential_V2,
			assertTidb: func(t *testing.T, tidb *bffv1beta2.Tidb) {
				t.Helper()
				require.NotNil(t, tidb.GetEssentialV2Instance())
				assert.Equal(t, "test-tidb", tidb.GetEssentialV2Instance().GetDisplayName())
			},
		},
	}
	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			tidb, err := server.cvtTiDB(ctx, &entity.Cluster{
				ClusterId:   101,
				ServicePlan: tt.plan,
			}, &openapingv1beta2.Tidb{
				Name:        "tidbs/101",
				DisplayName: "test-tidb",
			})

			require.NoError(t, err)
			assert.Equal(t, tt.plan, tidb.GetServicePlan())
			assert.Equal(t, "tidbs/101", tidb.GetName())
			tt.assertTidb(t, tidb)
		})
	}
}

func TestGetCreateAt_NextgenPremiumCompatiblePlans(t *testing.T) {
	createTime := time.Date(2026, time.May, 8, 7, 35, 0, 0, time.UTC)

	tests := []struct {
		name string
		tidb *bffv1beta2.Tidb
	}{
		{
			name: "Premium",
			tidb: &bffv1beta2.Tidb{
				ServicePlan: openapicommonv1beta1.ServicePlan_Premium,
				Tidb: &bffv1beta2.Tidb_PremiumInstance{
					PremiumInstance: &openapingv1beta2.Tidb{
						CreateTime: timestamppb.New(createTime),
					},
				},
			},
		},
		{
			name: "Premium_Reserved",
			tidb: &bffv1beta2.Tidb{
				ServicePlan: openapicommonv1beta1.ServicePlan_Premium_Reserved,
				Tidb: &bffv1beta2.Tidb_PremiumReservedInstance{
					PremiumReservedInstance: &openapingv1beta2.Tidb{
						CreateTime: timestamppb.New(createTime),
					},
				},
			},
		},
		{
			name: "Essential_V2",
			tidb: &bffv1beta2.Tidb{
				ServicePlan: openapicommonv1beta1.ServicePlan_Essential_V2,
				Tidb: &bffv1beta2.Tidb_EssentialV2Instance{
					EssentialV2Instance: &openapingv1beta2.Tidb{
						CreateTime: timestamppb.New(createTime),
					},
				},
			},
		},
	}
	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			got := getCreateAt(tt.tidb)

			assert.Equal(t, createTime, got)
		})
	}
}
