package cloudprovider

import (
	"testing"

	"github.com/onsi/gomega"
	grpcmetadata "google.golang.org/grpc/metadata"

	globalcommonv1 "github.com/tidbcloud/tidb-management-service/api/spec/global/common/v1"
	globalserverlessv1 "github.com/tidbcloud/tidb-management-service/api/spec/global/serverless/v1"
	"github.com/tidbcloud/tidb-management-service/serverless-global-service/app/register"
	"github.com/tidbcloud/tidb-management-service/utilities/grpc/metadata"
)

func TestListCloudProviders(t *testing.T) {
	g := gomega.NewWithT(t)
	ctx := grpcmetadata.NewIncomingContext(t.Context(), grpcmetadata.New(map[string]string{
		metadata.OrgIDHeaderKey:            "1",
		metadata.DefaultProjectIDHeaderKey: "1",
		metadata.ProjectListHeaderKey:      "1,2",
		metadata.UserIDHeaderKey:           "11",
	}))

	err := register.DiCall(func(svc globalserverlessv1.CloudProviderServiceServer) {
		resp, err := svc.List(ctx, &globalserverlessv1.CloudProviderServiceListRequest{})
		g.Expect(err).ShouldNot(gomega.HaveOccurred())
		g.Expect(resp.Total >= 1).Should(gomega.BeTrue())
		foundAWS := false
		for _, p := range resp.CloudProviders {
			if p.Id == globalcommonv1.CloudProvider_AWS {
				foundAWS = true
				g.Expect(p.DisplayName).Should(gomega.Equal("aws"))
				g.Expect(p.State).Should(gomega.Equal(globalcommonv1.CloudProvider_ACTIVE))
				g.Expect(p.IsPublic).Should(gomega.BeTrue())
			}
		}
		g.Expect(foundAWS).Should(gomega.BeTrue())
	})
	g.Expect(err).ShouldNot(gomega.HaveOccurred())
}

func TestRegisterCloudProvider(t *testing.T) {
	g := gomega.NewWithT(t)
	ctx := grpcmetadata.NewIncomingContext(t.Context(), grpcmetadata.New(map[string]string{
		metadata.OrgIDHeaderKey:            "1",
		metadata.DefaultProjectIDHeaderKey: "1",
		metadata.ProjectListHeaderKey:      "1,2",
		metadata.UserIDHeaderKey:           "11",
	}))

	err := register.DiCall(func(svc globalserverlessv1.CloudProviderServiceServer) {
		resp, err := svc.Register(ctx, &globalserverlessv1.CloudProviderServiceRegisterRequest{
			CloudProvider: &globalcommonv1.CloudProvider{
				Id:          globalcommonv1.CloudProvider_ALICLOUD,
				DisplayName: "alicloud",
				State:       globalcommonv1.CloudProvider_ACTIVE,
				IsPublic:    true,
			},
		})
		g.Expect(err).ShouldNot(gomega.HaveOccurred())
		g.Expect(resp.Id).Should(gomega.Equal(globalcommonv1.CloudProvider_ALICLOUD))
		g.Expect(resp.DisplayName).Should(gomega.Equal("alicloud"))
		g.Expect(resp.State).Should(gomega.Equal(globalcommonv1.CloudProvider_ACTIVE))
		g.Expect(resp.IsPublic).Should(gomega.BeTrue())
	})
	g.Expect(err).ShouldNot(gomega.HaveOccurred())
}

func TestRegisterCloudProvider_Private(t *testing.T) {
	g := gomega.NewWithT(t)
	ctx := grpcmetadata.NewIncomingContext(t.Context(), grpcmetadata.New(map[string]string{
		metadata.OrgIDHeaderKey:            "1",
		metadata.DefaultProjectIDHeaderKey: "1",
		metadata.ProjectListHeaderKey:      "1,2",
		metadata.UserIDHeaderKey:           "11",
	}))

	err := register.DiCall(func(svc globalserverlessv1.CloudProviderServiceServer) {
		resp, err := svc.Register(ctx, &globalserverlessv1.CloudProviderServiceRegisterRequest{
			CloudProvider: &globalcommonv1.CloudProvider{
				Id:          globalcommonv1.CloudProvider_GCP,
				DisplayName: "gcp",
				State:       globalcommonv1.CloudProvider_ACTIVE,
				IsPublic:    false,
			},
		})
		g.Expect(err).ShouldNot(gomega.HaveOccurred())
		g.Expect(resp.Id).Should(gomega.Equal(globalcommonv1.CloudProvider_GCP))
		g.Expect(resp.DisplayName).Should(gomega.Equal("gcp"))
		g.Expect(resp.State).Should(gomega.Equal(globalcommonv1.CloudProvider_ACTIVE))
		// allways be true, see infra/persistence/model/model.go Provider struct
		g.Expect(resp.IsPublic).Should(gomega.BeTrue()) // allways be true
	})
	g.Expect(err).ShouldNot(gomega.HaveOccurred())
}
