package regionalservercli

import (
	"bytes"
	"context"
	"encoding/json"
	"errors"
	"fmt"
	"io"
	"net/http"
	"net/url"
	"strconv"
	"time"

	_ "github.com/tidbcloud/infra-provider/regional-server/pkg/common/errors"
	"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"
)

type MigrationServiceAWSClient struct {
	endpoint   string
	httpClient *http.Client
}

func NewMigrationServiceAWSClient(endpoint string) *MigrationServiceAWSClient {
	return &MigrationServiceAWSClient{
		endpoint:   endpoint,
		httpClient: http.DefaultClient,
	}
}

func (c *MigrationServiceAWSClient) requestDoWithRetry(req *http.Request, retry int) ([]byte, error) {
	var lasterr error
	for i := retry; i >= 0; i-- {
		result, err := c.requestDo(req)
		if err == nil {
			return result, nil
		}
		if i > 0 {
			time.Sleep(500 * time.Millisecond)
		}
		lasterr = err
	}
	return nil, lasterr
}

func (c *MigrationServiceAWSClient) requestDo(req *http.Request) ([]byte, error) {
	resp, err := c.httpClient.Do(req)
	if err != nil {
		return nil, err
	}
	defer resp.Body.Close()
	data, err := io.ReadAll(resp.Body)
	if err != nil {
		return nil, err
	}
	if resp.StatusCode > 300 {
		return nil, errors.New(string(data))
	}
	return data, nil
}

func (c *MigrationServiceAWSClient) ImportCluster(ctx context.Context, cr *eksv1beta1.Cluster) error {
	bs, err := json.Marshal(cr)
	if err != nil {
		return err
	}
	req, err := http.NewRequestWithContext(ctx, http.MethodPost, fmt.Sprintf("%s/api/dedicated/v1/migration/crossplane/aws/import/cluster", c.endpoint), bytes.NewReader(bs))
	if err != nil {
		return err
	}
	_, err = c.requestDo(req)
	return err
}

func (c *MigrationServiceAWSClient) ImportVPC(ctx context.Context, cr *ec2v1beta1.VPC) error {
	bs, err := json.Marshal(cr)
	if err != nil {
		return err
	}
	req, err := http.NewRequestWithContext(ctx, http.MethodPost, fmt.Sprintf("%s/api/dedicated/v1/migration/crossplane/aws/import/vpc", c.endpoint), bytes.NewReader(bs))
	if err != nil {
		return err
	}
	_, err = c.requestDo(req)
	return err
}

func (c *MigrationServiceAWSClient) ImportProviderConfig(ctx context.Context, cr *xpv1beta1.ProviderConfig) error {
	bs, err := json.Marshal(cr)
	if err != nil {
		return err
	}
	req, err := http.NewRequestWithContext(ctx, http.MethodPost, fmt.Sprintf("%s/api/dedicated/v1/migration/crossplane/aws/import/providerconfig", c.endpoint), bytes.NewReader(bs))
	if err != nil {
		return err
	}
	_, err = c.requestDo(req)
	return err
}

func (c *MigrationServiceAWSClient) ImportAddress(ctx context.Context, cr *ec2v1beta1.Address) error {
	bs, err := json.Marshal(cr)
	if err != nil {
		return err
	}
	req, err := http.NewRequestWithContext(ctx, http.MethodPost, fmt.Sprintf("%s/api/dedicated/v1/migration/crossplane/aws/import/address", c.endpoint), bytes.NewReader(bs))
	if err != nil {
		return err
	}
	_, err = c.requestDo(req)
	return err
}

func (c *MigrationServiceAWSClient) ImportInternetGateway(ctx context.Context, cr *ec2v1beta1.InternetGateway) error {
	bs, err := json.Marshal(cr)
	if err != nil {
		return err
	}
	req, err := http.NewRequestWithContext(ctx, http.MethodPost, fmt.Sprintf("%s/api/dedicated/v1/migration/crossplane/aws/import/internetgateway", c.endpoint), bytes.NewReader(bs))
	if err != nil {
		return err
	}
	_, err = c.requestDo(req)
	return err
}

func (c *MigrationServiceAWSClient) ImportLaunchTemplate(ctx context.Context, cr *ec2v1alpha1.LaunchTemplate) error {
	bs, err := json.Marshal(cr)
	if err != nil {
		return err
	}
	req, err := http.NewRequestWithContext(ctx, http.MethodPost, fmt.Sprintf("%s/api/dedicated/v1/migration/crossplane/aws/import/launchtemplate", c.endpoint), bytes.NewReader(bs))
	if err != nil {
		return err
	}
	_, err = c.requestDo(req)
	return err
}

