package controller

import (
	"context"
	"dataservices/internal/entity"
	"dataservices/internal/repository_ddb"
	"fmt"
	"strings"
	"sync"
	"testing"
	"time"

	config2 "dataservices/commons/config"
	"dataservices/dbhubsdk"

	"github.com/aws/aws-sdk-go-v2/config"
	"github.com/aws/aws-sdk-go-v2/service/ec2"
	"github.com/stretchr/testify/require"
	"github.com/tidbcloud/tiinf/monitor/tilog"
	"go.uber.org/zap"
)

func TestControlServerCreateDeletePrivateLink(t *testing.T) {
	ctx := context.Background()
	region := "us-west-2"
	vpcID := "vpc-085f890400d64cd0a"
	securityGroupId := "sg-028f70250d5c19a1c" // security group which allow all traffic.
	serviceName := "com.amazonaws.vpce.us-west-2.vpce-svc-041b2a655013a3be7"
	projectId := uint64(123)
	clusterId := uint64(456)
	err := InitControlServer(ctx, config2.AwsConfig{
		Region:  region,
		Session: "dev-role-session-name",
		RoleArn: "arn:aws:iam::385595570414:role/dev-staging-data-api-dynamodb-role",
	}, config2.VpcConfig{
		VpcId: vpcID,
		AzConfList: []config2.AzConfig{
			{
				"us-west-2a",
				"subnet-098de5356152db3c2",
			},
			{
				"us-west-2b",
				"subnet-0aea29f5add64487c",
			},
			{
				"us-west-2c",
				"subnet-07b011c7c70726009",
			},
			{
				"us-west-2d",
				"subnet-0289b81f1633629b6",
			},
		},
		SecurityGroupId: securityGroupId,
	})
	require.NoError(t, err)

	resp, err := GlobalControlServer.CreatePrivateLink(ctx, projectId, clusterId, serviceName)
	require.NoError(t, err)
	require.Equal(t, 200, resp.Code)
	require.NotEqual(t, "", resp.VpcEndpointId)
	fmt.Printf("endpoint-id: %v -------\n\n", resp.VpcEndpointId)

	clusterInfos, err := repository_ddb.QueryUserClusterInfo(ctx, GlobalControlServer.ddbCli, projectId, clusterId)
	require.NoError(t, err)
	require.NotNil(t, 1, len(clusterInfos))
	fmt.Printf("get cluster info %#v ------\n", clusterInfos[0])
	require.Equal(t, projectId, clusterInfos[0].ProjectId)
	require.Equal(t, clusterId, clusterInfos[0].ClusterId)
	require.Equal(t, true, clusterInfos[0].IsDedicate)
	require.Equal(t, resp.VpcEndpointId, clusterInfos[0].EndpointId)
	require.Equal(t, serviceName, clusterInfos[0].EndpointService)

	//go func() {
	// log ddb info loop
	//for {
	//	clusterInfos, err := ddb.ScanUserClusterInfo(ctx, GlobalControlServer.ddbCli)
	//	require.NoError(t, err)
	//	for i, info := range clusterInfos {
	//		fmt.Printf("scan cluster info %v %#v ------\n", i, info)
	//	}
	//	time.Sleep(time.Second * 20)
	//}
	//}()

	vpcEndpointId := resp.VpcEndpointId
	cli := GlobalControlServer.ec2Cli
	for {
		info := &VpcEndpointInfo{id: vpcEndpointId}
		err := info.DescribeVpcEndpoint(ctx, cli)
		require.NoError(t, err)
		if info.available && info.clusterInfo.PrivateDNS != "" {
			break
		}
		time.Sleep(time.Second)
	}

	fmt.Printf("\n\nstart sleep -------------------\n\n")
	time.Sleep(10 * time.Second)

	clusterInfos, err = repository_ddb.QueryUserClusterInfo(ctx, GlobalControlServer.ddbCli, projectId, clusterId)
	require.NoError(t, err)
	require.NotNil(t, 1, len(clusterInfos))
	fmt.Printf("get cluster info %#v ------\n", clusterInfos[0])
	require.Equal(t, projectId, clusterInfos[0].ProjectId)
	require.Equal(t, clusterId, clusterInfos[0].ClusterId)
	require.Equal(t, true, clusterInfos[0].IsDedicate)
	require.Equal(t, vpcEndpointId, clusterInfos[0].EndpointId)
	require.Equal(t, serviceName, clusterInfos[0].EndpointService)
	require.NotEqual(t, "", clusterInfos[0].PrivateDNS)

	time.Sleep(time.Minute * 5)
	fmt.Printf("\n\nafter sleep -------------------\n\n")

	resp2, err := GlobalControlServer.DeletePrivateLink(ctx, projectId, clusterId, false)
	require.NoError(t, err)
	require.Equal(t, 200, resp2.Code)

	time.Sleep(5 * time.Second)
	clusterInfos, err = repository_ddb.QueryUserClusterInfo(ctx, GlobalControlServer.ddbCli, projectId, clusterId)
	require.NoError(t, err)
	require.NotNil(t, 1, len(clusterInfos))
	fmt.Printf("get cluster info after delete private link %#v ------\n", clusterInfos[0])
	require.Equal(t, projectId, clusterInfos[0].ProjectId)
	require.Equal(t, clusterId, clusterInfos[0].ClusterId)
	require.Equal(t, true, clusterInfos[0].IsDedicate)
	require.Equal(t, "", clusterInfos[0].EndpointId)
	require.Equal(t, "", clusterInfos[0].EndpointService)
	require.Equal(t, "", clusterInfos[0].PrivateDNS)
}

