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"

	awsiamv1beta1 "github.com/crossplane-contrib/provider-aws/apis/iam/v1beta1"
	computev1alpha1 "github.com/crossplane-contrib/provider-gcp/apis/compute/v1alpha1"
	computev1beta1 "github.com/crossplane-contrib/provider-gcp/apis/compute/v1beta1"
	containerv1beta1 "github.com/crossplane-contrib/provider-gcp/apis/container/v1beta1"
	containerv1beta2 "github.com/crossplane-contrib/provider-gcp/apis/container/v1beta2"
	gcpiamv1alpha1 "github.com/crossplane-contrib/provider-gcp/apis/iam/v1alpha1" // this is a workaround
	storagev1alpha1 "github.com/crossplane-contrib/provider-gcp/apis/storage/v1alpha1"
	xpv1beta1 "github.com/crossplane-contrib/provider-gcp/apis/v1beta1" // this is a workaround
	vpcpeeringv1beta1 "github.com/crossplane/provider-gcp/apis/vpcpeering/v1beta1"
)

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

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

func (c *MigrationServiceGCPClient) 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 *MigrationServiceGCPClient) 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 *MigrationServiceGCPClient) ImportAddress(ctx context.Context, cr *computev1beta1.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/gcp/import/address", c.endpoint), bytes.NewReader(bs))
	if err != nil {
		return err
	}
	_, err = c.requestDo(req)
	return err
}

func (c *MigrationServiceGCPClient) ImportFirewall(ctx context.Context, cr *computev1alpha1.Firewall) 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/gcp/import/firewall", c.endpoint), bytes.NewReader(bs))
	if err != nil {
		return err
	}
	_, err = c.requestDo(req)
	return err
}

func (c *MigrationServiceGCPClient) ImportNetwork(ctx context.Context, cr *computev1beta1.Network) 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/gcp/import/network", c.endpoint), bytes.NewReader(bs))
	if err != nil {
		return err
	}
	_, err = c.requestDo(req)
	return err
}

func (c *MigrationServiceGCPClient) ImportRouter(ctx context.Context, cr *computev1alpha1.Router) 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/gcp/import/router", c.endpoint), bytes.NewReader(bs))
	if err != nil {
		return err
	}
	_, err = c.requestDo(req)
	return err
}

func (c *MigrationServiceGCPClient) ImportSubnetwork(ctx context.Context, cr *computev1beta1.Subnetwork) 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/gcp/import/subnetwork", c.endpoint), bytes.NewReader(bs))
	if err != nil {
		return err
	}
	_, err = c.requestDo(req)
	return err
}

func (c *MigrationServiceGCPClient) ImportCluster(ctx context.Context, cr *containerv1beta2.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/gcp/import/cluster", c.endpoint), bytes.NewReader(bs))
	if err != nil {
		return err
	}
	_, err = c.requestDo(req)
	return err
}

func (c *MigrationServiceGCPClient) ImportNodePool(ctx context.Context, cr *containerv1beta1.NodePool) 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/gcp/import/nodepool", c.endpoint), bytes.NewReader(bs))
	if err != nil {
		return err
	}
	_, err = c.requestDo(req)
	return err
}

func (c *MigrationServiceGCPClient) 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/gcp/import/providerconfig", c.endpoint), bytes.NewReader(bs))
	if err != nil {
		return err
	}
	_, err = c.requestDo(req)
	return err
}

func (c *MigrationServiceGCPClient) ImportServiceAccountKey(ctx context.Context, cr *gcpiamv1alpha1.ServiceAccountKey) 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/gcp/import/serviceaccountkey", c.endpoint), bytes.NewReader(bs))
	if err != nil {
		return err
	}
	_, err = c.requestDo(req)
	return err
}

func (c *MigrationServiceGCPClient) ImportServiceAccountPolicy(ctx context.Context, cr *gcpiamv1alpha1.ServiceAccountPolicy) 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/gcp/import/serviceaccountpolicy", c.endpoint), bytes.NewReader(bs))
	if err != nil {
		return err
	}
	_, err = c.requestDo(req)
	return err
}

func (c *MigrationServiceGCPClient) ImportServiceAccount(ctx context.Context, cr *gcpiamv1alpha1.ServiceAccount) 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/gcp/import/serviceaccount", c.endpoint), bytes.NewReader(bs))
	if err != nil {
		return err
	}
	_, err = c.requestDo(req)
	return err
}

func (c *MigrationServiceGCPClient) ImportBucketPolicyMember(ctx context.Context, cr *storagev1alpha1.BucketPolicyMember) 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/gcp/import/bucketpolicymember", c.endpoint), bytes.NewReader(bs))
	if err != nil {
		return err
	}
	_, err = c.requestDo(req)
	return err
}

