package aws

import (
	"context"
	"testing"

	xpv1 "github.com/crossplane/crossplane-runtime/apis/common/v1"
	"github.com/stretchr/testify/assert"
	"github.com/stretchr/testify/require"
	"github.com/upbound/provider-aws/apis/ec2/v1beta1"
	corev1 "k8s.io/api/core/v1"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/apimachinery/pkg/runtime"
	"k8s.io/utils/ptr"
	"sigs.k8s.io/controller-runtime/pkg/client"
	"sigs.k8s.io/controller-runtime/pkg/client/fake"

	"github.com/tidbcloud/infra-provider/regional-server/api/v1alpha1"
	"github.com/tidbcloud/infra-provider/regional-server/pkg/config"
	"github.com/tidbcloud/infra-provider/regional-server/pkg/controllers/vpcpeering/task"
	"github.com/tidbcloud/infra-provider/regional-server/pkg/controllers/vpcpeering/task/common"
)

// fakeVPCPeeringTask creates a fake VPCPeeringConnection task for testing
func fakeVPCPeeringTask(t *testing.T, objects ...client.Object) *VPCPeeringConnection {
	scheme := runtime.NewScheme()
	require.NoError(t, v1alpha1.AddToScheme(scheme))
	require.NoError(t, v1beta1.AddToScheme(scheme))

	fakeClient := fake.NewClientBuilder().
		WithScheme(scheme).
		WithObjects(objects...).
		WithStatusSubresource(&v1beta1.Route{}).
		Build()

	return &VPCPeeringConnection{
		BaseTask: &task.BaseTask{
			Context: &task.Context{
				Local: fakeClient,
				VPCPeering: &v1alpha1.VPCPeering{
					ObjectMeta: metav1.ObjectMeta{
						Name:      "test-peering",
						Namespace: "default",
					},
					Spec: v1alpha1.VPCPeeringSpec{
						Region: "us-east-1",
						Target: v1alpha1.Target{
							AWS: &v1alpha1.AWS{
								PeerCIDR:  "10.1.0.0/16",
								AccountID: "123456789012",
								Region:    "us-east-1",
								VpcID:     "vpc-peer",
							},
						},
					},
				},
				VPC: &v1alpha1.VPC{
					ObjectMeta: metav1.ObjectMeta{
						Name:      "test-vpc",
						Namespace: "default",
						Labels: map[string]string{
							"tags.tidbcloud.com/environment": "test",
						},
					},
					Status: v1alpha1.VPCStatus{
						VPC: v1alpha1.VPCRes{
							VPCID: "vpc-source",
						},
					},
				},
				Internet: &v1alpha1.Internet{
					ObjectMeta: metav1.ObjectMeta{
						Name:      "test-internet",
						Namespace: "default",
					},
					Status: v1alpha1.InternetStatus{
						RouteTables: []v1alpha1.RouteTable{
							{Name: "rtb-nodes-us-east-1a", RouteTableID: "rtb-123"},
							{Name: "rtb-nodes-us-east-1b", RouteTableID: "rtb-456"},
						},
					},
				},
				Dataplane: &v1alpha1.DataPlane{
					ObjectMeta: metav1.ObjectMeta{
						Name:      "test-dataplane",
						Namespace: "default",
					},
					Spec: v1alpha1.DataPlaneSpec{
						AccountRef: v1alpha1.AccountReference{
							ProviderConfigName: "aws-provider-config",
						},
					},
				},
				Config: config.RootConfig{
					AdditionalCloudTags: map[string]string{
						"ManagedBy": "PingCAP",
					},
				},
			},
		},
	}
}