func TestRestartControlServer(t *testing.T) {
	ctx := context.Background()
	region := "us-west-2"
	vpcID := "vpc-022286d89fa3b0761"
	securityGroupId := "sg-04b221d7432c40764" // security group which allow all traffic.
	serviceName := "com.amazonaws.vpce.us-west-2.vpce-svc-04dcfcda2f640bedf"
	projectId := uint64(123)
	clusterId := uint64(456)

	awsConf := config2.AwsConfig{
		Region:  region,
		Session: "dev-role-session-name",
		RoleArn: "arn:aws:iam::385595570414:role/dev-staging-data-api-dynamodb-role",
	}
	vpcConf := config2.VpcConfig{
		VpcId: vpcID,
		AzConfList: []config2.AzConfig{
			{
				"us-west-2a",
				"subnet-098de5356152db3c2",
			},
			{
				"us-west-2b",
				"subnet-0aea29f5add64487c",
			},
			{
				"us-west-2c",
				"subnet-07b011c7c70726009",
			},
			{
				"us-west-2d",
				"subnet-0289b81f1633629b6",
			},
		},
		SecurityGroupId: securityGroupId,
	}
	err := InitControlServer(ctx, awsConf, vpcConf)
	require.NoError(t, err)

	resp, err := GlobalControlServer.CreatePrivateLink(ctx, projectId, clusterId, serviceName)
	require.NoError(t, err)
	require.Equal(t, 200, resp.Code)
	require.NotEqual(t, "", resp.VpcEndpointId)
	fmt.Printf("endpoint-id: %v -------\n\n", resp.VpcEndpointId)
	vpcEndpointId := resp.VpcEndpointId

	clusterInfos, err := repository_ddb.QueryUserClusterInfo(ctx, GlobalControlServer.ddbCli, projectId, clusterId)
	require.NoError(t, err)
	require.NotNil(t, 1, len(clusterInfos))
	fmt.Printf("get cluster info %#v ------\n", clusterInfos[0])
	require.Equal(t, projectId, clusterInfos[0].ProjectId)
	require.Equal(t, clusterId, clusterInfos[0].ClusterId)
	require.Equal(t, true, clusterInfos[0].IsDedicate)
	require.Equal(t, resp.VpcEndpointId, clusterInfos[0].EndpointId)
	require.Equal(t, serviceName, clusterInfos[0].EndpointService)
	require.Equal(t, "", clusterInfos[0].PrivateDNS)

	// Close server
	GlobalControlServer.Close()
	time.Sleep(time.Second * 5)

	// Restart server
	err = InitControlServer(ctx, awsConf, vpcConf)
	require.NoError(t, err)

	cli := GlobalControlServer.ec2Cli
	for {
		info := &VpcEndpointInfo{id: vpcEndpointId}
		err := info.DescribeVpcEndpoint(ctx, cli)
		require.NoError(t, err)
		if info.available && info.clusterInfo.PrivateDNS != "" {
			break
		}
		time.Sleep(time.Second)
	}

	fmt.Printf("\n\nstart sleep -------------------\n\n")
	time.Sleep(10 * time.Second)

	clusterInfos, err = repository_ddb.QueryUserClusterInfo(ctx, GlobalControlServer.ddbCli, projectId, clusterId)
	require.NoError(t, err)
	require.NotNil(t, 1, len(clusterInfos))
	fmt.Printf("get cluster info %#v ------\n", clusterInfos[0])
	require.Equal(t, projectId, clusterInfos[0].ProjectId)
	require.Equal(t, clusterId, clusterInfos[0].ClusterId)
	require.Equal(t, true, clusterInfos[0].IsDedicate)
	require.Equal(t, vpcEndpointId, clusterInfos[0].EndpointId)
	require.Equal(t, serviceName, clusterInfos[0].EndpointService)
	require.NotEqual(t, "", clusterInfos[0].PrivateDNS)

	time.Sleep(time.Minute * 5)
	fmt.Printf("\n\nafter sleep -------------------\n\n")

	resp2, err := GlobalControlServer.DeletePrivateLink(ctx, projectId, clusterId, false)
	require.NoError(t, err)
	require.Equal(t, 200, resp2.Code)

	time.Sleep(5 * time.Second)
	clusterInfos, err = repository_ddb.QueryUserClusterInfo(ctx, GlobalControlServer.ddbCli, projectId, clusterId)
	require.NoError(t, err)
	require.NotNil(t, 1, len(clusterInfos))
	fmt.Printf("get cluster info after delete private link %#v ------\n", clusterInfos[0])
	require.Equal(t, projectId, clusterInfos[0].ProjectId)
	require.Equal(t, clusterId, clusterInfos[0].ClusterId)
	require.Equal(t, true, clusterInfos[0].IsDedicate)
	require.Equal(t, "", clusterInfos[0].EndpointId)
	require.Equal(t, "", clusterInfos[0].EndpointService)
	require.Equal(t, "", clusterInfos[0].PrivateDNS)
}

