package eks

import (
	"context"
	"net/http"
	"net/http/httptest"
	"sync/atomic"
	"testing"

	awssdk "github.com/aws/aws-sdk-go-v2/aws"
	"github.com/aws/aws-sdk-go-v2/service/ec2"
	ec2types "github.com/aws/aws-sdk-go-v2/service/ec2/types"
	"github.com/stretchr/testify/assert"
	"github.com/stretchr/testify/require"
	"go.uber.org/mock/gomock"

	regionalaws "github.com/tidbcloud/infra-provider/pkg/cloud/aws"
	"github.com/tidbcloud/infra-provider/regional-server/api/v1alpha1"
)

func TestGetVPCEndpointConnsPreservesSinglePageBehavior(t *testing.T) {
	var calls atomic.Int32
	server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		calls.Add(1)
		require.NoError(t, r.ParseForm())
		assert.Equal(t, "DescribeVpcEndpointConnections", r.Form.Get("Action"))
		w.Header().Set("Content-Type", "text/xml")
		_, _ = w.Write([]byte(`<DescribeVpcEndpointConnectionsResponse>
<nextToken>next-page</nextToken><vpcEndpointConnectionSet><item>
<vpcEndpointId>vpce-first-page</vpcEndpointId><vpcEndpointState>available</vpcEndpointState>
</item></vpcEndpointConnectionSet></DescribeVpcEndpointConnectionsResponse>`))
	}))
	t.Cleanup(server.Close)

	cli := ec2.NewFromConfig(awssdk.Config{
		Region: "us-west-2", Credentials: awssdk.AnonymousCredentials{},
		HTTPClient: server.Client(), BaseEndpoint: awssdk.String(server.URL),
	})
	awsCli := regionalaws.NewMockClient(gomock.NewController(t))
	awsCli.EXPECT().EC2(gomock.Any()).Return(cli)
	task := NewEndpoint(fakeTaskContext(t), awsCli)

	connections, err := task.getVPCEndpointConns(context.Background(), "vpce-svc-1")

	require.NoError(t, err)
	require.Len(t, connections, 1)
	assert.Equal(t, "vpce-first-page", awssdk.ToString(connections[0].VpcEndpointId))
	assert.Equal(t, int32(1), calls.Load(), "legacy reconciliation must not follow NextToken")
}

func TestCalculateConnsStatusIncludesIPAddressType(t *testing.T) {
	tests := []struct {
		name        string
		addressType ec2types.IpAddressType
		want        v1alpha1.EndpointIPAddressType
	}{
		{name: "ipv4", addressType: ec2types.IpAddressType("ipv4"), want: v1alpha1.EndpointIPAddressTypeIPv4},
		{name: "ipv6", addressType: ec2types.IpAddressType("ipv6"), want: v1alpha1.EndpointIPAddressTypeIPv6},
		{name: "dualstack", addressType: ec2types.IpAddressType("dualstack"), want: v1alpha1.EndpointIPAddressTypeDualstack},
		{name: "unknown", addressType: ec2types.IpAddressType("unknown")},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			statuses, _ := (&Endpoint{}).calculateConnsStatus(
				[]v1alpha1.Connection{{Endpoint: "vpce-1"}},
				[]ec2types.VpcEndpointConnection{{
					VpcEndpointId:    awssdk.String("vpce-1"),
					VpcEndpointState: ec2types.StateAvailable,
					IpAddressType:    tt.addressType,
				}},
			)

			require.Len(t, statuses, 1)
			assert.Equal(t, tt.want, statuses[0].IPAddressType)
		})
	}
}