func TestCreateIncludesAdditionalCloudTags(t *testing.T) {
	task := fakeVPCPeeringTask(t)

	result := task.Create(context.Background())
	require.NoError(t, result.Error())

	peeringConn := &v1beta1.VPCPeeringConnection{}
	require.NoError(t, task.Local.Get(context.Background(), client.ObjectKey{Name: "test-peering"}, peeringConn))
	require.Contains(t, peeringConn.Spec.ForProvider.Tags, "ManagedBy")
	assert.Equal(t, "PingCAP", ptr.Deref(peeringConn.Spec.ForProvider.Tags["ManagedBy"], ""))
	assert.Equal(t, "test", ptr.Deref(peeringConn.Spec.ForProvider.Tags["environment"], ""))
}

func TestCreateSetsAutoAcceptForSameAccountBYOCO11yPeering(t *testing.T) {
	tests := []struct {
		name                string
		labels              map[string]string
		sourceAccountID     string
		targetAccountID     string
		targetRegion        string
		expectAutoAcceptSet bool
		expectPeerRegionSet bool
	}{
		{
			name:                "managed o11y peering in same account",
			labels:              map[string]string{common.O11yVPCPeeringManagedByLabel: common.O11yVPCPeeringManagedByValue},
			sourceAccountID:     "123456789012",
			targetAccountID:     "123456789012",
			targetRegion:        "us-east-1",
			expectAutoAcceptSet: true,
		},
		{
			name:                "normal peering leaves auto accept unset",
			sourceAccountID:     "123456789012",
			targetAccountID:     "123456789012",
			targetRegion:        "us-east-1",
			expectPeerRegionSet: true,
		},
		{
			name:                "managed o11y peering in same account ignores target region",
			labels:              map[string]string{common.O11yVPCPeeringManagedByLabel: common.O11yVPCPeeringManagedByValue},
			sourceAccountID:     "123456789012",
			targetAccountID:     "123456789012",
			targetRegion:        "us-west-2",
			expectAutoAcceptSet: true,
		},
		{
			name:                "managed o11y peering across accounts leaves auto accept unset",
			labels:              map[string]string{common.O11yVPCPeeringManagedByLabel: common.O11yVPCPeeringManagedByValue},
			sourceAccountID:     "123456789012",
			targetAccountID:     "210987654321",
			targetRegion:        "us-east-1",
			expectPeerRegionSet: true,
		},
		{
			name:                "managed o11y peering without source account leaves auto accept unset",
			labels:              map[string]string{common.O11yVPCPeeringManagedByLabel: common.O11yVPCPeeringManagedByValue},
			targetAccountID:     "123456789012",
			targetRegion:        "us-east-1",
			expectPeerRegionSet: true,
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			task := fakeVPCPeeringTask(t)
			task.VPCPeering.Labels = tt.labels
			task.VPCPeering.Annotations = map[string]string{
				v1alpha1.AnnotationKeySourceAccountID: tt.sourceAccountID,
			}
			task.VPCPeering.Spec.Target.AWS.AccountID = tt.targetAccountID
			task.VPCPeering.Spec.Target.AWS.Region = tt.targetRegion

			result := task.Create(context.Background())
			require.NoError(t, result.Error())

			peeringConn := &v1beta1.VPCPeeringConnection{}
			require.NoError(t, task.Local.Get(context.Background(), client.ObjectKey{Name: "test-peering"}, peeringConn))
			if tt.expectAutoAcceptSet {
				require.NotNil(t, peeringConn.Spec.ForProvider.AutoAccept)
				assert.True(t, *peeringConn.Spec.ForProvider.AutoAccept)
				assert.Nil(t, peeringConn.Spec.ForProvider.PeerRegion)
				return
			}
			assert.Nil(t, peeringConn.Spec.ForProvider.AutoAccept)
			if tt.expectPeerRegionSet {
				require.NotNil(t, peeringConn.Spec.ForProvider.PeerRegion)
				assert.Equal(t, tt.targetRegion, *peeringConn.Spec.ForProvider.PeerRegion)
				return
			}
			assert.Nil(t, peeringConn.Spec.ForProvider.PeerRegion)
		})
	}
}