func TestControlDeletePrivateLink(t *testing.T) {
	ctx := context.Background()
	region := "us-west-2"
	vpcID := "vpc-022286d89fa3b0761"
	securityGroupId := "sg-04b221d7432c40764" // security group which allow all traffic.
	//serviceName := "com.amazonaws.vpce.us-west-2.vpce-svc-04dcfcda2f640bedf"
	projectId := uint64(123)
	clusterId := uint64(456)
	err := InitControlServer(ctx, config2.AwsConfig{
		Region:  region,
		Session: "dev-role-session-name",
		RoleArn: "arn:aws:iam::385595570414:role/dev-staging-data-api-dynamodb-role",
	}, config2.VpcConfig{
		VpcId: vpcID,
		AzConfList: []config2.AzConfig{
			{
				"us-west-2a",
				"subnet-098de5356152db3c2",
			},
			{
				"us-west-2b",
				"subnet-0aea29f5add64487c",
			},
			{
				"us-west-2c",
				"subnet-07b011c7c70726009",
			},
			{
				"us-west-2d",
				"subnet-0289b81f1633629b6",
			},
		},
		SecurityGroupId: securityGroupId,
	})
	require.NoError(t, err)

	go func() {
		// log ddb info loop
		for {
			clusterInfos, err := repository_ddb.ScanUserClusterInfo(ctx, GlobalControlServer.ddbCli)
			require.NoError(t, err)
			for i, info := range clusterInfos {
				fmt.Printf("scan cluster info %v %#v ------\n", i, info)
			}
			time.Sleep(time.Second * 20)
		}
	}()

	resp2, err := GlobalControlServer.DeletePrivateLink(ctx, projectId, clusterId, false)
	require.NoError(t, err)
	require.Equal(t, 200, resp2.Code)

	time.Sleep(10 * time.Second)
	clusterInfos, err := repository_ddb.QueryUserClusterInfo(ctx, GlobalControlServer.ddbCli, projectId, clusterId)
	require.NoError(t, err)
	require.NotNil(t, 1, len(clusterInfos))
	fmt.Printf("get cluster info after delete private link %#v ------\n", clusterInfos[0])
	require.Equal(t, projectId, clusterInfos[0].ProjectId)
	require.Equal(t, clusterId, clusterInfos[0].ClusterId)
	require.Equal(t, true, clusterInfos[0].IsDedicate)
	require.Equal(t, "", clusterInfos[0].EndpointService)
	require.Equal(t, "", clusterInfos[0].PrivateDNS)
}

