package ack

import (
	"context"
	"fmt"
	"testing"
	"time"

	alivpcv1alpha1 "github.com/crossplane-contrib/provider-upjet-alibabacloud/apis/vpc/v1alpha1"
	xpv1 "github.com/crossplane/crossplane-runtime/apis/common/v1"
	"github.com/stretchr/testify/assert"
	"github.com/stretchr/testify/require"
	"github.com/tidbcloud/infra-provider/regional-server/api/v1alpha1"
	"github.com/tidbcloud/infra-provider/regional-server/pkg/consts"
	"github.com/tidbcloud/infra-provider/regional-server/pkg/controllers"
	"github.com/tidbcloud/infra-provider/regional-server/pkg/controllers/vpc/task"
	"github.com/tidbcloud/infra-provider/regional-server/pkg/k8s"
	"github.com/tidbcloud/infra-provider/regional-server/pkg/namer"
	"github.com/tidbcloud/infra-provider/regional-server/pkg/util"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/utils/ptr"
	"sigs.k8s.io/controller-runtime/pkg/client"
)

func fakeSubnetTask(t *testing.T) (*subnetTask, *vpcTask) {
	c := fakeTaskContext(t)
	vt := newFakeVPC(c)
	st := newFakeSubnet(c)
	return st, vt
}

func newFakeSubnet(ctx *task.Context) *subnetTask {
	return &subnetTask{
		BaseTask: &task.BaseTask{
			Context: ctx,
		},
	}
}

func markVswitchesReady(t *testing.T, subnetTask *subnetTask, subnets []*alivpcv1alpha1.Vswitch) {
	t.Helper()
	for _, subnet := range subnets {
		subnet.Status.SetConditions(xpv1.Available())
		subnet.Status.AtProvider.ID = ptr.To(subnet.Name + "-id")
		subnet.Status.AtProvider.ZoneID = subnet.Spec.ForProvider.ZoneID
		subnet.Status.AtProvider.CidrBlock = subnet.Spec.ForProvider.CidrBlock
		err := subnetTask.Local.Status().Update(context.Background(), subnet)
		assert.NoError(t, err)
	}
}

func TestSubnet_createSubnet(t *testing.T) {
	subnetTask, vpcTask := fakeSubnetTask(t)
	result := vpcTask.Create(context.Background())
	assert.True(t, result.IsDoneState())
	subnetTask.VPC.Status.VPC.Name = vpcTask.getVPCName()
	aliyunVPC := &alivpcv1alpha1.VPC{
		ObjectMeta: metav1.ObjectMeta{
			Name: vpcTask.getVPCName(),
		},
	}
	err := vpcTask.Local.Get(context.Background(), client.ObjectKeyFromObject(aliyunVPC), aliyunVPC)
	assert.NoError(t, err)

	tags := controllers.ConvertToCloudTags(vpcTask.VPC.Labels, consts.ProviderTypeACK)
	cidr := "10.16.0.0/21"
	zone := "ap-southeast-1a"
	subnetName := namer.NodesSubnetName(aliyunVPC.Name, zone)
	subnet, err := subnetTask.createSubnet(context.Background(), subnetName, zone, cidr, aliyunVPC, tags)
	assert.NoError(t, err)
	assert.Equal(t, subnetName, subnet.Name)
	assert.Equal(t, alivpcv1alpha1.VswitchSpec{
		ForProvider: alivpcv1alpha1.VswitchParameters{
			VswitchName: ptr.To(subnetName),
			Region:      ptr.To("ap-southeast-1"),
			ZoneID:      ptr.To("ap-southeast-1a"),
			CidrBlock:   ptr.To("10.16.0.0/21"),
			Tags:        util.ToMapPointer(tags),
			VPCIDRef: &xpv1.Reference{
				Name: aliyunVPC.Name,
			},
		},
		ResourceSpec: xpv1.ResourceSpec{
			ProviderConfigReference: &xpv1.Reference{Name: subnetTask.ProviderConfigName()},
			ManagementPolicies:      controllers.GetResourceManagementPolicies(),
		},
	}, subnet.Spec)
}