func (c *MigrationServiceAWSClient) ImportNATGateway(ctx context.Context, cr *ec2v1beta1.NATGateway) error {
	bs, err := json.Marshal(cr)
	if err != nil {
		return err
	}
	req, err := http.NewRequestWithContext(ctx, http.MethodPost, fmt.Sprintf("%s/api/dedicated/v1/migration/crossplane/aws/import/natgateway", c.endpoint), bytes.NewReader(bs))
	if err != nil {
		return err
	}
	_, err = c.requestDo(req)
	return err
}

func (c *MigrationServiceAWSClient) ImportRoute(ctx context.Context, cr *ec2v1alpha1.Route) error {
	bs, err := json.Marshal(cr)
	if err != nil {
		return err
	}
	req, err := http.NewRequestWithContext(ctx, http.MethodPost, fmt.Sprintf("%s/api/dedicated/v1/migration/crossplane/aws/import/route", c.endpoint), bytes.NewReader(bs))
	if err != nil {
		return err
	}
	_, err = c.requestDo(req)
	return err
}

func (c *MigrationServiceAWSClient) ImportRouteTable(ctx context.Context, cr *ec2v1beta1.RouteTable) error {
	bs, err := json.Marshal(cr)
	if err != nil {
		return err
	}
	req, err := http.NewRequestWithContext(ctx, http.MethodPost, fmt.Sprintf("%s/api/dedicated/v1/migration/crossplane/aws/import/routetable", c.endpoint), bytes.NewReader(bs))
	if err != nil {
		return err
	}
	_, err = c.requestDo(req)
	return err
}

func (c *MigrationServiceAWSClient) ImportSecurityGroup(ctx context.Context, cr *ec2v1beta1.SecurityGroup) error {
	bs, err := json.Marshal(cr)
	if err != nil {
		return err
	}
	req, err := http.NewRequestWithContext(ctx, http.MethodPost, fmt.Sprintf("%s/api/dedicated/v1/migration/crossplane/aws/import/securitygroup", c.endpoint), bytes.NewReader(bs))
	if err != nil {
		return err
	}
	_, err = c.requestDo(req)
	return err
}

func (c *MigrationServiceAWSClient) ImportSubnet(ctx context.Context, cr *ec2v1beta1.Subnet) error {
	bs, err := json.Marshal(cr)
	if err != nil {
		return err
	}
	req, err := http.NewRequestWithContext(ctx, http.MethodPost, fmt.Sprintf("%s/api/dedicated/v1/migration/crossplane/aws/import/subnet", c.endpoint), bytes.NewReader(bs))
	if err != nil {
		return err
	}
	_, err = c.requestDo(req)
	return err
}

func (c *MigrationServiceAWSClient) ImportVPCEndpoint(ctx context.Context, cr *ec2v1alpha1.VPCEndpoint) error {
	bs, err := json.Marshal(cr)
	if err != nil {
		return err
	}
	req, err := http.NewRequestWithContext(ctx, http.MethodPost, fmt.Sprintf("%s/api/dedicated/v1/migration/crossplane/aws/import/vpcendpoint", c.endpoint), bytes.NewReader(bs))
	if err != nil {
		return err
	}
	_, err = c.requestDo(req)
	return err
}

func (c *MigrationServiceAWSClient) ImportVPCEndpointServiceConfiguration(ctx context.Context, cr *ec2v1alpha1.VPCEndpointServiceConfiguration) error {
	bs, err := json.Marshal(cr)
	if err != nil {
		return err
	}
	req, err := http.NewRequestWithContext(ctx, http.MethodPost, fmt.Sprintf("%s/api/dedicated/v1/migration/crossplane/aws/import/vpcendpointserviceconfig", c.endpoint), bytes.NewReader(bs))
	if err != nil {
		return err
	}
	_, err = c.requestDo(req)
	return err
}

func (c *MigrationServiceAWSClient) ImportNodeGroup(ctx context.Context, cr *manualv1alpha1.NodeGroup) error {
	bs, err := json.Marshal(cr)
	if err != nil {
		return err
	}
	req, err := http.NewRequestWithContext(ctx, http.MethodPost, fmt.Sprintf("%s/api/dedicated/v1/migration/crossplane/aws/import/nodegroup", c.endpoint), bytes.NewReader(bs))
	if err != nil {
		return err
	}
	_, err = c.requestDo(req)
	return err
}