func TestControlServerToken(t *testing.T) {
	ctx := context.Background()
	region := "us-west-2"
	vpcID := "vpc-085f890400d64cd0a"
	securityGroupId := "sg-028f70250d5c19a1c" // security group which allow all traffic.
	err := InitControlServer(ctx, config2.AwsConfig{
		Region:  region,
		Session: "dev-role-session-name",
		RoleArn: "arn:aws:iam::385595570414:role/dev-staging-data-api-dynamodb-role",
	}, config2.VpcConfig{
		VpcId: vpcID,
		AzConfList: []config2.AzConfig{
			{
				"us-west-2a",
				"subnet-098de5356152db3c2",
			},
			{
				"us-west-2b",
				"subnet-0aea29f5add64487c",
			},
			{
				"us-west-2c",
				"subnet-07b011c7c70726009",
			},
			{
				"us-west-2d",
				"subnet-0289b81f1633629b6",
			},
		},
		SecurityGroupId: securityGroupId,
	})
	require.NoError(t, err)

	token1 := GlobalControlServer.GetToken(123, 456)
	require.NotNil(t, token1)
	token2 := GlobalControlServer.GetToken(123, 456)
	require.Nil(t, token2)
	token3 := GlobalControlServer.GetToken(123, 4567)
	require.NotNil(t, token3)
	token4 := GlobalControlServer.GetToken(123, 4567)
	require.Nil(t, token4)
	require.Equal(t, 2, len(GlobalControlServer.concurrentMap))

	GlobalControlServer.ReleaseToken(token1)
	require.Equal(t, 1, len(GlobalControlServer.concurrentMap))
	token2 = GlobalControlServer.GetToken(123, 456)
	require.NotNil(t, token2)
	token1 = GlobalControlServer.GetToken(123, 456)
	require.Nil(t, token1)
	GlobalControlServer.ReleaseToken(token2)

	GlobalControlServer.ReleaseToken(token3)
	require.Equal(t, 0, len(GlobalControlServer.concurrentMap))
	token4 = GlobalControlServer.GetToken(123, 4567)
	require.NotNil(t, token4)
	require.Equal(t, 1, len(GlobalControlServer.concurrentMap))
	GlobalControlServer.ReleaseToken(token4)
	require.Equal(t, 0, len(GlobalControlServer.concurrentMap))
}

func TestControlServerConcurrentCreatePrivateLink(t *testing.T) {
	ctx := context.Background()
	region := "us-west-2"
	vpcID := "vpc-085f890400d64cd0a"
	securityGroupId := "sg-028f70250d5c19a1c" // security group which allow all traffic.
	serviceName := "com.amazonaws.vpce.us-west-2.vpce-svc-06b24b842f470f046"
	projectId := uint64(123)
	clusterId := uint64(456789)
	err := InitControlServer(ctx, config2.AwsConfig{
		Region:  region,
		Session: "dev-role-session-name",
		RoleArn: "arn:aws:iam::385595570414:role/dev-staging-data-api-dynamodb-role",
	}, config2.VpcConfig{
		VpcId: vpcID,
		AzConfList: []config2.AzConfig{
			{
				"us-west-2a",
				"subnet-098de5356152db3c2",
			},
			{
				"us-west-2b",
				"subnet-0aea29f5add64487c",
			},
			{
				"us-west-2c",
				"subnet-07b011c7c70726009",
			},
			{
				"us-west-2d",
				"subnet-0289b81f1633629b6",
			},
		},
		SecurityGroupId: securityGroupId,
	})
	require.NoError(t, err)

	clusterInfo := entity.UserClusterInfo{
		ProjectId:       projectId,
		ClusterId:       clusterId,
		IsDedicate:      true,
		EndpointService: "abcde",
		EndpointId:      "xyz",
		PrivateDNS:      "dns",
	}
	err = repository_ddb.PutUserClusterInfo(ctx, GlobalControlServer.ddbCli, &clusterInfo)
	require.NoError(t, err)

	var wg sync.WaitGroup
	succNum := 0
	for i := 0; i < 20; i++ {
		wg.Add(1)
		go func() {
			defer wg.Done()
			resp, err := GlobalControlServer.CreatePrivateLink(ctx, projectId, clusterId, serviceName)
			if err == nil {
				succNum++
				require.Equal(t, clusterInfo.EndpointId, resp.VpcEndpointId)
				require.Equal(t, clusterInfo.PrivateDNS, resp.PrivateDNS)
			} else {
				require.Equal(t, 400, err.HTTPCode())
				require.Equal(t, "already in creating", err.ErrMsg())
			}
		}()
	}
	wg.Wait()
	// only one get token then try to create private link.
	require.Equal(t, 1, succNum)
}

