package byocvpcpeering

import (
	"context"
	"testing"

	"github.com/stretchr/testify/assert"
	"github.com/stretchr/testify/require"
	dataplanemanagerv1 "github.com/tidbcloud/cluster-service-ng/api/tidbcloud/dataplane-manager/v1"
	"go.uber.org/mock/gomock"

	globalcommonv1 "github.com/tidbcloud/tidb-management-service/api/spec/global/common/v1"
	globalngv1 "github.com/tidbcloud/tidb-management-service/api/spec/global/nextgen/v1"
	"github.com/tidbcloud/tidb-management-service/nextgen-global-service/domain/adapter/regionalserver/mock_regionalserver"
	"github.com/tidbcloud/tidb-management-service/nextgen-global-service/domain/entity"
	clusterrepo "github.com/tidbcloud/tidb-management-service/nextgen-global-service/domain/repository/cluster/mock_cluster"
	regionrepo "github.com/tidbcloud/tidb-management-service/nextgen-global-service/domain/repository/region/mock_region"
)

func TestListVpcPeerings(t *testing.T) {
	ctrl := gomock.NewController(t)
	clusterRepo := clusterrepo.NewMockRepo(ctrl)
	regionRepo := regionrepo.NewMockRepo(ctrl)
	regionalCli := mock_regionalserver.NewMockClient(ctrl)

	svc := &serviceImpl{
		clusterRepo: clusterRepo,
		regionRepo:  regionRepo,
		regionalCli: regionalCli,
	}

	cluster := &entity.Cluster{
		Cluster: &globalngv1.Cluster{
			ClusterId:   1001,
			DataplaneId: "dp-1",
		},
		RegionId: 2001,
	}
	region := &entity.Region{
		Region: &globalcommonv1.Region{
			Id:              globalcommonv1.Region_AWS_US_EAST_1,
			CloudProviderId: globalcommonv1.CloudProvider_AWS,
			State:           globalcommonv1.Region_ACTIVE,
			ServiceAddress:  "http://regional",
		},
		RegionID: 2001,
	}

	clusterRepo.EXPECT().Get(gomock.Any(), uint64(1001), false).Return(cluster, nil)
	regionRepo.EXPECT().Get(gomock.Any(), uint64(2001)).Return(region, nil)
	regionalCli.EXPECT().ListVpcPeerings(gomock.Any(), region, &dataplanemanagerv1.ListVpcPeeringsRequest{
		DataPlaneId: "dp-1",
	}).Return(&dataplanemanagerv1.ListVpcPeeringsResponse{
		VpcPeerings: []*dataplanemanagerv1.VpcPeering{
			{
				Id:                   "peering-1",
				SourceCidrBlock:      "10.0.0.0/16",
				DestinationCidrBlock: "192.168.0.0/16",
				Info: &dataplanemanagerv1.VpcPeering_Aws_{
					Aws: &dataplanemanagerv1.VpcPeering_Aws{
						SourceAccountId:        "tidb-account",
						SourceVpcId:            "tidb-vpc",
						SourceRegion:           "us-east-1",
						DestinationAccountId:   "customer-account",
						DestinationVpcId:       "customer-vpc",
						DestinationRegion:      "us-west-2",
						VpcPeeringConnectionId: "pcx-123",
					},
				},
				Status: dataplanemanagerv1.VpcPeering_ACTIVE,
			},
		},
	}, nil)

	resp, err := svc.ListVpcPeerings(context.Background(), &globalngv1.ListVpcPeeringsRequest{
		ClusterId: 1001,
	})
	require.Nil(t, err)
	require.Len(t, resp, 1)
	assert.Equal(t, uint64(1001), resp[0].GetClusterId())
	assert.Equal(t, "pcx-123", resp[0].GetId())
	assert.Equal(t, globalcommonv1.CloudProvider_AWS, resp[0].GetCloudProviderId())
	assert.Equal(t, globalcommonv1.Region_AWS_US_EAST_1, resp[0].GetTidbCloudRegionId())
	assert.Equal(t, globalcommonv1.Region_AWS_US_WEST_2, resp[0].GetCustomerRegionId())
	assert.Equal(t, "tidb-account", resp[0].GetTidbCloudAccountId())
	assert.Equal(t, "customer-account", resp[0].GetCustomerAccountId())
	assert.Equal(t, "tidb-vpc", resp[0].GetTidbCloudVpcId())
	assert.Equal(t, "customer-vpc", resp[0].GetCustomerVpcId())
	assert.Equal(t, "10.0.0.0/16", resp[0].GetTidbCloudVpcCidr())
	assert.Equal(t, "192.168.0.0/16", resp[0].GetCustomerVpcCidr())
}

func TestGetVpcPeering(t *testing.T) {
	ctrl := gomock.NewController(t)
	clusterRepo := clusterrepo.NewMockRepo(ctrl)
	regionRepo := regionrepo.NewMockRepo(ctrl)
	regionalCli := mock_regionalserver.NewMockClient(ctrl)

	svc := &serviceImpl{
		clusterRepo: clusterRepo,
		regionRepo:  regionRepo,
		regionalCli: regionalCli,
	}

	cluster := &entity.Cluster{
		Cluster: &globalngv1.Cluster{
			ClusterId:   1001,
			DataplaneId: "dp-1",
		},
		RegionId: 2001,
	}
	region := &entity.Region{
		Region: &globalcommonv1.Region{
			Id:              globalcommonv1.Region_AWS_US_EAST_1,
			CloudProviderId: globalcommonv1.CloudProvider_AWS,
			State:           globalcommonv1.Region_ACTIVE,
			ServiceAddress:  "http://regional",
		},
		RegionID: 2001,
	}

	clusterRepo.EXPECT().Get(gomock.Any(), uint64(1001), false).Return(cluster, nil)
	regionRepo.EXPECT().Get(gomock.Any(), uint64(2001)).Return(region, nil)
	regionalCli.EXPECT().GetVpcPeering(gomock.Any(), region, &dataplanemanagerv1.GetVpcPeeringRequest{
		DataPlaneId:  "dp-1",
		VpcPeeringId: "pcx-123",
	}).Return(&dataplanemanagerv1.VpcPeering{
		Id:                   "peering-1",
		SourceCidrBlock:      "10.0.0.0/16",
		DestinationCidrBlock: "192.168.0.0/16",
		Info: &dataplanemanagerv1.VpcPeering_Aws_{
			Aws: &dataplanemanagerv1.VpcPeering_Aws{
				SourceAccountId:        "tidb-account",
				SourceVpcId:            "tidb-vpc",
				SourceRegion:           "us-east-1",
				DestinationAccountId:   "customer-account",
				DestinationVpcId:       "customer-vpc",
				DestinationRegion:      "us-west-2",
				VpcPeeringConnectionId: "pcx-123",
			},
		},
		Status: dataplanemanagerv1.VpcPeering_ACTIVE,
	}, nil)

	resp, err := svc.GetVpcPeering(context.Background(), &globalngv1.GetVpcPeeringRequest{
		ClusterId:    1001,
		VpcPeeringId: "pcx-123",
	})
	require.Nil(t, err)
	require.NotNil(t, resp)
	assert.Equal(t, "pcx-123", resp.GetId())
	assert.Equal(t, globalcommonv1.Region_AWS_US_EAST_1, resp.GetTidbCloudRegionId())
	assert.Equal(t, globalcommonv1.Region_AWS_US_WEST_2, resp.GetCustomerRegionId())
}