func (c *MigrationServiceAWSClient) ImportInstanceProfile(ctx context.Context, cr *iamv1alpha1.InstanceProfile) error {
	bs, err := json.Marshal(cr)
	if err != nil {
		return err
	}
	req, err := http.NewRequestWithContext(ctx, http.MethodPost, fmt.Sprintf("%s/api/dedicated/v1/migration/crossplane/aws/import/instanceprofile", c.endpoint), bytes.NewReader(bs))
	if err != nil {
		return err
	}
	_, err = c.requestDo(req)
	return err
}

func (c *MigrationServiceAWSClient) ImportPolicy(ctx context.Context, cr *iamv1beta1.Policy) error {
	bs, err := json.Marshal(cr)
	if err != nil {
		return err
	}
	req, err := http.NewRequestWithContext(ctx, http.MethodPost, fmt.Sprintf("%s/api/dedicated/v1/migration/crossplane/aws/import/policy", c.endpoint), bytes.NewReader(bs))
	if err != nil {
		return err
	}
	_, err = c.requestDo(req)
	return err
}

func (c *MigrationServiceAWSClient) ImportRolePolicyAttachment(ctx context.Context, cr *iamv1beta1.RolePolicyAttachment) error {
	bs, err := json.Marshal(cr)
	if err != nil {
		return err
	}
	req, err := http.NewRequestWithContext(ctx, http.MethodPost, fmt.Sprintf("%s/api/dedicated/v1/migration/crossplane/aws/import/rolepolicyattachment", c.endpoint), bytes.NewReader(bs))
	if err != nil {
		return err
	}
	_, err = c.requestDo(req)
	return err
}

func (c *MigrationServiceAWSClient) ImportRole(ctx context.Context, cr *iamv1beta1.Role) error {
	bs, err := json.Marshal(cr)
	if err != nil {
		return err
	}
	req, err := http.NewRequestWithContext(ctx, http.MethodPost, fmt.Sprintf("%s/api/dedicated/v1/migration/crossplane/aws/import/role", c.endpoint), bytes.NewReader(bs))
	if err != nil {
		return err
	}
	_, err = c.requestDo(req)
	return err
}

func (c *MigrationServiceAWSClient) ImportResourceRecordSet(ctx context.Context, cr *route53v1alpha1.ResourceRecordSet) error {
	bs, err := json.Marshal(cr)
	if err != nil {
		return err
	}
	req, err := http.NewRequestWithContext(ctx, http.MethodPost, fmt.Sprintf("%s/api/dedicated/v1/migration/crossplane/aws/import/resourcerecordset", c.endpoint), bytes.NewReader(bs))
	if err != nil {
		return err
	}
	_, err = c.requestDo(req)
	return err
}

func (c *MigrationServiceAWSClient) ImportVPCPeeringConnection(ctx context.Context, cr *ec2v1alpha1.VPCPeeringConnection) error {
	bs, err := json.Marshal(cr)
	if err != nil {
		return err
	}
	req, err := http.NewRequestWithContext(ctx, http.MethodPost, fmt.Sprintf("%s/api/dedicated/v1/migration/crossplane/aws/import/vpcpeeringconnection", c.endpoint), bytes.NewReader(bs))
	if err != nil {
		return err
	}
	_, err = c.requestDo(req)
	return err
}

func (c *MigrationServiceAWSClient) CheckCluster(ctx context.Context, key client.ObjectKey) error {
	query := make(url.Values)
	if key.Namespace != "" {
		query.Add("namespace", key.Namespace)
	}
	query.Add("name", key.Name)
	req, err := http.NewRequestWithContext(ctx, http.MethodGet, fmt.Sprintf("%s/api/dedicated/v1/migration/crossplane/aws/check/cluster?%s", c.endpoint, query.Encode()), nil)
	if err != nil {
		return err
	}
	_, err = c.requestDo(req)
	return err
}

func (c *MigrationServiceAWSClient) CheckVPC(ctx context.Context, key client.ObjectKey) error {
	query := make(url.Values)
	if key.Namespace != "" {
		query.Add("namespace", key.Namespace)
	}
	query.Add("name", key.Name)
	req, err := http.NewRequestWithContext(ctx, http.MethodGet, fmt.Sprintf("%s/api/dedicated/v1/migration/crossplane/aws/check/vpc?%s", c.endpoint, query.Encode()), nil)
	if err != nil {
		return err
	}
	_, err = c.requestDo(req)
	return err
}

func (c *MigrationServiceAWSClient) CheckAddress(ctx context.Context, key client.ObjectKey) error {
	query := make(url.Values)
	if key.Namespace != "" {
		query.Add("namespace", key.Namespace)
	}
	query.Add("name", key.Name)
	req, err := http.NewRequestWithContext(ctx, http.MethodGet, fmt.Sprintf("%s/api/dedicated/v1/migration/crossplane/aws/check/address?%s", c.endpoint, query.Encode()), nil)
	if err != nil {
		return err
	}
	_, err = c.requestDo(req)
	return err
}