func TestControlServerGetEndpointServicesAzSubnet(t *testing.T) {
	ctx := context.Background()
	region := "us-west-2"
	vpcID := "vpc-085f890400d64cd0a"
	securityGroupId := "sg-028f70250d5c19a1c" // security group which allow all traffic.
	serviceName := "com.amazonaws.vpce.us-west-2.vpce-svc-041b2a655013a3be7"
	err := InitControlServer(ctx, config2.AwsConfig{
		Region:  region,
		Session: "dev-role-session-name",
		RoleArn: "arn:aws:iam::385595570414:role/dev-staging-data-api-dynamodb-role",
	}, config2.VpcConfig{
		VpcId: vpcID,
		AzConfList: []config2.AzConfig{
			{
				"us-west-2a",
				"subnet-098de5356152db3c2",
			},
			{
				"us-west-2b",
				"subnet-0aea29f5add64487c",
			},
			{
				"us-west-2c",
				"subnet-07b011c7c70726009",
			},
			{
				"us-west-2d",
				"subnet-0289b81f1633629b6",
			},
		},
		SecurityGroupId: securityGroupId,
	})
	require.NoError(t, err)

	cli := GlobalControlServer.ec2Cli
	subnetIds, err := GlobalControlServer.GetEndpointServicesAzSubnet(ctx, cli, serviceName)
	require.NoError(t, err)
	require.NotNil(t, subnetIds)
	fmt.Printf("service subnet ids: %v --\n\n", subnetIds)
}

func TestCreatePrivateLink(t *testing.T) {
	ctx := context.Background()
	region := "us-west-2"
	vpcID := "vpc-085f890400d64cd0a"
	securityGroupId := "sg-028f70250d5c19a1c" // security group which allow all traffic.
	serviceName := "com.amazonaws.vpce.us-west-2.vpce-svc-06b24b842f470f046"

	cli, err := NewClient(ctx, region)
	require.NoError(t, err)

	describeSubnetsOutput, err := DescribeSubnets(ctx, cli, vpcID)
	require.NoError(t, err)
	subnetPrivateID := ""
	for _, subnet := range describeSubnetsOutput.Subnets {
		fmt.Printf("%v     %v    %v      %v     %v \n\n", *subnet.SubnetId, subnet.Tags, *subnet.SubnetArn, *subnet.EnableDns64, *subnet.VpcId)
		isPrivite := false
		for _, tag := range subnet.Tags {
			fmt.Printf("%v     %v \n\n", *tag.Key, *tag.Value)
			isPrivite = strings.Contains(*tag.Value, "private")
		}
		if isPrivite {
			subnetPrivateID = *subnet.SubnetId
			fmt.Printf("subnetPriviteIDs     %v \n\n", subnetPrivateID)
		}
	}
	subnetIds := []string{"subnet-098de5356152db3c2", "subnet-0aea29f5add64487c", "subnet-07b011c7c70726009"}

	createVpcEndpointOutput, err := CreateVpcEndpoint(ctx, cli, 1, vpcID, securityGroupId, serviceName, subnetIds)
	require.NoError(t, err)
	require.NotNil(t, createVpcEndpointOutput)
	printField("createVpcEndpointOutput.ClientToken", createVpcEndpointOutput.ClientToken)
	vpcEndpointID := "unknown"
	if createVpcEndpointOutput.VpcEndpoint != nil {
		vpcEndpointID = *createVpcEndpointOutput.VpcEndpoint.VpcEndpointId
		printField("createVpcEndpointOutput.VpcEndpoint.VpcEndpointId", createVpcEndpointOutput.VpcEndpoint.VpcEndpointId)
		printField("createVpcEndpointOutput.VpcEndpoint.VpcId", createVpcEndpointOutput.VpcEndpoint.VpcId)
		fmt.Printf("%v: %v \n", "createVpcEndpointOutput.VpcEndpoint.VpcEndpointType.Values()", createVpcEndpointOutput.VpcEndpoint.VpcEndpointType.Values())
		fmt.Printf("%v: %v \n", "createVpcEndpointOutput.VpcEndpoint.NetworkInterfaceIds", createVpcEndpointOutput.VpcEndpoint.NetworkInterfaceIds)
		fmt.Printf("%v: %v \n", "createVpcEndpointOutput.VpcEndpoint.PrivateDnsEnabled", *createVpcEndpointOutput.VpcEndpoint.PrivateDnsEnabled)
		fmt.Printf("%v: %v \n", "createVpcEndpointOutput.VpcEndpoint.ServiceName", *createVpcEndpointOutput.VpcEndpoint.ServiceName)
	}

	err = WaitPrivateLinkAvailable(ctx, cli, vpcEndpointID, time.Second*600)
	require.NoError(t, err)

	err = EnablePrivateLinkDNS(ctx, cli, vpcEndpointID)
	require.NoError(t, err)

	privateDNSName, err := GetPrivateLinkDNS(ctx, cli, vpcEndpointID)
	fmt.Printf("GetPrivateLinkDNS privateDNSName: %v \n\n", privateDNSName)
	require.NoError(t, err)
	require.NotEqual(t, "", privateDNSName)

	err = WaitPrivateLinkAvailable(ctx, cli, vpcEndpointID, time.Second*600)
	require.NoError(t, err)
}