func (c *MigrationServiceGCPClient) ImportPeering(ctx context.Context, cr *vpcpeeringv1beta1.Peering) 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/gcp/import/peering", c.endpoint), bytes.NewReader(bs))
	if err != nil {
		return err
	}
	_, err = c.requestDo(req)
	return err
}

func (c *MigrationServiceGCPClient) ImportOIDCProvider(ctx context.Context, cr *awsiamv1beta1.OpenIDConnectProvider) 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/gcp/import/openidconnectprovider", c.endpoint), bytes.NewReader(bs))
	if err != nil {
		return err
	}
	_, err = c.requestDo(req)
	return err
}

func (c *MigrationServiceGCPClient) ImportPolicy(ctx context.Context, cr *awsiamv1beta1.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/gcp/import/policy", c.endpoint), bytes.NewReader(bs))
	if err != nil {
		return err
	}
	_, err = c.requestDo(req)
	return err
}

func (c *MigrationServiceGCPClient) ImportRolePolicyAttachment(ctx context.Context, cr *awsiamv1beta1.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/gcp/import/rolepolicyattachment", c.endpoint), bytes.NewReader(bs))
	if err != nil {
		return err
	}
	_, err = c.requestDo(req)
	return err
}

func (c *MigrationServiceGCPClient) ImportRole(ctx context.Context, cr *awsiamv1beta1.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/gcp/import/role", c.endpoint), bytes.NewReader(bs))
	if err != nil {
		return err
	}
	_, err = c.requestDo(req)
	return err
}

func (c *MigrationServiceGCPClient) 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/gcp/check/address?%s", c.endpoint, query.Encode()), nil)
	if err != nil {
		return err
	}
	_, err = c.requestDo(req)
	return err
}

func (c *MigrationServiceGCPClient) CheckFirewall(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/gcp/check/firewall?%s", c.endpoint, query.Encode()), nil)
	if err != nil {
		return err
	}
	_, err = c.requestDo(req)
	return err
}

func (c *MigrationServiceGCPClient) CheckNetwork(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/gcp/check/network?%s", c.endpoint, query.Encode()), nil)
	if err != nil {
		return err
	}
	_, err = c.requestDo(req)
	return err
}

func (c *MigrationServiceGCPClient) CheckRouter(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/gcp/check/router?%s", c.endpoint, query.Encode()), nil)
	if err != nil {
		return err
	}
	_, err = c.requestDo(req)
	return err
}

func (c *MigrationServiceGCPClient) CheckSubnetwork(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/gcp/check/subnetwork?%s", c.endpoint, query.Encode()), nil)
	if err != nil {
		return err
	}
	_, err = c.requestDo(req)
	return err
}

func (c *MigrationServiceGCPClient) 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/gcp/check/cluster?%s", c.endpoint, query.Encode()), nil)
	if err != nil {
		return err
	}
	_, err = c.requestDo(req)
	return err
}

func (c *MigrationServiceGCPClient) CheckNodePool(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/gcp/check/nodepool?%s", c.endpoint, query.Encode()), nil)
	if err != nil {
		return err
	}
	_, err = c.requestDo(req)
	return err
}

func (c *MigrationServiceGCPClient) CheckServiceAccountKey(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/gcp/check/serviceaccountkey?%s", c.endpoint, query.Encode()), nil)
	if err != nil {
		return err
	}
	_, err = c.requestDo(req)
	return err
}

func (c *MigrationServiceGCPClient) CheckServiceAccountPolicy(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/gcp/check/serviceaccountpolicy?%s", c.endpoint, query.Encode()), nil)
	if err != nil {
		return err
	}
	_, err = c.requestDo(req)
	return err
}

func (c *MigrationServiceGCPClient) CheckServiceAccount(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/gcp/check/serviceaccount?%s", c.endpoint, query.Encode()), nil)
	if err != nil {
		return err
	}
	_, err = c.requestDo(req)
	return err
}

func (c *MigrationServiceGCPClient) CheckBucketPolicyMember(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/gcp/check/bucketpolicymember?%s", c.endpoint, query.Encode()), nil)
	if err != nil {
		return err
	}
	_, err = c.requestDo(req)
	return err
}

func (c *MigrationServiceGCPClient) CheckPeering(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/gcp/check/peering?%s", c.endpoint, query.Encode()), nil)
	if err != nil {
		return err
	}
	_, err = c.requestDo(req)
	return err
}

func (c *MigrationServiceGCPClient) CheckOIDCProvider(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/gcp/check/openidconnectprovider?%s", c.endpoint, query.Encode()), nil)
	if err != nil {
		return err
	}
	_, err = c.requestDo(req)
	return err
}

func (c *MigrationServiceGCPClient) 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/gcp/check/policy?%s", c.endpoint, query.Encode()), nil)
	if err != nil {
		return err
	}
	_, err = c.requestDo(req)
	return err
}