func (c *MigrationServiceAWSClient) CheckInternetGateway(ctx context.Context, key client.ObjectKey) error {
	query := make(url.Values)
	if key.Namespace != "" {
		query.Add("namespace", key.Namespace)
	}
	query.Add("name", key.Name)
	req, err := http.NewRequestWithContext(ctx, http.MethodGet, fmt.Sprintf("%s/api/dedicated/v1/migration/crossplane/aws/check/internetgateway?%s", c.endpoint, query.Encode()), nil)
	if err != nil {
		return err
	}
	_, err = c.requestDo(req)
	return err
}

func (c *MigrationServiceAWSClient) CheckLaunchTemplate(ctx context.Context, key client.ObjectKey) error {
	query := make(url.Values)
	if key.Namespace != "" {
		query.Add("namespace", key.Namespace)
	}
	query.Add("name", key.Name)
	req, err := http.NewRequestWithContext(ctx, http.MethodGet, fmt.Sprintf("%s/api/dedicated/v1/migration/crossplane/aws/check/launchtemplate?%s", c.endpoint, query.Encode()), nil)
	if err != nil {
		return err
	}
	_, err = c.requestDo(req)
	return err
}

func (c *MigrationServiceAWSClient) CheckNATGateway(ctx context.Context, key client.ObjectKey) error {
	query := make(url.Values)
	if key.Namespace != "" {
		query.Add("namespace", key.Namespace)
	}
	query.Add("name", key.Name)
	req, err := http.NewRequestWithContext(ctx, http.MethodGet, fmt.Sprintf("%s/api/dedicated/v1/migration/crossplane/aws/check/natgateway?%s", c.endpoint, query.Encode()), nil)
	if err != nil {
		return err
	}
	_, err = c.requestDo(req)
	return err
}

func (c *MigrationServiceAWSClient) CheckRoute(ctx context.Context, key client.ObjectKey) error {
	query := make(url.Values)
	if key.Namespace != "" {
		query.Add("namespace", key.Namespace)
	}
	query.Add("name", key.Name)
	req, err := http.NewRequestWithContext(ctx, http.MethodGet, fmt.Sprintf("%s/api/dedicated/v1/migration/crossplane/aws/check/route?%s", c.endpoint, query.Encode()), nil)
	if err != nil {
		return err
	}
	_, err = c.requestDo(req)
	return err
}

func (c *MigrationServiceAWSClient) CheckRouteTable(ctx context.Context, key client.ObjectKey) error {
	query := make(url.Values)
	if key.Namespace != "" {
		query.Add("namespace", key.Namespace)
	}
	query.Add("name", key.Name)
	req, err := http.NewRequestWithContext(ctx, http.MethodGet, fmt.Sprintf("%s/api/dedicated/v1/migration/crossplane/aws/check/routetable?%s", c.endpoint, query.Encode()), nil)
	if err != nil {
		return err
	}
	_, err = c.requestDo(req)
	return err
}

func (c *MigrationServiceAWSClient) CheckSecurityGroup(ctx context.Context, key client.ObjectKey) error {
	query := make(url.Values)
	if key.Namespace != "" {
		query.Add("namespace", key.Namespace)
	}
	query.Add("name", key.Name)
	req, err := http.NewRequestWithContext(ctx, http.MethodGet, fmt.Sprintf("%s/api/dedicated/v1/migration/crossplane/aws/check/securitygroup?%s", c.endpoint, query.Encode()), nil)
	if err != nil {
		return err
	}
	_, err = c.requestDo(req)
	return err
}

func (c *MigrationServiceAWSClient) CheckSubnet(ctx context.Context, key client.ObjectKey) error {
	query := make(url.Values)
	if key.Namespace != "" {
		query.Add("namespace", key.Namespace)
	}
	query.Add("name", key.Name)
	req, err := http.NewRequestWithContext(ctx, http.MethodGet, fmt.Sprintf("%s/api/dedicated/v1/migration/crossplane/aws/check/subnet?%s", c.endpoint, query.Encode()), nil)
	if err != nil {
		return err
	}
	_, err = c.requestDo(req)
	return err
}