func TestBuildPeeringRouteLabels(t *testing.T) {
	task := fakeVPCPeeringTask(t)
	labels := task.buildPeeringRouteLabels()

	assert.Contains(t, labels, v1alpha1.VPCPeeringNameKey)
	assert.Equal(t, "test-peering", labels[v1alpha1.VPCPeeringNameKey])
}

func TestBuildPeeringRoute(t *testing.T) {
	tests := []struct {
		name           string
		routeTableName string
		peerCIDR       string
		pcxName        string
		labels         map[string]string
		validate       func(*testing.T, *v1beta1.Route)
	}{
		{
			name:           "valid route creation",
			routeTableName: "rtb-nodes-us-east-1a",
			peerCIDR:       "10.1.0.0/16",
			pcxName:        "pcx-12345",
			labels:         map[string]string{"test": "label"},
			validate: func(t *testing.T, route *v1beta1.Route) {
				assert.NotNil(t, route)
				assert.Equal(t, "10.1.0.0/16", *route.Spec.ForProvider.DestinationCidrBlock)
				assert.Equal(t, "pcx-12345", route.Spec.ForProvider.VPCPeeringConnectionIDRef.Name)
				assert.Equal(t, "rtb-nodes-us-east-1a", route.Spec.ForProvider.RouteTableIDRef.Name)
				assert.Contains(t, route.Labels, "test")
				assert.Equal(t, "us-east-1", *route.Spec.ForProvider.Region)
			},
		},
		{
			name:           "route with empty route table name",
			routeTableName: "",
			peerCIDR:       "10.1.0.0/16",
			pcxName:        "pcx-12345",
			labels:         map[string]string{},
			validate: func(t *testing.T, route *v1beta1.Route) {
				// Should still create route, validation happens at apply time
				assert.NotNil(t, route)
				assert.Equal(t, "", route.Spec.ForProvider.RouteTableIDRef.Name)
			},
		},
		{
			name:           "route with multiple labels",
			routeTableName: "rtb-nodes-us-east-1a",
			peerCIDR:       "10.1.0.0/16",
			pcxName:        "pcx-12345",
			labels: map[string]string{
				"label1": "value1",
				"label2": "value2",
			},
			validate: func(t *testing.T, route *v1beta1.Route) {
				assert.Contains(t, route.Labels, "label1")
				assert.Contains(t, route.Labels, "label2")
			},
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			task := fakeVPCPeeringTask(t)
			route := task.buildPeeringRoute(tt.routeTableName, tt.peerCIDR, tt.pcxName, tt.labels)
			if tt.validate != nil {
				tt.validate(t, route)
			}
		})
	}
}

func TestListPeeringRoutes(t *testing.T) {
	tests := []struct {
		name          string
		setupObjects  func() []client.Object
		expectedCount int
		expectError   bool
	}{
		{
			name: "list routes with matching labels",
			setupObjects: func() []client.Object {
				return []client.Object{
					&v1beta1.Route{
						ObjectMeta: metav1.ObjectMeta{
							Name:      "route-1",
							Namespace: "default",
							Labels: map[string]string{
								v1alpha1.VPCPeeringNameKey: "test-peering",
							},
						},
					},
					&v1beta1.Route{
						ObjectMeta: metav1.ObjectMeta{
							Name:      "route-2",
							Namespace: "default",
							Labels: map[string]string{
								v1alpha1.VPCPeeringNameKey: "test-peering",
							},
						},
					},
					&v1beta1.Route{
						ObjectMeta: metav1.ObjectMeta{
							Name:      "route-3",
							Namespace: "default",
							Labels: map[string]string{
								v1alpha1.VPCPeeringNameKey: "other-peering",
							},
						},
					},
				}
			},
			expectedCount: 2,
			expectError:   false,
		},
		{
			name: "no routes found",
			setupObjects: func() []client.Object {
				return []client.Object{}
			},
			expectedCount: 0,
			expectError:   false,
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			objects := tt.setupObjects()
			task := fakeVPCPeeringTask(t, objects...)

			routes, err := task.listPeeringRoutes(context.Background())
			if tt.expectError {
				assert.Error(t, err)
			} else {
				assert.NoError(t, err)
				assert.Len(t, routes, tt.expectedCount)
			}
		})
	}
}