func TestSubnet_Create(t *testing.T) {
	subnetTask, vpcTask := fakeSubnetTask(t)
	result := vpcTask.Create(context.Background())
	assert.True(t, result.IsDoneState())
	subnetTask.VPC.Status.VPC.Name = vpcTask.getVPCName()
	aliyunVPC := &alivpcv1alpha1.VPC{
		ObjectMeta: metav1.ObjectMeta{
			Name: vpcTask.getVPCName(),
		},
	}
	err := vpcTask.Local.Get(context.Background(), client.ObjectKeyFromObject(aliyunVPC), aliyunVPC)
	assert.NoError(t, err)

	subnetTask.Create(context.Background())
	subnetList := &alivpcv1alpha1.VswitchList{}
	err = subnetTask.Local.List(context.Background(), subnetList)
	assert.NoError(t, err)
	assert.Equal(t, 9, len(subnetList.Items))

	workers, public, private, err := util.GetAliyunSubnetCIDRs(vpcTask.VPC.Spec.CIDR, len(subnetTask.GetZones()))
	if assert.Equal(t, len(workers), len(subnetTask.nodeSubnets)) {
		for i, nodeCidr := range workers {
			assert.Equal(t, nodeCidr, *subnetTask.nodeSubnets[i].Spec.ForProvider.CidrBlock)
		}
	}
	if assert.Equal(t, len(public), len(subnetTask.publicSubnets)) {
		for i, publicCidr := range public {
			assert.Equal(t, publicCidr, *subnetTask.publicSubnets[i].Spec.ForProvider.CidrBlock)
		}
	}
	if assert.Equal(t, len(private), len(subnetTask.privateSubnets)) {
		for i, privateCidr := range private {
			assert.Equal(t, privateCidr, *subnetTask.privateSubnets[i].Spec.ForProvider.CidrBlock)
		}
	}
}

func TestSubnet_CreateOptimized(t *testing.T) {
	subnetTask, vpcTask := fakeSubnetTask(t)
	subnetTask.VPC.Spec.NodeZones = []string{"ap-southeast-1a"}
	result := vpcTask.Create(context.Background())
	assert.True(t, result.IsDoneState())
	subnetTask.VPC.Status.VPC.Name = vpcTask.getVPCName()
	aliyunVPC := &alivpcv1alpha1.VPC{
		ObjectMeta: metav1.ObjectMeta{
			Name: vpcTask.getVPCName(),
		},
	}
	err := vpcTask.Local.Get(context.Background(), client.ObjectKeyFromObject(aliyunVPC), aliyunVPC)
	assert.NoError(t, err)

	result = subnetTask.Create(context.Background())
	assert.True(t, result.IsDoneState())
	subnetList := &alivpcv1alpha1.VswitchList{}
	err = subnetTask.Local.List(context.Background(), subnetList)
	assert.NoError(t, err)
	assert.Len(t, subnetList.Items, 5)

	vpcName := subnetTask.getVPCName()
	zones := subnetTask.GetZones()
	workers, public, private, err := util.GetAliyunSubnetCIDRsOptimized(
		subnetTask.VPC.Spec.CIDR,
		subnetTask.VPC.Spec.NodeZones,
		zones,
	)
	assert.NoError(t, err)

	assert.Len(t, subnetTask.nodeSubnets, 1)
	assert.Len(t, public, 2)
	assert.Len(t, private, 2)
	assert.Len(t, subnetTask.publicSubnets, len(public))
	assert.Len(t, subnetTask.privateSubnets, len(private))

	for _, nodeSubnet := range subnetTask.nodeSubnets {
		zone := *nodeSubnet.Spec.ForProvider.ZoneID
		assert.Equal(t, namer.NodesSubnetName(vpcName, zone), nodeSubnet.Name)
		assert.Equal(t, workers[zone], *nodeSubnet.Spec.ForProvider.CidrBlock)
	}
	for _, publicSubnet := range subnetTask.publicSubnets {
		zone := *publicSubnet.Spec.ForProvider.ZoneID
		assert.Equal(t, namer.PublicSubnetName(vpcName, zone), publicSubnet.Name)
		assert.Equal(t, public[zone], *publicSubnet.Spec.ForProvider.CidrBlock)
	}
	for _, privateSubnet := range subnetTask.privateSubnets {
		zone := *privateSubnet.Spec.ForProvider.ZoneID
		assert.Equal(t, namer.PrivateSubnetName(vpcName, zone), privateSubnet.Name)
		assert.Equal(t, private[zone], *privateSubnet.Spec.ForProvider.CidrBlock)
	}
}