func (c *MigrationServiceAWSClient) CheckVPCEndpoint(ctx context.Context, key client.ObjectKey) error {
	query := make(url.Values)
	if key.Namespace != "" {
		query.Add("namespace", key.Namespace)
	}
	query.Add("name", key.Name)
	req, err := http.NewRequestWithContext(ctx, http.MethodGet, fmt.Sprintf("%s/api/dedicated/v1/migration/crossplane/aws/check/vpcendpoint?%s", c.endpoint, query.Encode()), nil)
	if err != nil {
		return err
	}
	_, err = c.requestDo(req)
	return err
}

func (c *MigrationServiceAWSClient) CheckVPCEndpointServiceConfiguration(ctx context.Context, key client.ObjectKey) error {
	query := make(url.Values)
	if key.Namespace != "" {
		query.Add("namespace", key.Namespace)
	}
	query.Add("name", key.Name)
	req, err := http.NewRequestWithContext(ctx, http.MethodGet, fmt.Sprintf("%s/api/dedicated/v1/migration/crossplane/aws/check/vpcendpointserviceconfig?%s", c.endpoint, query.Encode()), nil)
	if err != nil {
		return err
	}
	_, err = c.requestDo(req)
	return err
}
func (c *MigrationServiceAWSClient) CheckNodeGroup(ctx context.Context, key client.ObjectKey) error {
	query := make(url.Values)
	if key.Namespace != "" {
		query.Add("namespace", key.Namespace)
	}
	query.Add("name", key.Name)
	req, err := http.NewRequestWithContext(ctx, http.MethodGet, fmt.Sprintf("%s/api/dedicated/v1/migration/crossplane/aws/check/nodegroup?%s", c.endpoint, query.Encode()), nil)
	if err != nil {
		return err
	}
	_, err = c.requestDo(req)
	return err
}

func (c *MigrationServiceAWSClient) CheckInstanceProfile(ctx context.Context, key client.ObjectKey) error {
	query := make(url.Values)
	if key.Namespace != "" {
		query.Add("namespace", key.Namespace)
	}
	query.Add("name", key.Name)
	req, err := http.NewRequestWithContext(ctx, http.MethodGet, fmt.Sprintf("%s/api/dedicated/v1/migration/crossplane/aws/check/instanceprofile?%s", c.endpoint, query.Encode()), nil)
	if err != nil {
		return err
	}
	_, err = c.requestDo(req)
	return err
}
func (c *MigrationServiceAWSClient) CheckPolicy(ctx context.Context, key client.ObjectKey) error {
	query := make(url.Values)
	if key.Namespace != "" {
		query.Add("namespace", key.Namespace)
	}
	query.Add("name", key.Name)
	req, err := http.NewRequestWithContext(ctx, http.MethodGet, fmt.Sprintf("%s/api/dedicated/v1/migration/crossplane/aws/check/policy?%s", c.endpoint, query.Encode()), nil)
	if err != nil {
		return err
	}
	_, err = c.requestDo(req)
	return err
}

func (c *MigrationServiceAWSClient) CheckRolePolicyAttachment(ctx context.Context, key client.ObjectKey) error {
	query := make(url.Values)
	if key.Namespace != "" {
		query.Add("namespace", key.Namespace)
	}
	query.Add("name", key.Name)
	req, err := http.NewRequestWithContext(ctx, http.MethodGet, fmt.Sprintf("%s/api/dedicated/v1/migration/crossplane/aws/check/rolepolicyattachment?%s", c.endpoint, query.Encode()), nil)
	if err != nil {
		return err
	}
	_, err = c.requestDo(req)
	return err
}

func (c *MigrationServiceAWSClient) CheckRole(ctx context.Context, key client.ObjectKey) error {
	query := make(url.Values)
	if key.Namespace != "" {
		query.Add("namespace", key.Namespace)
	}
	query.Add("name", key.Name)
	req, err := http.NewRequestWithContext(ctx, http.MethodGet, fmt.Sprintf("%s/api/dedicated/v1/migration/crossplane/aws/check/role?%s", c.endpoint, query.Encode()), nil)
	if err != nil {
		return err
	}
	_, err = c.requestDo(req)
	return err
}

func (c *MigrationServiceAWSClient) CheckResourceRecordSet(ctx context.Context, key client.ObjectKey) error {
	query := make(url.Values)
	if key.Namespace != "" {
		query.Add("namespace", key.Namespace)
	}
	query.Add("name", key.Name)
	req, err := http.NewRequestWithContext(ctx, http.MethodGet, fmt.Sprintf("%s/api/dedicated/v1/migration/crossplane/aws/check/resourcerecordset?%s", c.endpoint, query.Encode()), nil)
	if err != nil {
		return err
	}
	_, err = c.requestDo(req)
	return err
}