func TestArePeeringRoutesReady(t *testing.T) {
	tests := []struct {
		name         string
		setupObjects func() []client.Object
		expectReady  bool
		expectError  bool
	}{
		{
			name: "all routes ready and active",
			setupObjects: func() []client.Object {
				return []client.Object{
					&v1beta1.Route{
						ObjectMeta: metav1.ObjectMeta{
							Name:      "route-1",
							Namespace: "default",
							Labels: map[string]string{
								v1alpha1.VPCPeeringNameKey: "test-peering",
							},
						},
						Status: v1beta1.RouteStatus{
							ResourceStatus: xpv1.ResourceStatus{
								ConditionedStatus: xpv1.ConditionedStatus{
									Conditions: []xpv1.Condition{
										{Type: xpv1.TypeReady, Status: corev1.ConditionTrue, Reason: xpv1.ReasonAvailable},
										{Type: xpv1.TypeSynced, Status: corev1.ConditionTrue},
									},
								},
							},
							AtProvider: v1beta1.RouteObservation_2{
								State: ptr.To("active"),
							},
						},
					},
					&v1beta1.Route{
						ObjectMeta: metav1.ObjectMeta{
							Name:      "route-2",
							Namespace: "default",
							Labels: map[string]string{
								v1alpha1.VPCPeeringNameKey: "test-peering",
							},
						},
						Status: v1beta1.RouteStatus{
							ResourceStatus: xpv1.ResourceStatus{
								ConditionedStatus: xpv1.ConditionedStatus{
									Conditions: []xpv1.Condition{
										{Type: xpv1.TypeReady, Status: corev1.ConditionTrue, Reason: xpv1.ReasonAvailable},
										{Type: xpv1.TypeSynced, Status: corev1.ConditionTrue},
									},
								},
							},
							AtProvider: v1beta1.RouteObservation_2{
								State: ptr.To("active"),
							},
						},
					},
				}
			},
			expectReady: true,
			expectError: false,
		},
		{
			name: "route in blackhole state",
			setupObjects: func() []client.Object {
				return []client.Object{
					&v1beta1.Route{
						ObjectMeta: metav1.ObjectMeta{
							Name:      "route-1",
							Namespace: "default",
							Labels: map[string]string{
								v1alpha1.VPCPeeringNameKey: "test-peering",
							},
						},
						Status: v1beta1.RouteStatus{
							ResourceStatus: xpv1.ResourceStatus{
								ConditionedStatus: xpv1.ConditionedStatus{
									Conditions: []xpv1.Condition{
										{Type: xpv1.TypeReady, Status: corev1.ConditionTrue, Reason: xpv1.ReasonAvailable},
										{Type: xpv1.TypeSynced, Status: corev1.ConditionTrue},
									},
								},
							},
							AtProvider: v1beta1.RouteObservation_2{
								State: ptr.To("blackhole"),
							},
						},
					},
					&v1beta1.Route{
						ObjectMeta: metav1.ObjectMeta{
							Name:      "route-2",
							Namespace: "default",
							Labels: map[string]string{
								v1alpha1.VPCPeeringNameKey: "test-peering",
							},
						},
						Status: v1beta1.RouteStatus{
							ResourceStatus: xpv1.ResourceStatus{
								ConditionedStatus: xpv1.ConditionedStatus{
									Conditions: []xpv1.Condition{
										{Type: xpv1.TypeReady, Status: corev1.ConditionTrue, Reason: xpv1.ReasonAvailable},
										{Type: xpv1.TypeSynced, Status: corev1.ConditionTrue},
									},
								},
							},
							AtProvider: v1beta1.RouteObservation_2{
								State: ptr.To("active"),
							},
						},
					},
				}
			},
			expectReady: false,
			expectError: false,
		},
		{
			name: "route count mismatch - only 1 route when 2 expected",
			setupObjects: func() []client.Object {
				return []client.Object{
					&v1beta1.Route{
						ObjectMeta: metav1.ObjectMeta{
							Name:      "route-1",
							Namespace: "default",
							Labels: map[string]string{
								v1alpha1.VPCPeeringNameKey: "test-peering",
							},
						},
						Status: v1beta1.RouteStatus{
							ResourceStatus: xpv1.ResourceStatus{
								ConditionedStatus: xpv1.ConditionedStatus{
									Conditions: []xpv1.Condition{
										{Type: xpv1.TypeReady, Status: corev1.ConditionTrue, Reason: xpv1.ReasonAvailable},
										{Type: xpv1.TypeSynced, Status: corev1.ConditionTrue},
									},
								},
							},
							AtProvider: v1beta1.RouteObservation_2{
								State: ptr.To("active"),
							},
						},
					},
				}
			},
			expectReady: false,
			expectError: false,
		},
		{
			name: "no routes found",
			setupObjects: func() []client.Object {
				return []client.Object{}
			},
			expectReady: false,
			expectError: false,
		},
		{
			name: "multiple routes with one not ready",
			setupObjects: func() []client.Object {
				return []client.Object{
					&v1beta1.Route{
						ObjectMeta: metav1.ObjectMeta{
							Name:      "route-1",
							Namespace: "default",
							Labels: map[string]string{
								v1alpha1.VPCPeeringNameKey: "test-peering",
							},
						},
						Status: v1beta1.RouteStatus{
							ResourceStatus: xpv1.ResourceStatus{
								ConditionedStatus: xpv1.ConditionedStatus{
									Conditions: []xpv1.Condition{
										{Type: xpv1.TypeReady, Status: corev1.ConditionTrue, Reason: xpv1.ReasonAvailable},
										{Type: xpv1.TypeSynced, Status: corev1.ConditionTrue},
									},
								},
							},
							AtProvider: v1beta1.RouteObservation_2{
								State: ptr.To("active"),
							},
						},
					},
					&v1beta1.Route{
						ObjectMeta: metav1.ObjectMeta{
							Name:      "route-2",
							Namespace: "default",
							Labels: map[string]string{
								v1alpha1.VPCPeeringNameKey: "test-peering",
							},
						},
						Status: v1beta1.RouteStatus{
							ResourceStatus: xpv1.ResourceStatus{
								ConditionedStatus: xpv1.ConditionedStatus{
									Conditions: []xpv1.Condition{
										{Type: xpv1.TypeReady, Status: corev1.ConditionFalse},
									},
								},
							},
						},
					},
				}
			},
			expectReady: false,
			expectError: false,
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			objects := tt.setupObjects()
			task := fakeVPCPeeringTask(t, objects...)

			// Get node route table names
			nodeRouteTableNames, err := common.GetNodeRouteTableNames(task.Internet, common.AWSNodeRouteTableFilter)
			require.NoError(t, err)

			// Get routes first, then pass to arePeeringRoutesReady
			routes, err := task.listPeeringRoutes(context.Background())
			if tt.expectError {
				assert.Error(t, err)
				return
			}
			assert.NoError(t, err)

			// arePeeringRoutesReady returns (created, ready, error)
			_, ready, err := task.arePeeringRoutesReady(routes, nodeRouteTableNames)
			assert.NoError(t, err)
			assert.Equal(t, tt.expectReady, ready)
		})
	}
}