func TestSubnetCreateOptimizedWithPrivateLinkEndpointSubnets(t *testing.T) {
	subnetTask, vpcTask := fakeSubnetTask(t)
	subnetTask.VPC.Spec.CIDR = "10.0.0.0/18"
	subnetTask.VPC.Spec.NodeZones = []string{"ap-southeast-1a"}
	subnetTask.VPC.Spec.PrivateLinkEndpointZones = []string{
		"ap-southeast-1d",
		"ap-southeast-1b",
		"ap-southeast-1a",
		"ap-southeast-1c",
	}
	result := vpcTask.Create(context.Background())
	require.True(t, result.IsDoneState())
	subnetTask.VPC.Status.VPC.Name = vpcTask.getVPCName()

	result = subnetTask.Create(context.Background())
	require.True(t, result.IsDoneState())

	endpointCIDRs, err := util.GetAliyunPrivateLinkEndpointSubnetCIDRs(
		subnetTask.VPC.Spec.CIDR,
		subnetTask.VPC.Spec.PrivateLinkEndpointZones,
	)
	require.NoError(t, err)
	require.Len(t, subnetTask.endpointSubnets, 4)
	for _, endpointSubnet := range subnetTask.endpointSubnets {
		zone := *endpointSubnet.Spec.ForProvider.ZoneID
		assert.Equal(t, namer.PrivateLinkEndpointSubnetName(subnetTask.getVPCName(), zone), endpointSubnet.Name)
		assert.Equal(t, endpointCIDRs[zone], *endpointSubnet.Spec.ForProvider.CidrBlock)
	}

	markVswitchesReady(t, subnetTask, subnetTask.nodeSubnets)
	markVswitchesReady(t, subnetTask, subnetTask.publicSubnets)
	markVswitchesReady(t, subnetTask, subnetTask.privateSubnets)
	markVswitchesReady(t, subnetTask, subnetTask.endpointSubnets)
	result = subnetTask.PostCreate(context.Background())
	require.True(t, result.IsDoneState())
	require.Len(t, subnetTask.VPC.Status.PrivateLinkEndpointSubnets, 4)
	for _, subnet := range subnetTask.VPC.Status.PrivateLinkEndpointSubnets {
		assert.Equal(t, endpointCIDRs[subnet.AvailabilityZoneID], subnet.CIDRBlock)
	}
}

func TestSubnetCreateOptimizedWithPrivateLinkEndpointZonesSkipsMultiNodeZones(t *testing.T) {
	subnetTask, vpcTask := fakeSubnetTask(t)
	subnetTask.VPC.Spec.CIDR = "10.0.0.0/18"
	subnetTask.VPC.Spec.NodeZones = []string{"ap-southeast-1a", "ap-southeast-1b"}
	subnetTask.VPC.Spec.PrivateLinkEndpointZones = []string{
		"ap-southeast-1a",
		"ap-southeast-1b",
		"ap-southeast-1c",
	}
	result := vpcTask.Create(context.Background())
	require.True(t, result.IsDoneState())
	subnetTask.VPC.Status.VPC.Name = vpcTask.getVPCName()

	result = subnetTask.Create(context.Background())
	require.True(t, result.IsDoneState())

	assert.Len(t, subnetTask.nodeSubnets, 2)
	assert.Len(t, subnetTask.publicSubnets, 2)
	assert.Len(t, subnetTask.privateSubnets, 2)
	assert.Empty(t, subnetTask.endpointSubnets)
}

func TestSubnetCreatePrivateLinkEndpointSubnetsPreflightsCIDRCapacity(t *testing.T) {
	subnetTask, vpcTask := fakeSubnetTask(t)
	subnetTask.VPC.Spec.CIDR = "10.0.0.0/20"
	subnetTask.VPC.Spec.NodeZones = []string{"ap-southeast-1a"}
	for i := range 17 {
		subnetTask.VPC.Spec.PrivateLinkEndpointZones = append(
			subnetTask.VPC.Spec.PrivateLinkEndpointZones,
			fmt.Sprintf("ap-southeast-1-zone-%02d", i),
		)
	}
	result := vpcTask.Create(context.Background())
	require.True(t, result.IsDoneState())
	subnetTask.VPC.Status.VPC.Name = vpcTask.getVPCName()

	result = subnetTask.Create(context.Background())
	require.Error(t, result.Error())
	assert.ErrorContains(t, result.Error(), "can fit 16 /26 endpoint subnets")

	subnetList := &alivpcv1alpha1.VswitchList{}
	require.NoError(t, subnetTask.Local.List(context.Background(), subnetList))
	assert.Empty(t, subnetList.Items)
}