func (c *MigrationServiceAWSClient) CheckVPCPeeringConnection(ctx context.Context, key client.ObjectKey) error {
	query := make(url.Values)
	if key.Namespace != "" {
		query.Add("namespace", key.Namespace)
	}
	query.Add("name", key.Name)
	req, err := http.NewRequestWithContext(ctx, http.MethodGet, fmt.Sprintf("%s/api/dedicated/v1/migration/crossplane/aws/check/vpcpeeringconnection?%s", c.endpoint, query.Encode()), nil)
	if err != nil {
		return err
	}
	_, err = c.requestDo(req)
	return err
}

func (c *MigrationServiceAWSClient) ReconcileCluster(ctx context.Context, key client.ObjectKey, pause bool) error {
	query := make(url.Values)
	if key.Namespace != "" {
		query.Add("namespace", key.Namespace)
	}
	query.Add("name", key.Name)
	query.Add("pause", strconv.FormatBool(pause))
	req, err := http.NewRequestWithContext(ctx, http.MethodPatch, fmt.Sprintf("%s/api/dedicated/v1/migration/crossplane/aws/reconcile/cluster?%s", c.endpoint, query.Encode()), nil)
	if err != nil {
		return err
	}
	_, err = c.requestDoWithRetry(req, 2)
	return err
}

func (c *MigrationServiceAWSClient) ReconcileVPC(ctx context.Context, key client.ObjectKey, pause bool) error {
	query := make(url.Values)
	if key.Namespace != "" {
		query.Add("namespace", key.Namespace)
	}
	query.Add("name", key.Name)
	query.Add("pause", strconv.FormatBool(pause))
	req, err := http.NewRequestWithContext(ctx, http.MethodPatch, fmt.Sprintf("%s/api/dedicated/v1/migration/crossplane/aws/reconcile/vpc?%s", c.endpoint, query.Encode()), nil)
	if err != nil {
		return err
	}
	_, err = c.requestDoWithRetry(req, 2)
	return err
}

func (c *MigrationServiceAWSClient) ReconcileAddress(ctx context.Context, key client.ObjectKey, pause bool) error {
	query := make(url.Values)
	if key.Namespace != "" {
		query.Add("namespace", key.Namespace)
	}
	query.Add("name", key.Name)
	query.Add("pause", strconv.FormatBool(pause))
	req, err := http.NewRequestWithContext(ctx, http.MethodPatch, fmt.Sprintf("%s/api/dedicated/v1/migration/crossplane/aws/reconcile/address?%s", c.endpoint, query.Encode()), nil)
	if err != nil {
		return err
	}
	_, err = c.requestDoWithRetry(req, 2)
	return err
}

func (c *MigrationServiceAWSClient) ReconcileInternetGateway(ctx context.Context, key client.ObjectKey, pause bool) error {
	query := make(url.Values)
	if key.Namespace != "" {
		query.Add("namespace", key.Namespace)
	}
	query.Add("name", key.Name)
	query.Add("pause", strconv.FormatBool(pause))
	req, err := http.NewRequestWithContext(ctx, http.MethodPatch, fmt.Sprintf("%s/api/dedicated/v1/migration/crossplane/aws/reconcile/internetgateway?%s", c.endpoint, query.Encode()), nil)
	if err != nil {
		return err
	}
	_, err = c.requestDoWithRetry(req, 2)
	return err
}

func (c *MigrationServiceAWSClient) ReconcileLaunchTemplate(ctx context.Context, key client.ObjectKey, pause bool) error {
	query := make(url.Values)
	if key.Namespace != "" {
		query.Add("namespace", key.Namespace)
	}
	query.Add("name", key.Name)
	query.Add("pause", strconv.FormatBool(pause))
	req, err := http.NewRequestWithContext(ctx, http.MethodPatch, fmt.Sprintf("%s/api/dedicated/v1/migration/crossplane/aws/reconcile/launchtemplate?%s", c.endpoint, query.Encode()), nil)
	if err != nil {
		return err
	}
	_, err = c.requestDoWithRetry(req, 2)
	return err
}

func (c *MigrationServiceAWSClient) ReconcileNATGateway(ctx context.Context, key client.ObjectKey, pause bool) error {
	query := make(url.Values)
	if key.Namespace != "" {
		query.Add("namespace", key.Namespace)
	}
	query.Add("name", key.Name)
	query.Add("pause", strconv.FormatBool(pause))
	req, err := http.NewRequestWithContext(ctx, http.MethodPatch, fmt.Sprintf("%s/api/dedicated/v1/migration/crossplane/aws/reconcile/natgateway?%s", c.endpoint, query.Encode()), nil)
	if err != nil {
		return err
	}
	_, err = c.requestDoWithRetry(req, 2)
	return err
}