func TestCreatePeeringRoutes(t *testing.T) {
	tests := []struct {
		name         string
		peerCIDR     string
		pcxName      string
		expectError  bool
		validateFunc func(*testing.T, *VPCPeeringConnection)
	}{
		{
			name:        "create routes for multiple route tables",
			peerCIDR:    "10.1.0.0/16",
			pcxName:     "pcx-12345",
			expectError: false,
			validateFunc: func(t *testing.T, task *VPCPeeringConnection) {
				routes, err := task.listPeeringRoutes(context.Background())
				require.NoError(t, err)
				assert.Len(t, routes, 2, "should create 2 routes for 2 route tables")

				for _, route := range routes {
					assert.Equal(t, "10.1.0.0/16", *route.Spec.ForProvider.DestinationCidrBlock)
					assert.Equal(t, "pcx-12345", route.Spec.ForProvider.VPCPeeringConnectionIDRef.Name)
					assert.Contains(t, route.Labels, v1alpha1.VPCPeeringNameKey)
				}
			},
		},
		{
			name:        "idempotent operation - routes already exist",
			peerCIDR:    "10.1.0.0/16",
			pcxName:     "pcx-12345",
			expectError: false,
			validateFunc: func(t *testing.T, task *VPCPeeringConnection) {
				// Get node route table names
				nodeRouteTableNames, err := common.GetNodeRouteTableNames(task.Internet, common.AWSNodeRouteTableFilter)
				require.NoError(t, err)

				// Create routes first time
				err = task.createPeeringRoutes(context.Background(), "10.1.0.0/16", "pcx-12345", nodeRouteTableNames)
				require.NoError(t, err)

				// Create routes second time - should be idempotent
				err = task.createPeeringRoutes(context.Background(), "10.1.0.0/16", "pcx-12345", nodeRouteTableNames)
				require.NoError(t, err)

				routes, err := task.listPeeringRoutes(context.Background())
				require.NoError(t, err)
				assert.Len(t, routes, 2, "should still have 2 routes after idempotent operation")
			},
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			task := fakeVPCPeeringTask(t)

			// Get node route table names
			nodeRouteTableNames, err := common.GetNodeRouteTableNames(task.Internet, common.AWSNodeRouteTableFilter)
			require.NoError(t, err)

			err = task.createPeeringRoutes(context.Background(), tt.peerCIDR, tt.pcxName, nodeRouteTableNames)
			if tt.expectError {
				assert.Error(t, err)
			} else {
				assert.NoError(t, err)
				if tt.validateFunc != nil {
					tt.validateFunc(t, task)
				}
			}
		})
	}
}