func TestDescribeVpcEndpointServices(t *testing.T) {
	ctx := context.Background()
	region := "us-west-2"
	vpcId := "vpc-085f890400d64cd0a"
	//securityGroupId := "sg-028f70250d5c19a1c" // security group which allow all traffic.
	serviceName := "com.amazonaws.vpce.us-west-2.vpce-svc-041b2a655013a3be7"

	cli, err := NewClient(ctx, region)
	require.NoError(t, err)

	resp, err := cli.DescribeVpcEndpointServices(ctx, &ec2.DescribeVpcEndpointServicesInput{
		ServiceNames: []string{serviceName},
	})
	require.NoError(t, err)
	require.Equal(t, 1, len(resp.ServiceDetails))
	fmt.Printf("AvailabilityZones: %v --------\n\n", resp.ServiceDetails[0].AvailabilityZones)

	describeSubnetsOutput, err := DescribeSubnets(ctx, cli, vpcId)
	require.NoError(t, err)
	for _, subnet := range describeSubnetsOutput.Subnets {
		fmt.Printf("\nsubnet: %v     %v\n", *subnet.SubnetId, *subnet.AvailabilityZone)
		for _, tag := range subnet.Tags {
			fmt.Printf("%v     %v \n", *tag.Key, *tag.Value)
		}
	}
}

func TestDescribeVpcEndpoint(t *testing.T) {
	ctx := context.Background()
	region := "us-west-2"
	endpointId := "vpce-0194e9f252cbf83de"

	cli, err := NewClient(ctx, region)
	require.NoError(t, err)

	resp, err := cli.DescribeVpcEndpoints(ctx, &ec2.DescribeVpcEndpointsInput{
		VpcEndpointIds: []string{endpointId},
	})
	require.NoError(t, err)
	require.Equal(t, 1, len(resp.VpcEndpoints))
	for _, e := range resp.VpcEndpoints {
		state := strings.ToLower(fmt.Sprintf("%v", e.State))
		for _, dns := range e.DnsEntries {
			fmt.Printf("%v %v %v -----\n\n", state, *dns.DnsName, *dns.HostedZoneId)
		}
	}
}

func TestDeletePrivateLink(t *testing.T) {
	ctx := context.Background()
	region := "us-west-2"
	endpointId := ""

	cli, err := NewClient(ctx, region)
	require.NoError(t, err)

	resp, err := DeleteVpcEndpoint(ctx, cli, endpointId)
	require.NoError(t, err)
	for _, v := range resp.Unsuccessful {
		if v.ResourceId != nil {
			fmt.Printf("deleteVpcEndpointsOutput.ResourceId: %v\n", *v.ResourceId)
		}
		if v.Error != nil {
			fmt.Printf("deleteVpcEndpointsOutput.Error: %v\n", *v.Error)
		}
	}
	fmt.Printf("deleteVpcEndpointsOutput.ResultMetadata: %v\n", resp.ResultMetadata)

}