func (c *MigrationServiceAWSClient) ReconcileRoute(ctx context.Context, key client.ObjectKey, pause bool) error {
	query := make(url.Values)
	if key.Namespace != "" {
		query.Add("namespace", key.Namespace)
	}
	query.Add("name", key.Name)
	query.Add("pause", strconv.FormatBool(pause))
	req, err := http.NewRequestWithContext(ctx, http.MethodPatch, fmt.Sprintf("%s/api/dedicated/v1/migration/crossplane/aws/reconcile/route?%s", c.endpoint, query.Encode()), nil)
	if err != nil {
		return err
	}
	_, err = c.requestDoWithRetry(req, 2)
	return err
}

func (c *MigrationServiceAWSClient) ReconcileRouteTable(ctx context.Context, key client.ObjectKey, pause bool) error {
	query := make(url.Values)
	if key.Namespace != "" {
		query.Add("namespace", key.Namespace)
	}
	query.Add("name", key.Name)
	query.Add("pause", strconv.FormatBool(pause))
	req, err := http.NewRequestWithContext(ctx, http.MethodPatch, fmt.Sprintf("%s/api/dedicated/v1/migration/crossplane/aws/reconcile/routetable?%s", c.endpoint, query.Encode()), nil)
	if err != nil {
		return err
	}
	_, err = c.requestDoWithRetry(req, 2)
	return err
}

func (c *MigrationServiceAWSClient) ReconcileSecurityGroup(ctx context.Context, key client.ObjectKey, pause bool) error {
	query := make(url.Values)
	if key.Namespace != "" {
		query.Add("namespace", key.Namespace)
	}
	query.Add("name", key.Name)
	query.Add("pause", strconv.FormatBool(pause))
	req, err := http.NewRequestWithContext(ctx, http.MethodPatch, fmt.Sprintf("%s/api/dedicated/v1/migration/crossplane/aws/reconcile/securitygroup?%s", c.endpoint, query.Encode()), nil)
	if err != nil {
		return err
	}
	_, err = c.requestDoWithRetry(req, 2)
	return err
}

func (c *MigrationServiceAWSClient) ReconcileSubnet(ctx context.Context, key client.ObjectKey, pause bool) error {
	query := make(url.Values)
	if key.Namespace != "" {
		query.Add("namespace", key.Namespace)
	}
	query.Add("name", key.Name)
	query.Add("pause", strconv.FormatBool(pause))
	req, err := http.NewRequestWithContext(ctx, http.MethodPatch, fmt.Sprintf("%s/api/dedicated/v1/migration/crossplane/aws/reconcile/subnet?%s", c.endpoint, query.Encode()), nil)
	if err != nil {
		return err
	}
	_, err = c.requestDoWithRetry(req, 2)
	return err
}

func (c *MigrationServiceAWSClient) ReconcileVPCEndpoint(ctx context.Context, key client.ObjectKey, pause bool) error {
	query := make(url.Values)
	if key.Namespace != "" {
		query.Add("namespace", key.Namespace)
	}
	query.Add("name", key.Name)
	query.Add("pause", strconv.FormatBool(pause))
	req, err := http.NewRequestWithContext(ctx, http.MethodPatch, fmt.Sprintf("%s/api/dedicated/v1/migration/crossplane/aws/reconcile/vpcendpoint?%s", c.endpoint, query.Encode()), nil)
	if err != nil {
		return err
	}
	_, err = c.requestDoWithRetry(req, 2)
	return err
}

func (c *MigrationServiceAWSClient) ReconcileVPCEndpointServiceConfiguration(ctx context.Context, key client.ObjectKey, pause bool) error {
	query := make(url.Values)
	if key.Namespace != "" {
		query.Add("namespace", key.Namespace)
	}
	query.Add("name", key.Name)
	query.Add("pause", strconv.FormatBool(pause))
	req, err := http.NewRequestWithContext(ctx, http.MethodPatch, fmt.Sprintf("%s/api/dedicated/v1/migration/crossplane/aws/reconcile/vpcendpointserviceconfig?%s", c.endpoint, query.Encode()), nil)
	if err != nil {
		return err
	}
	_, err = c.requestDoWithRetry(req, 2)
	return err
}