func TestDeletePeeringRoutes(t *testing.T) {
	tests := []struct {
		name         string
		setupObjects func() []client.Object
		expectError  bool
		validateFunc func(*testing.T, *VPCPeeringConnection)
	}{
		{
			name: "delete existing routes",
			setupObjects: func() []client.Object {
				return []client.Object{
					&v1beta1.Route{
						ObjectMeta: metav1.ObjectMeta{
							Name:      "route-1",
							Namespace: "default",
							Labels: map[string]string{
								v1alpha1.VPCPeeringNameKey: "test-peering",
							},
						},
					},
					&v1beta1.Route{
						ObjectMeta: metav1.ObjectMeta{
							Name:      "route-2",
							Namespace: "default",
							Labels: map[string]string{
								v1alpha1.VPCPeeringNameKey: "test-peering",
							},
						},
					},
				}
			},
			expectError: false,
			validateFunc: func(t *testing.T, task *VPCPeeringConnection) {
				// Note: fake client may not fully simulate Kubernetes deletion behavior
				// (particularly with finalizers and management policies).
				// The deletion logic is tested through DeleteUpboundResource which is
				// tested elsewhere. Here we just verify the operation completes without error.
				//
				// In a real Kubernetes cluster, objects would be properly deleted.
			},
		},
		{
			name: "delete when no routes exist",
			setupObjects: func() []client.Object {
				return []client.Object{}
			},
			expectError: false,
			validateFunc: func(t *testing.T, task *VPCPeeringConnection) {
				routes, err := task.listPeeringRoutes(context.Background())
				require.NoError(t, err)
				assert.Len(t, routes, 0)
			},
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			objects := tt.setupObjects()
			task := fakeVPCPeeringTask(t, objects...)

			err := task.deletePeeringRoutes(context.Background())
			if tt.expectError {
				assert.Error(t, err)
			} else {
				assert.NoError(t, err)
				if tt.validateFunc != nil {
					tt.validateFunc(t, task)
				}
			}
		})
	}
}