func TestSubnetCreatePrivateLinkEndpointSubnetsRequiresOptimizedCIDR(t *testing.T) {
	subnetTask, vpcTask := fakeSubnetTask(t)
	subnetTask.VPC.Spec.CIDR = "10.0.0.0/18"
	subnetTask.VPC.Spec.Zones = []string{"ap-southeast-1a"}
	subnetTask.VPC.Spec.NodeZones = []string{"ap-southeast-1a"}
	subnetTask.VPC.Spec.PrivateLinkEndpointZones = []string{"ap-southeast-1a"}
	result := vpcTask.Create(context.Background())
	require.True(t, result.IsDoneState())
	subnetTask.VPC.Status.VPC.Name = vpcTask.getVPCName()

	result = subnetTask.Create(context.Background())
	require.Error(t, result.Error())
	assert.ErrorContains(t, result.Error(), "vpc.spec.privateLinkEndpointZones requires optimized CIDR layout")
	assert.Equal(t, 30*time.Second, k8s.ShouldRequeue(result.RawError()).RequeueAfter)
}

func TestSubnet_CreateOptimizedSortsNodeSubnets(t *testing.T) {
	subnetTask, vpcTask := fakeSubnetTask(t)
	subnetTask.VPC.Spec.NodeZones = []string{"ap-southeast-1b", "ap-southeast-1a"}
	result := vpcTask.Create(context.Background())
	assert.True(t, result.IsDoneState())
	subnetTask.VPC.Status.VPC.Name = vpcTask.getVPCName()

	result = subnetTask.Create(context.Background())
	assert.True(t, result.IsDoneState())

	require.Len(t, subnetTask.nodeSubnets, 2)
	assert.Equal(t, "ap-southeast-1a", *subnetTask.nodeSubnets[0].Spec.ForProvider.ZoneID)
	assert.Equal(t, "ap-southeast-1b", *subnetTask.nodeSubnets[1].Spec.ForProvider.ZoneID)
}

func TestShouldUseOptimizedCIDR(t *testing.T) {
	cases := []struct {
		name      string
		nodeZones []string
		zones     []string
		want      bool
	}{
		{
			name:      "single node zone strict subset",
			nodeZones: []string{"ap-southeast-1a"},
			zones:     []string{"ap-southeast-1a", "ap-southeast-1b", "ap-southeast-1c"},
			want:      true,
		},
		{
			name:      "node zones equal configured zones",
			nodeZones: []string{"ap-southeast-1a", "ap-southeast-1b"},
			zones:     []string{"ap-southeast-1a", "ap-southeast-1b"},
			want:      false,
		},
		{
			name:      "three node zones falls back to legacy",
			nodeZones: []string{"ap-southeast-1a", "ap-southeast-1b", "ap-southeast-1c"},
			zones: []string{
				"ap-southeast-1a",
				"ap-southeast-1b",
				"ap-southeast-1c",
				"ap-southeast-1d",
				"ap-southeast-1e",
			},
			want: false,
		},
		{
			name:      "empty node zones",
			nodeZones: nil,
			zones:     []string{"ap-southeast-1a", "ap-southeast-1b"},
			want:      false,
		},
	}

	for _, tc := range cases {
		t.Run(tc.name, func(t *testing.T) {
			assert.Equal(t, tc.want, shouldUseOptimizedCIDR(tc.nodeZones, tc.zones))
		})
	}
}