func (c *MigrationServiceAWSClient) ReconcileNodeGroup(ctx context.Context, key client.ObjectKey, pause bool) error {
	query := make(url.Values)
	if key.Namespace != "" {
		query.Add("namespace", key.Namespace)
	}
	query.Add("name", key.Name)
	query.Add("pause", strconv.FormatBool(pause))
	req, err := http.NewRequestWithContext(ctx, http.MethodPatch, fmt.Sprintf("%s/api/dedicated/v1/migration/crossplane/aws/reconcile/nodegroup?%s", c.endpoint, query.Encode()), nil)
	if err != nil {
		return err
	}
	_, err = c.requestDoWithRetry(req, 2)
	return err
}

func (c *MigrationServiceAWSClient) ReconcileInstanceProfile(ctx context.Context, key client.ObjectKey, pause bool) error {
	query := make(url.Values)
	if key.Namespace != "" {
		query.Add("namespace", key.Namespace)
	}
	query.Add("name", key.Name)
	query.Add("pause", strconv.FormatBool(pause))
	req, err := http.NewRequestWithContext(ctx, http.MethodPatch, fmt.Sprintf("%s/api/dedicated/v1/migration/crossplane/aws/reconcile/instanceprofile?%s", c.endpoint, query.Encode()), nil)
	if err != nil {
		return err
	}
	_, err = c.requestDoWithRetry(req, 2)
	return err
}

func (c *MigrationServiceAWSClient) ReconcilePolicy(ctx context.Context, key client.ObjectKey, pause bool) error {
	query := make(url.Values)
	if key.Namespace != "" {
		query.Add("namespace", key.Namespace)
	}
	query.Add("name", key.Name)
	query.Add("pause", strconv.FormatBool(pause))
	req, err := http.NewRequestWithContext(ctx, http.MethodPatch, fmt.Sprintf("%s/api/dedicated/v1/migration/crossplane/aws/reconcile/policy?%s", c.endpoint, query.Encode()), nil)
	if err != nil {
		return err
	}
	_, err = c.requestDoWithRetry(req, 2)
	return err
}

func (c *MigrationServiceAWSClient) ReconcileRolePolicyAttachment(ctx context.Context, key client.ObjectKey, pause bool) error {
	query := make(url.Values)
	if key.Namespace != "" {
		query.Add("namespace", key.Namespace)
	}
	query.Add("name", key.Name)
	query.Add("pause", strconv.FormatBool(pause))
	req, err := http.NewRequestWithContext(ctx, http.MethodPatch, fmt.Sprintf("%s/api/dedicated/v1/migration/crossplane/aws/reconcile/rolepolicyattachment?%s", c.endpoint, query.Encode()), nil)
	if err != nil {
		return err
	}
	_, err = c.requestDoWithRetry(req, 2)
	return err
}

func (c *MigrationServiceAWSClient) ReconcileRole(ctx context.Context, key client.ObjectKey, pause bool) error {
	query := make(url.Values)
	if key.Namespace != "" {
		query.Add("namespace", key.Namespace)
	}
	query.Add("name", key.Name)
	query.Add("pause", strconv.FormatBool(pause))
	req, err := http.NewRequestWithContext(ctx, http.MethodPatch, fmt.Sprintf("%s/api/dedicated/v1/migration/crossplane/aws/reconcile/role?%s", c.endpoint, query.Encode()), nil)
	if err != nil {
		return err
	}
	_, err = c.requestDoWithRetry(req, 2)
	return err
}

func (c *MigrationServiceAWSClient) ReconcileResourceRecordSet(ctx context.Context, key client.ObjectKey, pause bool) error {
	query := make(url.Values)
	if key.Namespace != "" {
		query.Add("namespace", key.Namespace)
	}
	query.Add("name", key.Name)
	query.Add("pause", strconv.FormatBool(pause))
	req, err := http.NewRequestWithContext(ctx, http.MethodPatch, fmt.Sprintf("%s/api/dedicated/v1/migration/crossplane/aws/reconcile/resourcerecordset?%s", c.endpoint, query.Encode()), nil)
	if err != nil {
		return err
	}
	_, err = c.requestDoWithRetry(req, 2)
	return err
}

func (c *MigrationServiceAWSClient) ReconcileVPCPeeringConnection(ctx context.Context, key client.ObjectKey, pause bool) error {
	query := make(url.Values)
	if key.Namespace != "" {
		query.Add("namespace", key.Namespace)
	}
	query.Add("name", key.Name)
	query.Add("pause", strconv.FormatBool(pause))
	req, err := http.NewRequestWithContext(ctx, http.MethodPatch, fmt.Sprintf("%s/api/dedicated/v1/migration/crossplane/aws/reconcile/vpcpeeringconnection?%s", c.endpoint, query.Encode()), nil)
	if err != nil {
		return err
	}
	_, err = c.requestDoWithRetry(req, 2)
	return err
}