func TestUpdateVPCPeeringRoutesStatus(t *testing.T) {
	tests := []struct {
		name         string
		setupObjects func() []client.Object
		expectError  bool
		validateFunc func(*testing.T, *VPCPeeringConnection)
	}{
		{
			name: "update status with active routes",
			setupObjects: func() []client.Object {
				return []client.Object{
					&v1beta1.Route{
						ObjectMeta: metav1.ObjectMeta{
							Name:      "route-1",
							Namespace: "default",
							Labels: map[string]string{
								v1alpha1.VPCPeeringNameKey: "test-peering",
							},
						},
						Spec: v1beta1.RouteSpec{
							ForProvider: v1beta1.RouteParameters_2{
								DestinationCidrBlock: ptr.To("10.1.0.0/16"),
								RouteTableIDRef:      &xpv1.Reference{Name: "rtb-nodes-us-east-1a"},
							},
						},
						Status: v1beta1.RouteStatus{
							AtProvider: v1beta1.RouteObservation_2{
								State: ptr.To("active"),
							},
						},
					},
				}
			},
			expectError: false,
			validateFunc: func(t *testing.T, task *VPCPeeringConnection) {
				assert.NotNil(t, task.VPCPeering.Status.AWS)
				assert.Len(t, task.VPCPeering.Status.AWS.Routes, 1)
				assert.Equal(t, "route-1", task.VPCPeering.Status.AWS.Routes[0].Name)
				assert.Equal(t, "rtb-nodes-us-east-1a", task.VPCPeering.Status.AWS.Routes[0].RouteTableName)
				assert.Equal(t, "active", task.VPCPeering.Status.AWS.Routes[0].State)
			},
		},
		{
			name: "update status with blackhole routes",
			setupObjects: func() []client.Object {
				return []client.Object{
					&v1beta1.Route{
						ObjectMeta: metav1.ObjectMeta{
							Name:      "route-1",
							Namespace: "default",
							Labels: map[string]string{
								v1alpha1.VPCPeeringNameKey: "test-peering",
							},
						},
						Spec: v1beta1.RouteSpec{
							ForProvider: v1beta1.RouteParameters_2{
								DestinationCidrBlock: ptr.To("10.1.0.0/16"),
								RouteTableIDRef:      &xpv1.Reference{Name: "rtb-nodes-us-east-1a"},
							},
						},
						Status: v1beta1.RouteStatus{
							AtProvider: v1beta1.RouteObservation_2{
								State: ptr.To("blackhole"),
							},
						},
					},
				}
			},
			expectError: false,
			validateFunc: func(t *testing.T, task *VPCPeeringConnection) {
				assert.NotNil(t, task.VPCPeering.Status.AWS)
				assert.Len(t, task.VPCPeering.Status.AWS.Routes, 1)
				assert.Equal(t, "blackhole", task.VPCPeering.Status.AWS.Routes[0].State)
			},
		},
		{
			name: "update status with no routes",
			setupObjects: func() []client.Object {
				return []client.Object{}
			},
			expectError: false,
			validateFunc: func(t *testing.T, task *VPCPeeringConnection) {
				assert.NotNil(t, task.VPCPeering.Status.AWS)
				assert.Len(t, task.VPCPeering.Status.AWS.Routes, 0)
			},
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			objects := tt.setupObjects()
			task := fakeVPCPeeringTask(t, objects...)

			// Get routes first, then pass to updateVPCPeeringRoutesStatus
			routes, err := task.listPeeringRoutes(context.Background())
			if tt.expectError {
				assert.Error(t, err)
				return
			}
			assert.NoError(t, err)

			err = task.updateVPCPeeringRoutesStatus(routes)
			assert.NoError(t, err)
			if tt.validateFunc != nil {
				tt.validateFunc(t, task)
			}
		})
	}
}
