package service

import (
	"context"
	"testing"

	. "github.com/onsi/gomega"
	"github.com/tidbcloud/serverless-service/internal/domain/entity"
	"github.com/tidbcloud/serverless-service/internal/domain/facade/mock_facade"
	"github.com/tidbcloud/serverless-service/internal/domain/repo/mock_repo"
	"github.com/tidbcloud/serverless-service/internal/errorcode"
	globalserverlessv1 "github.com/tidbcloud/tidb-management-service/api/spec/global/serverless/v1"
	regionalserverlessv1 "github.com/tidbcloud/tidb-management-service/api/spec/regional/serverless/v1"
	tidbmgmtservicev1 "github.com/tidbcloud/tidb-management-service/api/spec/tidb_mgmt_service/v1"
	"go.uber.org/mock/gomock"
)

func Test_exportService_getExportProxyEndpoint_UsesPersistedValue(t *testing.T) {
	g := NewGomegaWithT(t)
	svc := &exportService{}

	proxyEndpoint, bizErr := svc.getExportProxyEndpoint(context.Background(), &entity.Export{
		ProxyEndpoint: "https://stored-proxy.example",
	})

	g.Expect(bizErr).To(BeNil())
	g.Expect(proxyEndpoint).To(Equal("https://stored-proxy.example"))
}

func Test_exportService_getExportProxyEndpoint_BackfillsMissingValue(t *testing.T) {
	g := NewGomegaWithT(t)
	ctx := context.Background()
	ctrl := gomock.NewController(t)
	defer ctrl.Finish()

	mgmtSvc := mock_facade.NewMockMgmtSvcFacade(ctrl)
	exportRepo := mock_repo.NewMockExportRepo(ctrl)
	svc := &exportService{mgmtSvc: mgmtSvc, exportRepo: exportRepo}
	export := &entity.Export{ID: "exp-1", ClusterID: "1"}
	cluster := &tidbmgmtservicev1.Cluster{
		ClusterId: 1,
		ClusterInfo: &tidbmgmtservicev1.Cluster_ServerlessCluster{
			ServerlessCluster: &globalserverlessv1.ServerlessServiceCluster{
				Cluster: &regionalserverlessv1.ServerlessRegionalServiceClusterInfo{
					ProxyEndpoint: "https://proxy.example",
				},
			},
		},
	}
	mgmtSvc.EXPECT().
		GetCluster(gomock.Any(), uint64(1), tidbmgmtservicev1.ClusterFilter_CLUSTER_VIEW_BASIC).
		Return(cluster, nil)
	exportRepo.EXPECT().
		UpdateProxyEndpoint(gomock.Any(), "exp-1", "1", "https://proxy.example").
		Return(nil)

	proxyEndpoint, bizErr := svc.getExportProxyEndpoint(ctx, export)

	g.Expect(bizErr).To(BeNil())
	g.Expect(proxyEndpoint).To(Equal("https://proxy.example"))
	g.Expect(export.ProxyEndpoint).To(Equal("https://proxy.example"))
}

func Test_exportService_getClusterProxyEndpoint_EmptyProxyEndpoint(t *testing.T) {
	g := NewGomegaWithT(t)
	ctx := context.Background()
	ctrl := gomock.NewController(t)
	defer ctrl.Finish()

	mgmtSvc := mock_facade.NewMockMgmtSvcFacade(ctrl)
	svc := &exportService{mgmtSvc: mgmtSvc}

	cluster := &tidbmgmtservicev1.Cluster{
		ClusterId: 1,
		ClusterInfo: &tidbmgmtservicev1.Cluster_ServerlessCluster{
			ServerlessCluster: &globalserverlessv1.ServerlessServiceCluster{
				Cluster: &regionalserverlessv1.ServerlessRegionalServiceClusterInfo{
					ProxyEndpoint: "",
				},
			},
		},
	}
	mgmtSvc.EXPECT().
		GetCluster(gomock.Any(), uint64(1), tidbmgmtservicev1.ClusterFilter_CLUSTER_VIEW_BASIC).
		Return(cluster, nil)

	proxyEndpoint, bizErr := svc.getClusterProxyEndpoint(ctx, "1")
	g.Expect(bizErr).ToNot(BeNil())
	g.Expect(bizErr.ErrCode()).To(Equal(errorcode.ErrCodeInvalidClusterID))
	g.Expect(proxyEndpoint).To(Equal(""))
}