func TestCS0(t *testing.T) {
	err := dbhubsdk.InitSdk(
		"/Users/cs/.kube/config",
		"nightly-ms",
		"/Users/cs/.infra-api/infra-api-kubeconfig.yaml")
	require.NoError(t, err)
	ctx := context.Background()
	dedicateCls, err := dbhubsdk.Serverless.InfraApi.GetCluster(ctx, 43563, 2578952)
	require.NoError(t, err)
	//fmt.Printf("%#v\n", dedicateCls)
	require.Equal(t, "eks", dedicateCls.GetProviderType())
	require.Equal(t, "eks-us-west-2", dedicateCls.Spec.NetworkName)
	fmt.Printf("dedicateCls.Spec.SqlEndpoints.Public.Enabled: %v \n", *dedicateCls.Spec.SqlEndpoints.Public.Enabled)
	fmt.Printf("dedicateCls.Spec.SqlEndpoints.Public.Port: %v \n", *dedicateCls.Spec.SqlEndpoints.Public.Port)
	fmt.Printf("dedicateCls.Spec.SqlEndpoints.Public.LoadBalancerSourceRanges: %v \n", dedicateCls.Spec.SqlEndpoints.Public.LoadBalancerSourceRanges)
	//fmt.Printf("dedicateCls.Spec.SqlEndpoints.Private: %#v \n", dedicateCls.Spec.SqlEndpoints.Private)
	if dedicateCls.Spec.SqlEndpoints.Private != nil {
		fmt.Printf("dedicateCls.Spec.SqlEndpoints.Private.Enabled: %v \n", *dedicateCls.Spec.SqlEndpoints.Private.Enabled)
		fmt.Printf("dedicateCls.Spec.SqlEndpoints.Private.Port: %v \n", *dedicateCls.Spec.SqlEndpoints.Private.Port)
		fmt.Printf("dedicateCls.Spec.SqlEndpoints.Private.LoadBalancerSourceRanges: %v \n", dedicateCls.Spec.SqlEndpoints.Private.LoadBalancerSourceRanges)
	}

	fmt.Printf("\n\n----------------------------\n\n")

	serverlessCls, err := dbhubsdk.Serverless.InfraApi.GetCluster(ctx, 43563, 270017)
	require.NoError(t, err)
	//fmt.Printf("%#v\n", serverlessCls)
	require.Equal(t, "aws-free-tier", serverlessCls.GetProviderType())
	require.Equal(t, "aws-free-tier-us-east-1", serverlessCls.Spec.NetworkName)
	fmt.Printf("serverlessCls.Spec.SqlEndpoints.Public.Enabled: %v \n", *serverlessCls.Spec.SqlEndpoints.Public.Enabled)
	fmt.Printf("serverlessCls.Spec.SqlEndpoints.Public.Port: %v \n", *serverlessCls.Spec.SqlEndpoints.Public.Port)
	fmt.Printf("serverlessCls.Spec.SqlEndpoints.Public.LoadBalancerSourceRanges: %v \n", serverlessCls.Spec.SqlEndpoints.Public.LoadBalancerSourceRanges)
	if serverlessCls.Spec.SqlEndpoints.Private != nil {
		fmt.Printf("serverlessCls.Spec.SqlEndpoints.Private.Enabled: %v \n", *serverlessCls.Spec.SqlEndpoints.Private.Enabled)
		fmt.Printf("serverlessCls.Spec.SqlEndpoints.Private.Port: %v \n", *serverlessCls.Spec.SqlEndpoints.Private.Port)
		fmt.Printf("serverlessCls.Spec.SqlEndpoints.Private.LoadBalancerSourceRanges: %v \n", serverlessCls.Spec.SqlEndpoints.Private.LoadBalancerSourceRanges)
	}
}

func NewClient(ctx context.Context, region string) (*ec2.Client, error) {
	cfg, err := config.LoadDefaultConfig(context.TODO(),
		config.WithRegion(region),
	)
	if err != nil {
		tilog.Error(ctx, "New aws ec2 client failed.", zap.Error(err))
		return nil, err
	}
	return ec2.NewFromConfig(cfg), nil
}

func printField(name string, value *string) {
	if value == nil {
		fmt.Printf("%v: %v \n", name, nil)
	} else {
		fmt.Printf("%v: %v \n", name, *value)
	}
}