func TestSubnet_convertCloudSubnet(t *testing.T) {
	t.Run("get subnet error", func(t *testing.T) {
		subnetTask, _ := fakeSubnetTask(t)
		subnet := &alivpcv1alpha1.Vswitch{
			ObjectMeta: metav1.ObjectMeta{
				Name: "test-not-found",
			},
		}
		_, err := subnetTask.convertCloudSubnet(context.Background(), subnet)
		assert.Error(t, err)
	})

	t.Run("subnet is not ready", func(t *testing.T) {
		subnetTask, vpcTask := fakeSubnetTask(t)
		result := vpcTask.Create(context.Background())
		assert.True(t, result.IsDoneState())
		subnetTask.VPC.Status.VPC.Name = vpcTask.getVPCName()
		result = subnetTask.Create(context.Background())
		assert.True(t, result.IsDoneState())
		subnetList := &alivpcv1alpha1.VswitchList{}
		err := subnetTask.Local.List(context.Background(), subnetList)
		assert.NoError(t, err)
		assert.NotEmpty(t, subnetList.Items)

		subnet := &subnetList.Items[0]
		_, err = subnetTask.convertCloudSubnet(context.Background(), subnet)
		assert.Error(t, err)
	})

	t.Run("subnet is ready", func(t *testing.T) {
		subnetTask, vpcTask := fakeSubnetTask(t)
		result := vpcTask.Create(context.Background())
		assert.True(t, result.IsDoneState())
		subnetTask.VPC.Status.VPC.Name = vpcTask.getVPCName()
		result = subnetTask.Create(context.Background())
		assert.True(t, result.IsDoneState())
		subnetList := &alivpcv1alpha1.VswitchList{}
		err := subnetTask.Local.List(context.Background(), subnetList)
		assert.NoError(t, err)
		assert.NotEmpty(t, subnetList.Items)

		subnet := &subnetList.Items[0]
		subnet.Status.SetConditions(xpv1.Available())
		expectedSubnetID := "aliyun-subnet-id-1"
		expectedZoneID := "ap-southeast-1a"
		expectedCidr := "10.16.0.0/21"
		subnet.Status.AtProvider.ID = ptr.To(expectedSubnetID)
		subnet.Status.AtProvider.ZoneID = ptr.To(expectedZoneID)
		subnet.Status.AtProvider.CidrBlock = ptr.To(expectedCidr)
		err = subnetTask.Local.Status().Update(context.Background(), subnet)
		assert.NoError(t, err)

		subnetRecord, err := subnetTask.convertCloudSubnet(context.Background(), subnet)
		assert.NoError(t, err)
		assert.Equal(t, &v1alpha1.Subnet{
			SubnetID:           expectedSubnetID,
			Name:               subnet.Name,
			AvailabilityZone:   expectedZoneID,
			AvailabilityZoneID: expectedZoneID,
			CIDRBlock:          expectedCidr,
		}, subnetRecord)
	})
}