func (c *MigrationServiceGCPClient) 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/gcp/check/rolepolicyattachment?%s", c.endpoint, query.Encode()), nil)
	if err != nil {
		return err
	}
	_, err = c.requestDo(req)
	return err
}

func (c *MigrationServiceGCPClient) 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/gcp/check/role?%s", c.endpoint, query.Encode()), nil)
	if err != nil {
		return err
	}
	_, err = c.requestDo(req)
	return err
}

func (c *MigrationServiceGCPClient) 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/gcp/reconcile/address?%s", c.endpoint, query.Encode()), nil)
	if err != nil {
		return err
	}
	_, err = c.requestDoWithRetry(req, 2)
	return err
}

func (c *MigrationServiceGCPClient) ReconcileFirewall(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/gcp/reconcile/firewall?%s", c.endpoint, query.Encode()), nil)
	if err != nil {
		return err
	}
	_, err = c.requestDoWithRetry(req, 2)
	return err
}
func (c *MigrationServiceGCPClient) ReconcileNetwork(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/gcp/reconcile/network?%s", c.endpoint, query.Encode()), nil)
	if err != nil {
		return err
	}
	_, err = c.requestDoWithRetry(req, 2)
	return err
}

func (c *MigrationServiceGCPClient) ReconcileRouter(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/gcp/reconcile/router?%s", c.endpoint, query.Encode()), nil)
	if err != nil {
		return err
	}
	_, err = c.requestDoWithRetry(req, 2)
	return err
}

func (c *MigrationServiceGCPClient) ReconcileSubnetwork(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/gcp/reconcile/subnetwork?%s", c.endpoint, query.Encode()), nil)
	if err != nil {
		return err
	}
	_, err = c.requestDoWithRetry(req, 2)
	return err
}

func (c *MigrationServiceGCPClient) 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/gcp/reconcile/cluster?%s", c.endpoint, query.Encode()), nil)
	if err != nil {
		return err
	}
	_, err = c.requestDoWithRetry(req, 2)
	return err
}

func (c *MigrationServiceGCPClient) ReconcileNodePool(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/gcp/reconcile/nodepool?%s", c.endpoint, query.Encode()), nil)
	if err != nil {
		return err
	}
	_, err = c.requestDoWithRetry(req, 2)
	return err
}

func (c *MigrationServiceGCPClient) ReconcileServiceAccountKey(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/gcp/reconcile/serviceaccountkey?%s", c.endpoint, query.Encode()), nil)
	if err != nil {
		return err
	}
	_, err = c.requestDoWithRetry(req, 2)
	return err
}

func (c *MigrationServiceGCPClient) ReconcileServiceAccountPolicy(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/gcp/reconcile/serviceaccountpolicy?%s", c.endpoint, query.Encode()), nil)
	if err != nil {
		return err
	}
	_, err = c.requestDoWithRetry(req, 2)
	return err
}
func (c *MigrationServiceGCPClient) ReconcileServiceAccount(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/gcp/reconcile/serviceaccount?%s", c.endpoint, query.Encode()), nil)
	if err != nil {
		return err
	}
	_, err = c.requestDoWithRetry(req, 2)
	return err
}

func (c *MigrationServiceGCPClient) ReconcileBucketPolicyMember(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/gcp/reconcile/bucketpolicymember?%s", c.endpoint, query.Encode()), nil)
	if err != nil {
		return err
	}
	_, err = c.requestDoWithRetry(req, 2)
	return err
}

func (c *MigrationServiceGCPClient) ReconcilePeering(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/gcp/reconcile/peering?%s", c.endpoint, query.Encode()), nil)
	if err != nil {
		return err
	}
	_, err = c.requestDoWithRetry(req, 2)
	return err
}

func (c *MigrationServiceGCPClient) ReconcileOIDCProvider(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/gcp/reconcile/openidconnectprovider?%s", c.endpoint, query.Encode()), nil)
	if err != nil {
		return err
	}
	_, err = c.requestDoWithRetry(req, 2)
	return err
}

func (c *MigrationServiceGCPClient) 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/gcp/reconcile/policy?%s", c.endpoint, query.Encode()), nil)
	if err != nil {
		return err
	}
	_, err = c.requestDoWithRetry(req, 2)
	return err
}

func (c *MigrationServiceGCPClient) 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/gcp/reconcile/rolepolicyattachment?%s", c.endpoint, query.Encode()), nil)
	if err != nil {
		return err
	}
	_, err = c.requestDoWithRetry(req, 2)
	return err
}

func (c *MigrationServiceGCPClient) 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/gcp/reconcile/role?%s", c.endpoint, query.Encode()), nil)
	if err != nil {
		return err
	}
	_, err = c.requestDoWithRetry(req, 2)
	return err
}
