package regionalservercli_test

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

	"github.com/jarcoal/httpmock"
	"github.com/stretchr/testify/require"
	"github.com/tidbcloud/infra-provider/regional-server/pkg/common/regionalservercli"
	"sigs.k8s.io/controller-runtime/pkg/client"

	ec2v1alpha1 "github.com/crossplane-contrib/provider-aws/apis/ec2/v1alpha1"
	ec2v1beta1 "github.com/crossplane-contrib/provider-aws/apis/ec2/v1beta1"
	"github.com/crossplane-contrib/provider-aws/apis/eks/manualv1alpha1"
	eksv1beta1 "github.com/crossplane-contrib/provider-aws/apis/eks/v1beta1"
	iamv1alpha1 "github.com/crossplane-contrib/provider-aws/apis/iam/v1alpha1"
	iamv1beta1 "github.com/crossplane-contrib/provider-aws/apis/iam/v1beta1"
	route53v1alpha1 "github.com/crossplane-contrib/provider-aws/apis/route53/v1alpha1"
	xpv1beta1 "github.com/crossplane-contrib/provider-aws/apis/v1beta1"
)

// TestMigrationAWSClient just test path and method are correct
func TestMigrationAWSClient(t *testing.T) {
	ctx := context.Background()
	httpmock.Activate()
	defer httpmock.DeactivateAndReset()
	successHandlerFunc := func(r *http.Request) (*http.Response, error) {
		return httpmock.NewJsonResponse(http.StatusOK, struct{}{})
	}
	reconcileHandlerFunc := func(r *http.Request) (*http.Response, error) {
		q := r.URL.Query()
		if q.Get("pause") != "false" && q.Get("pause") != "true" {
			return httpmock.NewJsonResponse(http.StatusBadRequest, struct{}{})
		}
		return httpmock.NewJsonResponse(http.StatusOK, struct{}{})
	}

	notFoundHandlerFunc := func(r *http.Request) (*http.Response, error) {
		t.Logf("not found handler for url: %+v\n", r.URL.String())
		return httpmock.NewJsonResponse(http.StatusNotFound, struct{}{})
	}
	httpmock.RegisterNoResponder(notFoundHandlerFunc)
	httpmock.RegisterResponder(http.MethodPost, "/api/dedicated/v1/migration/crossplane/aws/import/cluster", successHandlerFunc)
	httpmock.RegisterResponder(http.MethodPost, "/api/dedicated/v1/migration/crossplane/aws/import/vpc", successHandlerFunc)
	httpmock.RegisterResponder(http.MethodPost, "/api/dedicated/v1/migration/crossplane/aws/import/providerconfig", successHandlerFunc)
	httpmock.RegisterResponder(http.MethodPost, "/api/dedicated/v1/migration/crossplane/aws/import/address", successHandlerFunc)
	httpmock.RegisterResponder(http.MethodPost, "/api/dedicated/v1/migration/crossplane/aws/import/internetgateway", successHandlerFunc)
	httpmock.RegisterResponder(http.MethodPost, "/api/dedicated/v1/migration/crossplane/aws/import/launchtemplate", successHandlerFunc)
	httpmock.RegisterResponder(http.MethodPost, "/api/dedicated/v1/migration/crossplane/aws/import/natgateway", successHandlerFunc)
	httpmock.RegisterResponder(http.MethodPost, "/api/dedicated/v1/migration/crossplane/aws/import/route", successHandlerFunc)
	httpmock.RegisterResponder(http.MethodPost, "/api/dedicated/v1/migration/crossplane/aws/import/routetable", successHandlerFunc)
	httpmock.RegisterResponder(http.MethodPost, "/api/dedicated/v1/migration/crossplane/aws/import/securitygroup", successHandlerFunc)
	httpmock.RegisterResponder(http.MethodPost, "/api/dedicated/v1/migration/crossplane/aws/import/subnet", successHandlerFunc)
	httpmock.RegisterResponder(http.MethodPost, "/api/dedicated/v1/migration/crossplane/aws/import/vpcendpoint", successHandlerFunc)
	httpmock.RegisterResponder(http.MethodPost, "/api/dedicated/v1/migration/crossplane/aws/import/vpcendpointserviceconfig", successHandlerFunc)
	httpmock.RegisterResponder(http.MethodPost, "/api/dedicated/v1/migration/crossplane/aws/import/nodegroup", successHandlerFunc)
	httpmock.RegisterResponder(http.MethodPost, "/api/dedicated/v1/migration/crossplane/aws/import/instanceprofile", successHandlerFunc)
	httpmock.RegisterResponder(http.MethodPost, "/api/dedicated/v1/migration/crossplane/aws/import/policy", successHandlerFunc)
	httpmock.RegisterResponder(http.MethodPost, "/api/dedicated/v1/migration/crossplane/aws/import/rolepolicyattachment", successHandlerFunc)
	httpmock.RegisterResponder(http.MethodPost, "/api/dedicated/v1/migration/crossplane/aws/import/role", successHandlerFunc)
	httpmock.RegisterResponder(http.MethodPost, "/api/dedicated/v1/migration/crossplane/aws/import/resourcerecordset", successHandlerFunc)
	httpmock.RegisterResponder(http.MethodPost, "/api/dedicated/v1/migration/crossplane/aws/import/vpcpeeringconnection", successHandlerFunc)

	httpmock.RegisterResponder(http.MethodGet, "/api/dedicated/v1/migration/crossplane/aws/check/cluster", successHandlerFunc)
	httpmock.RegisterResponder(http.MethodGet, "/api/dedicated/v1/migration/crossplane/aws/check/vpc", successHandlerFunc)
	httpmock.RegisterResponder(http.MethodGet, "/api/dedicated/v1/migration/crossplane/aws/check/address", successHandlerFunc)
	httpmock.RegisterResponder(http.MethodGet, "/api/dedicated/v1/migration/crossplane/aws/check/internetgateway", successHandlerFunc)
	httpmock.RegisterResponder(http.MethodGet, "/api/dedicated/v1/migration/crossplane/aws/check/launchtemplate", successHandlerFunc)
	httpmock.RegisterResponder(http.MethodGet, "/api/dedicated/v1/migration/crossplane/aws/check/natgateway", successHandlerFunc)
	httpmock.RegisterResponder(http.MethodGet, "/api/dedicated/v1/migration/crossplane/aws/check/route", successHandlerFunc)
	httpmock.RegisterResponder(http.MethodGet, "/api/dedicated/v1/migration/crossplane/aws/check/routetable", successHandlerFunc)
	httpmock.RegisterResponder(http.MethodGet, "/api/dedicated/v1/migration/crossplane/aws/check/securitygroup", successHandlerFunc)
	httpmock.RegisterResponder(http.MethodGet, "/api/dedicated/v1/migration/crossplane/aws/check/subnet", successHandlerFunc)
	httpmock.RegisterResponder(http.MethodGet, "/api/dedicated/v1/migration/crossplane/aws/check/vpcendpoint", successHandlerFunc)
	httpmock.RegisterResponder(http.MethodGet, "/api/dedicated/v1/migration/crossplane/aws/check/vpcendpointserviceconfig", successHandlerFunc)
	httpmock.RegisterResponder(http.MethodGet, "/api/dedicated/v1/migration/crossplane/aws/check/nodegroup", successHandlerFunc)
	httpmock.RegisterResponder(http.MethodGet, "/api/dedicated/v1/migration/crossplane/aws/check/instanceprofile", successHandlerFunc)
	httpmock.RegisterResponder(http.MethodGet, "/api/dedicated/v1/migration/crossplane/aws/check/policy", successHandlerFunc)
	httpmock.RegisterResponder(http.MethodGet, "/api/dedicated/v1/migration/crossplane/aws/check/rolepolicyattachment", successHandlerFunc)
	httpmock.RegisterResponder(http.MethodGet, "/api/dedicated/v1/migration/crossplane/aws/check/role", successHandlerFunc)
	httpmock.RegisterResponder(http.MethodGet, "/api/dedicated/v1/migration/crossplane/aws/check/resourcerecordset", successHandlerFunc)
	httpmock.RegisterResponder(http.MethodGet, "/api/dedicated/v1/migration/crossplane/aws/check/vpcpeeringconnection", successHandlerFunc)

	httpmock.RegisterResponder(http.MethodPatch, "/api/dedicated/v1/migration/crossplane/aws/reconcile/cluster", reconcileHandlerFunc)
	httpmock.RegisterResponder(http.MethodPatch, "/api/dedicated/v1/migration/crossplane/aws/reconcile/vpc", reconcileHandlerFunc)
	httpmock.RegisterResponder(http.MethodPatch, "/api/dedicated/v1/migration/crossplane/aws/reconcile/address", reconcileHandlerFunc)
	httpmock.RegisterResponder(http.MethodPatch, "/api/dedicated/v1/migration/crossplane/aws/reconcile/internetgateway", reconcileHandlerFunc)
	httpmock.RegisterResponder(http.MethodPatch, "/api/dedicated/v1/migration/crossplane/aws/reconcile/launchtemplate", reconcileHandlerFunc)
	httpmock.RegisterResponder(http.MethodPatch, "/api/dedicated/v1/migration/crossplane/aws/reconcile/natgateway", reconcileHandlerFunc)
	httpmock.RegisterResponder(http.MethodPatch, "/api/dedicated/v1/migration/crossplane/aws/reconcile/route", reconcileHandlerFunc)
	httpmock.RegisterResponder(http.MethodPatch, "/api/dedicated/v1/migration/crossplane/aws/reconcile/routetable", reconcileHandlerFunc)
	httpmock.RegisterResponder(http.MethodPatch, "/api/dedicated/v1/migration/crossplane/aws/reconcile/securitygroup", reconcileHandlerFunc)
	httpmock.RegisterResponder(http.MethodPatch, "/api/dedicated/v1/migration/crossplane/aws/reconcile/subnet", reconcileHandlerFunc)
	httpmock.RegisterResponder(http.MethodPatch, "/api/dedicated/v1/migration/crossplane/aws/reconcile/vpcendpoint", reconcileHandlerFunc)
	httpmock.RegisterResponder(http.MethodPatch, "/api/dedicated/v1/migration/crossplane/aws/reconcile/vpcendpointserviceconfig", reconcileHandlerFunc)
	httpmock.RegisterResponder(http.MethodPatch, "/api/dedicated/v1/migration/crossplane/aws/reconcile/nodegroup", reconcileHandlerFunc)
	httpmock.RegisterResponder(http.MethodPatch, "/api/dedicated/v1/migration/crossplane/aws/reconcile/instanceprofile", reconcileHandlerFunc)
	httpmock.RegisterResponder(http.MethodPatch, "/api/dedicated/v1/migration/crossplane/aws/reconcile/policy", reconcileHandlerFunc)
	httpmock.RegisterResponder(http.MethodPatch, "/api/dedicated/v1/migration/crossplane/aws/reconcile/rolepolicyattachment", reconcileHandlerFunc)
	httpmock.RegisterResponder(http.MethodPatch, "/api/dedicated/v1/migration/crossplane/aws/reconcile/role", reconcileHandlerFunc)
	httpmock.RegisterResponder(http.MethodPatch, "/api/dedicated/v1/migration/crossplane/aws/reconcile/resourcerecordset", reconcileHandlerFunc)
	httpmock.RegisterResponder(http.MethodPatch, "/api/dedicated/v1/migration/crossplane/aws/reconcile/vpcpeeringconnection", reconcileHandlerFunc)

	cli := regionalservercli.NewMigrationServiceAWSClient("http://cluster-service.mock")
	{
		err := cli.ImportCluster(ctx, new(eksv1beta1.Cluster))
		require.Nil(t, err)
	}
	{
		err := cli.ImportVPC(ctx, new(ec2v1beta1.VPC))
		require.Nil(t, err)
	}
	{
		err := cli.ImportProviderConfig(ctx, new(xpv1beta1.ProviderConfig))
		require.Nil(t, err)
	}
	{
		err := cli.ImportAddress(ctx, new(ec2v1beta1.Address))
		require.Nil(t, err)
	}
	{
		err := cli.ImportInternetGateway(ctx, new(ec2v1beta1.InternetGateway))
		require.Nil(t, err)
	}

	{
		err := cli.ImportLaunchTemplate(ctx, new(ec2v1alpha1.LaunchTemplate))
		require.Nil(t, err)
	}
	{
		err := cli.ImportNATGateway(ctx, new(ec2v1beta1.NATGateway))
		require.Nil(t, err)
	}
	{
		err := cli.ImportRoute(ctx, new(ec2v1alpha1.Route))
		require.Nil(t, err)
	}
	{
		err := cli.ImportRouteTable(ctx, new(ec2v1beta1.RouteTable))
		require.Nil(t, err)
	}
	{
		err := cli.ImportSecurityGroup(ctx, new(ec2v1beta1.SecurityGroup))
		require.Nil(t, err)
	}
	{
		err := cli.ImportSubnet(ctx, new(ec2v1beta1.Subnet))
		require.Nil(t, err)
	}
	{
		err := cli.ImportVPCEndpoint(ctx, new(ec2v1alpha1.VPCEndpoint))
		require.Nil(t, err)
	}
	{
		err := cli.ImportVPCEndpointServiceConfiguration(ctx, new(ec2v1alpha1.VPCEndpointServiceConfiguration))
		require.Nil(t, err)
	}
	{
		err := cli.ImportNodeGroup(ctx, new(manualv1alpha1.NodeGroup))
		require.Nil(t, err)
	}
	{
		err := cli.ImportInstanceProfile(ctx, new(iamv1alpha1.InstanceProfile))
		require.Nil(t, err)
	}
	{
		err := cli.ImportPolicy(ctx, new(iamv1beta1.Policy))
		require.Nil(t, err)
	}
	{
		err := cli.ImportRolePolicyAttachment(ctx, new(iamv1beta1.RolePolicyAttachment))
		require.Nil(t, err)
	}
	{
		err := cli.ImportRole(ctx, new(iamv1beta1.Role))
		require.Nil(t, err)
	}
	{
		err := cli.ImportResourceRecordSet(ctx, new(route53v1alpha1.ResourceRecordSet))
		require.Nil(t, err)
	}
	{
		err := cli.ImportVPCPeeringConnection(ctx, new(ec2v1alpha1.VPCPeeringConnection))
		require.Nil(t, err)
	}
	key := client.ObjectKey{
		Namespace: "foo",
		Name:      "foo",
	}
	{
		err := cli.CheckCluster(ctx, key)
		require.Nil(t, err)
	}
	{
		err := cli.CheckVPC(ctx, key)
		require.Nil(t, err)
	}
	{
		err := cli.CheckAddress(ctx, key)
		require.Nil(t, err)
	}
	{
		err := cli.CheckInternetGateway(ctx, key)
		require.Nil(t, err)
	}

	{
		err := cli.CheckLaunchTemplate(ctx, key)
		require.Nil(t, err)
	}
	{
		err := cli.CheckNATGateway(ctx, key)
		require.Nil(t, err)
	}
	{
		err := cli.CheckRoute(ctx, key)
		require.Nil(t, err)
	}
	{
		err := cli.CheckRouteTable(ctx, key)
		require.Nil(t, err)
	}
	{
		err := cli.CheckSecurityGroup(ctx, key)
		require.Nil(t, err)
	}
	{
		err := cli.CheckSubnet(ctx, key)
		require.Nil(t, err)
	}
	{
		err := cli.CheckVPCEndpoint(ctx, key)
		require.Nil(t, err)
	}
	{
		err := cli.CheckVPCEndpointServiceConfiguration(ctx, key)
		require.Nil(t, err)
	}
	{
		err := cli.CheckNodeGroup(ctx, key)
		require.Nil(t, err)
	}
	{
		err := cli.CheckInstanceProfile(ctx, key)
		require.Nil(t, err)
	}
	{
		err := cli.CheckPolicy(ctx, key)
		require.Nil(t, err)
	}
	{
		err := cli.CheckRolePolicyAttachment(ctx, key)
		require.Nil(t, err)
	}
	{
		err := cli.CheckRole(ctx, key)
		require.Nil(t, err)
	}
	{
		err := cli.CheckResourceRecordSet(ctx, key)
		require.Nil(t, err)
	}
	{
		err := cli.CheckVPCPeeringConnection(ctx, key)
		require.Nil(t, err)
	}

	{
		err := cli.ReconcileCluster(ctx, key, false)
		require.Nil(t, err)
	}
	{
		err := cli.ReconcileVPC(ctx, key, false)
		require.Nil(t, err)
	}
	{
		err := cli.ReconcileAddress(ctx, key, false)
		require.Nil(t, err)
	}
	{
		err := cli.ReconcileInternetGateway(ctx, key, false)
		require.Nil(t, err)
	}

	{
		err := cli.ReconcileLaunchTemplate(ctx, key, false)
		require.Nil(t, err)
	}
	{
		err := cli.ReconcileNATGateway(ctx, key, false)
		require.Nil(t, err)
	}
	{
		err := cli.ReconcileRoute(ctx, key, false)
		require.Nil(t, err)
	}
	{
		err := cli.ReconcileRouteTable(ctx, key, false)
		require.Nil(t, err)
	}
	{
		err := cli.ReconcileSecurityGroup(ctx, key, false)
		require.Nil(t, err)
	}
	{
		err := cli.ReconcileSubnet(ctx, key, false)
		require.Nil(t, err)
	}
	{
		err := cli.ReconcileVPCEndpoint(ctx, key, false)
		require.Nil(t, err)
	}
	{
		err := cli.ReconcileVPCEndpointServiceConfiguration(ctx, key, false)
		require.Nil(t, err)
	}
	{
		err := cli.ReconcileNodeGroup(ctx, key, false)
		require.Nil(t, err)
	}
	{
		err := cli.ReconcileInstanceProfile(ctx, key, false)
		require.Nil(t, err)
	}
	{
		err := cli.ReconcilePolicy(ctx, key, false)
		require.Nil(t, err)
	}
	{
		err := cli.ReconcileRolePolicyAttachment(ctx, key, false)
		require.Nil(t, err)
	}
	{
		err := cli.ReconcileRole(ctx, key, false)
		require.Nil(t, err)
	}
	{
		err := cli.ReconcileResourceRecordSet(ctx, key, false)
		require.Nil(t, err)
	}
	{
		err := cli.ReconcileVPCPeeringConnection(ctx, key, false)
		require.Nil(t, err)
	}
}