func TestSubnet_PostCreate(t *testing.T) {
	t.Run("subnets are not ready", func(t *testing.T) {
		subnetTask, vpcTask := fakeSubnetTask(t)
		result := vpcTask.Create(context.Background())
		assert.True(t, result.IsDoneState())
		subnetTask.VPC.Status.VPC.Name = vpcTask.getVPCName()
		result = subnetTask.Create(context.Background())
		assert.True(t, result.IsDoneState())

		result = subnetTask.PostCreate(context.Background())
		assert.Error(t, result.Error())
	})

	expectedNodeSubnetRecords := []v1alpha1.Subnet{
		{
			SubnetID:           "subnet-node-ap-southeast-1a",
			AvailabilityZone:   "ap-southeast-1a",
			AvailabilityZoneID: "ap-southeast-1a",
			CIDRBlock:          "10.10.0.0/19",
		},
		{
			SubnetID:           "subnet-node-ap-southeast-1b",
			AvailabilityZone:   "ap-southeast-1b",
			AvailabilityZoneID: "ap-southeast-1b",
			CIDRBlock:          "10.10.64.0/19",
		},
		{
			SubnetID:           "subnet-node-ap-southeast-1c",
			AvailabilityZone:   "ap-southeast-1c",
			AvailabilityZoneID: "ap-southeast-1c",
			CIDRBlock:          "10.10.128.0/19",
		},
	}
	expectedPrivateSubnetRecords := []v1alpha1.Subnet{
		{
			SubnetID:           "subnet-private-ap-southeast-1a",
			AvailabilityZone:   "ap-southeast-1a",
			AvailabilityZoneID: "ap-southeast-1a",
			CIDRBlock:          "10.10.48.0/20",
		},
		{
			SubnetID:           "subnet-private-ap-southeast-1b",
			AvailabilityZone:   "ap-southeast-1b",
			AvailabilityZoneID: "ap-southeast-1b",
			CIDRBlock:          "10.10.112.0/20",
		},
		{
			SubnetID:           "subnet-private-ap-southeast-1c",
			AvailabilityZone:   "ap-southeast-1c",
			AvailabilityZoneID: "ap-southeast-1c",
			CIDRBlock:          "10.10.176.0/20",
		},
	}
	expectedPublicSubnetRecords := []v1alpha1.Subnet{
		{
			SubnetID:           "subnet-public-ap-southeast-1a",
			AvailabilityZone:   "ap-southeast-1a",
			AvailabilityZoneID: "ap-southeast-1a",
			CIDRBlock:          "10.10.32.0/20",
		},
		{
			SubnetID:           "subnet-public-ap-southeast-1b",
			AvailabilityZone:   "ap-southeast-1b",
			AvailabilityZoneID: "ap-southeast-1b",
			CIDRBlock:          "10.10.96.0/20",
		},
		{
			SubnetID:           "subnet-public-ap-southeast-1c",
			AvailabilityZone:   "ap-southeast-1c",
			AvailabilityZoneID: "ap-southeast-1c",
			CIDRBlock:          "10.10.160.0/20",
		},
	}

	t.Run("subnets are partial ready", func(t *testing.T) {
		subnetTask, vpcTask := fakeSubnetTask(t)
		result := vpcTask.Create(context.Background())
		assert.True(t, result.IsDoneState())
		subnetTask.VPC.Status.VPC.Name = vpcTask.getVPCName()
		result = subnetTask.Create(context.Background())
		assert.True(t, result.IsDoneState())

		for i, subnet := range subnetTask.nodeSubnets {
			subnet.Status.SetConditions(xpv1.Available())
			subnet.Status.AtProvider.ID = ptr.To(expectedNodeSubnetRecords[i].SubnetID)
			subnet.Status.AtProvider.ZoneID = ptr.To(expectedNodeSubnetRecords[i].AvailabilityZoneID)
			subnet.Status.AtProvider.CidrBlock = ptr.To(expectedNodeSubnetRecords[i].CIDRBlock)
			err := subnetTask.Local.Status().Update(context.Background(), subnet)
			assert.NoError(t, err)
		}
		result = subnetTask.PostCreate(context.Background())
		assert.Error(t, result.Error())
	})

	t.Run("subnets are all ready", func(t *testing.T) {
		subnetTask, vpcTask := fakeSubnetTask(t)
		result := vpcTask.Create(context.Background())
		assert.True(t, result.IsDoneState())
		subnetTask.VPC.Status.VPC.Name = vpcTask.getVPCName()
		result = subnetTask.Create(context.Background())
		assert.True(t, result.IsDoneState())

		for i, subnet := range subnetTask.nodeSubnets {
			subnet.Status.SetConditions(xpv1.Available())
			subnet.Status.AtProvider.ID = ptr.To(expectedNodeSubnetRecords[i].SubnetID)
			subnet.Status.AtProvider.ZoneID = ptr.To(expectedNodeSubnetRecords[i].AvailabilityZoneID)
			subnet.Status.AtProvider.CidrBlock = ptr.To(expectedNodeSubnetRecords[i].CIDRBlock)
			err := subnetTask.Local.Status().Update(context.Background(), subnet)
			assert.NoError(t, err)
			expectedNodeSubnetRecords[i].Name = subnet.Name
		}
		for i, subnet := range subnetTask.privateSubnets {
			subnet.Status.SetConditions(xpv1.Available())
			subnet.Status.AtProvider.ID = ptr.To(expectedPrivateSubnetRecords[i].SubnetID)
			subnet.Status.AtProvider.ZoneID = ptr.To(expectedPrivateSubnetRecords[i].AvailabilityZoneID)
			subnet.Status.AtProvider.CidrBlock = ptr.To(expectedPrivateSubnetRecords[i].CIDRBlock)
			err := subnetTask.Local.Status().Update(context.Background(), subnet)
			assert.NoError(t, err)
			expectedPrivateSubnetRecords[i].Name = subnet.Name
		}
		for i, subnet := range subnetTask.publicSubnets {
			subnet.Status.SetConditions(xpv1.Available())
			subnet.Status.AtProvider.ID = ptr.To(expectedPublicSubnetRecords[i].SubnetID)
			subnet.Status.AtProvider.ZoneID = ptr.To(expectedPublicSubnetRecords[i].AvailabilityZoneID)
			subnet.Status.AtProvider.CidrBlock = ptr.To(expectedPublicSubnetRecords[i].CIDRBlock)
			err := subnetTask.Local.Status().Update(context.Background(), subnet)
			assert.NoError(t, err)
			expectedPublicSubnetRecords[i].Name = subnet.Name
		}
		result = subnetTask.PostCreate(context.Background())
		assert.True(t, result.IsDoneState())

		assert.Equal(t, expectedNodeSubnetRecords, subnetTask.VPC.Status.NodeSubnets)
		assert.Equal(t, expectedPrivateSubnetRecords, subnetTask.VPC.Status.PrivateSubnets)
		assert.Equal(t, expectedPublicSubnetRecords, subnetTask.VPC.Status.PublicSubnets)
		assert.Nil(t, subnetTask.VPC.Status.ControlPlaneSubnets)
	})

	t.Run("optimized subnets are all ready without control plane subnets", func(t *testing.T) {
		subnetTask, vpcTask := fakeSubnetTask(t)
		subnetTask.VPC.Spec.NodeZones = []string{"ap-southeast-1a"}
		result := vpcTask.Create(context.Background())
		assert.True(t, result.IsDoneState())
		subnetTask.VPC.Status.VPC.Name = vpcTask.getVPCName()
		result = subnetTask.Create(context.Background())
		assert.True(t, result.IsDoneState())

		markVswitchesReady(t, subnetTask, subnetTask.nodeSubnets)
		markVswitchesReady(t, subnetTask, subnetTask.privateSubnets)
		markVswitchesReady(t, subnetTask, subnetTask.publicSubnets)

		cidr := subnetTask.VPC.Spec.CIDR
		nodeZones := append([]string(nil), subnetTask.VPC.Spec.NodeZones...)
		zones := subnetTask.GetZones()
		result = subnetTask.PostCreate(context.Background())
		assert.True(t, result.IsDoneState())

		workers, public, private, err := util.GetAliyunSubnetCIDRsOptimized(
			cidr,
			nodeZones,
			zones,
		)
		assert.NoError(t, err)
		assert.Len(t, subnetTask.VPC.Status.NodeSubnets, 1)
		assert.Len(t, subnetTask.VPC.Status.PrivateSubnets, len(private))
		assert.Len(t, subnetTask.VPC.Status.PublicSubnets, len(public))
		assert.Nil(t, subnetTask.VPC.Status.ControlPlaneSubnets)
		for _, subnet := range subnetTask.VPC.Status.NodeSubnets {
			assert.Equal(t, workers[subnet.AvailabilityZone], subnet.CIDRBlock)
		}
		for _, subnet := range subnetTask.VPC.Status.PublicSubnets {
			assert.Equal(t, public[subnet.AvailabilityZone], subnet.CIDRBlock)
		}
		for _, subnet := range subnetTask.VPC.Status.PrivateSubnets {
			assert.Equal(t, private[subnet.AvailabilityZone], subnet.CIDRBlock)
		}
	})
}

