package regionalserver

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

	"github.com/stretchr/testify/assert"
	"github.com/stretchr/testify/require"
	dataplanemanagerv1 "github.com/tidbcloud/cluster-service-ng/api/tidbcloud/dataplane-manager/v1"
)

func TestListVpcPeerings(t *testing.T) {
	var gotMethod, gotPath string
	srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		gotMethod = r.Method
		gotPath = r.URL.Path
		w.Header().Set("Content-Type", "application/json")
		_, _ = w.Write([]byte(`{
			"vpcPeerings":[
				{
					"id":"peering-1",
					"sourceCidrBlock":"10.0.0.0/16",
					"destinationCidrBlock":"192.168.0.0/16",
					"aws":{
						"destinationAccountId":"customer-account",
						"destinationVpcId":"customer-vpc",
						"destinationRegion":"us-west-2",
						"sourceAccountId":"tidb-account",
						"sourceVpcId":"tidb-vpc",
						"vpcPeeringConnectionId":"pcx-123",
						"sourceRegion":"us-east-1"
					},
					"status":"ACTIVE",
					"message":"ok"
				}
			]
		}`))
	}))
	defer srv.Close()

	cli := newTestRegionalCli()
	region := newActiveRegion(srv.URL)

	resp, err := cli.ListVpcPeerings(context.Background(), region, &dataplanemanagerv1.ListVpcPeeringsRequest{
		DataPlaneId: "dp-1",
	})
	require.Nil(t, err)
	require.NotNil(t, resp)
	require.Len(t, resp.GetVpcPeerings(), 1)
	assert.Equal(t, http.MethodGet, gotMethod)
	assert.Equal(t, "/dataplane-manager/api/v1/dataplanes/dp-1/vpcPeerings", gotPath)
	assert.Equal(t, "peering-1", resp.GetVpcPeerings()[0].GetId())
	assert.Equal(t, "pcx-123", resp.GetVpcPeerings()[0].GetAws().GetVpcPeeringConnectionId())
}

func TestGetVpcPeering(t *testing.T) {
	t.Run("success", func(t *testing.T) {
		var gotMethod, gotPath string
		srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
			gotMethod = r.Method
			gotPath = r.URL.Path
			w.Header().Set("Content-Type", "application/json")
			_, _ = w.Write([]byte(`{
				"id":"pcx-123",
				"sourceCidrBlock":"10.0.0.0/16",
				"destinationCidrBlock":"192.168.0.0/16",
				"aws":{
					"destinationAccountId":"customer-account",
					"destinationVpcId":"customer-vpc",
					"destinationRegion":"us-west-2",
					"sourceAccountId":"tidb-account",
					"sourceVpcId":"tidb-vpc",
					"vpcPeeringConnectionId":"pcx-123",
					"sourceRegion":"us-east-1"
				},
				"status":"ACTIVE",
				"message":"ok"
			}`))
		}))
		defer srv.Close()

		cli := newTestRegionalCli()
		region := newActiveRegion(srv.URL)

		resp, err := cli.GetVpcPeering(context.Background(), region, &dataplanemanagerv1.GetVpcPeeringRequest{
			DataPlaneId:  "dp-1",
			VpcPeeringId: "pcx-123",
		})
		require.Nil(t, err)
		require.NotNil(t, resp)
		assert.Equal(t, http.MethodGet, gotMethod)
		assert.Equal(t, "/dataplane-manager/api/v1/dataplanes/dp-1/vpcPeerings/pcx-123", gotPath)
		assert.Equal(t, "pcx-123", resp.GetId())
	})

	t.Run("not found", func(t *testing.T) {
		srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
			http.Error(w, `{"error":"not found"}`, http.StatusNotFound)
		}))
		defer srv.Close()

		cli := newTestRegionalCli()
		region := newActiveRegion(srv.URL)

		resp, err := cli.GetVpcPeering(context.Background(), region, &dataplanemanagerv1.GetVpcPeeringRequest{
			DataPlaneId:  "dp-1",
			VpcPeeringId: "pcx-404",
		})
		require.Nil(t, resp)
		require.NotNil(t, err)
		assert.Contains(t, err.Error(), "vpc peering not found")
	})
}