func TestSubnet_Delete(t *testing.T) {
	t.Run("subnets not found", func(t *testing.T) {
		subnetTask, _ := fakeSubnetTask(t)
		result := subnetTask.Delete(context.Background())
		assert.True(t, result.IsDoneState())
	})

	t.Run("delete subnets", func(t *testing.T) {
		subnetTask, vpcTask := fakeSubnetTask(t)
		result := vpcTask.Create(context.Background())
		assert.True(t, result.IsDoneState())
		subnetTask.VPC.Status.VPC.Name = vpcTask.getVPCName()
		result = subnetTask.Create(context.Background())
		assert.True(t, result.IsDoneState())

		result = subnetTask.Delete(context.Background())
		assert.True(t, result.IsDoneState())

		subnetList := &alivpcv1alpha1.VswitchList{}
		err := subnetTask.Local.List(context.Background(), subnetList)
		assert.NoError(t, err)
		assert.Empty(t, subnetList.Items)
	})
}

func TestSubnet_PostDelete(t *testing.T) {
	t.Run("subnets still exist", func(t *testing.T) {
		subnetTask, vpcTask := fakeSubnetTask(t)
		result := vpcTask.Create(context.Background())
		assert.True(t, result.IsDoneState())
		subnetTask.VPC.Status.VPC.Name = vpcTask.getVPCName()
		result = subnetTask.Create(context.Background())
		assert.True(t, result.IsDoneState())

		result = subnetTask.PostDelete(context.Background())
		assert.Error(t, result.Error())
	})

	t.Run("subnets are all deleted", func(t *testing.T) {
		subnetTask, _ := fakeSubnetTask(t)
		result := subnetTask.PostDelete(context.Background())
		assert.True(t, result.IsDoneState())
	})
}
