// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
// Code generated by Microsoft (R) Go Code Generator. DO NOT EDIT.

package armresiliencemanagement

import (
	"context"
	"errors"
	"github.com/Azure/azure-sdk-for-go/sdk/azcore"
	"github.com/Azure/azure-sdk-for-go/sdk/azcore/arm"
	"github.com/Azure/azure-sdk-for-go/sdk/azcore/policy"
	"github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime"
	"net/http"
	"net/url"
	"strings"
)

// RecoveryJobsClient - Operations for managing recovery jobs.
// Don't use this type directly, use NewRecoveryJobsClient() instead.
//
// Generated from API version 2026-04-01-preview
type RecoveryJobsClient struct {
	internal *arm.Client
}

// NewRecoveryJobsClient creates a new instance of RecoveryJobsClient with the specified values.
//   - credential - used to authorize requests. Usually a credential from azidentity.
//   - options - Contains optional client configuration. Pass nil to accept the default values.
func NewRecoveryJobsClient(credential azcore.TokenCredential, options *arm.ClientOptions) (*RecoveryJobsClient, error) {
	cl, err := arm.NewClient(moduleName, moduleVersion, credential, options)
	if err != nil {
		return nil, err
	}
	client := &RecoveryJobsClient{
		internal: cl,
	}
	return client, nil
}

// BeginCancel - This action attempts to cancel the ongoing recovery orchestration job.
// If the operation fails it returns an *azcore.ResponseError type.
//   - serviceGroupName - The name of the service group.
//   - operationID - A GUID that represents the Long Running OperationId.
//   - recoveryPlanName - The name of the recovery orchestration plan.
//   - recoveryJobName - The unique name (GUID) of the recovery job.
//   - body - The content of the action request
//   - options - RecoveryJobsClientBeginCancelOptions contains the optional parameters for the RecoveryJobsClient.BeginCancel
//     method.
func (client *RecoveryJobsClient) BeginCancel(ctx context.Context, serviceGroupName string, operationID string, recoveryPlanName string, recoveryJobName string, body RecoveryActionRequest, options *RecoveryJobsClientBeginCancelOptions) (*runtime.Poller[RecoveryJobsClientCancelResponse], error) {
	if options == nil || options.ResumeToken == "" {
		resp, err := client.cancel(ctx, serviceGroupName, operationID, recoveryPlanName, recoveryJobName, body, options)
		if err != nil {
			return nil, err
		}
		poller, err := runtime.NewPoller(resp, client.internal.Pipeline(), &runtime.NewPollerOptions[RecoveryJobsClientCancelResponse]{
			Tracer: client.internal.Tracer(),
		})
		return poller, err
	} else {
		return runtime.NewPollerFromResumeToken(options.ResumeToken, client.internal.Pipeline(), &runtime.NewPollerFromResumeTokenOptions[RecoveryJobsClientCancelResponse]{
			Tracer: client.internal.Tracer(),
		})
	}
}

// Cancel - This action attempts to cancel the ongoing recovery orchestration job.
// If the operation fails it returns an *azcore.ResponseError type.
func (client *RecoveryJobsClient) cancel(ctx context.Context, serviceGroupName string, operationID string, recoveryPlanName string, recoveryJobName string, body RecoveryActionRequest, options *RecoveryJobsClientBeginCancelOptions) (*http.Response, error) {
	var err error
	const operationName = "RecoveryJobsClient.BeginCancel"
	ctx = context.WithValue(ctx, runtime.CtxAPINameKey{}, operationName)
	ctx, endSpan := runtime.StartSpan(ctx, operationName, client.internal.Tracer(), nil)
	defer func() { endSpan(err) }()
	req, err := client.cancelCreateRequest(ctx, serviceGroupName, operationID, recoveryPlanName, recoveryJobName, body, options)
	if err != nil {
		return nil, err
	}
	httpResp, err := client.internal.Pipeline().Do(req)
	if err != nil {
		return nil, err
	}
	if !runtime.HasStatusCode(httpResp, http.StatusAccepted) {
		err = runtime.NewResponseError(httpResp)
		return nil, err
	}
	return httpResp, nil
}

// cancelCreateRequest creates the Cancel request.
func (client *RecoveryJobsClient) cancelCreateRequest(ctx context.Context, serviceGroupName string, operationID string, recoveryPlanName string, recoveryJobName string, body RecoveryActionRequest, _ *RecoveryJobsClientBeginCancelOptions) (*policy.Request, error) {
	urlPath := "/providers/Microsoft.Management/serviceGroups/{serviceGroupName}/providers/Microsoft.AzureResilienceManagement/recoveryPlans/{recoveryPlanName}/recoveryJobs/{recoveryJobName}/cancel"
	if serviceGroupName == "" {
		return nil, errors.New("parameter serviceGroupName cannot be empty")
	}
	urlPath = strings.ReplaceAll(urlPath, "{serviceGroupName}", url.PathEscape(serviceGroupName))
	if recoveryPlanName == "" {
		return nil, errors.New("parameter recoveryPlanName cannot be empty")
	}
	urlPath = strings.ReplaceAll(urlPath, "{recoveryPlanName}", url.PathEscape(recoveryPlanName))
	if recoveryJobName == "" {
		return nil, errors.New("parameter recoveryJobName cannot be empty")
	}
	urlPath = strings.ReplaceAll(urlPath, "{recoveryJobName}", url.PathEscape(recoveryJobName))
	req, err := runtime.NewRequest(ctx, http.MethodPost, runtime.JoinPaths(client.internal.Endpoint(), urlPath))
	if err != nil {
		return nil, err
	}
	reqQP := req.Raw().URL.Query()
	reqQP.Set("api-version", version20260401Preview)
	req.Raw().URL.RawQuery = strings.ReplaceAll(reqQP.Encode(), "+", "%20")
	req.Raw().Header["operation-id"] = []string{operationID}
	req.Raw().Header["Content-Type"] = []string{"application/json"}
	if err := runtime.MarshalAsJSON(req, body); err != nil {
		return nil, err
	}
	return req, nil
}

// Get - Get a RecoveryJob
// If the operation fails it returns an *azcore.ResponseError type.
//   - serviceGroupName - The name of the service group.
//   - recoveryPlanName - The name of the recovery orchestration plan.
//   - recoveryJobName - The unique name (GUID) of the recovery job.
//   - options - RecoveryJobsClientGetOptions contains the optional parameters for the RecoveryJobsClient.Get method.
func (client *RecoveryJobsClient) Get(ctx context.Context, serviceGroupName string, recoveryPlanName string, recoveryJobName string, options *RecoveryJobsClientGetOptions) (RecoveryJobsClientGetResponse, error) {
	var err error
	const operationName = "RecoveryJobsClient.Get"
	ctx = context.WithValue(ctx, runtime.CtxAPINameKey{}, operationName)
	ctx, endSpan := runtime.StartSpan(ctx, operationName, client.internal.Tracer(), nil)
	defer func() { endSpan(err) }()
	req, err := client.getCreateRequest(ctx, serviceGroupName, recoveryPlanName, recoveryJobName, options)
	if err != nil {
		return RecoveryJobsClientGetResponse{}, err
	}
	httpResp, err := client.internal.Pipeline().Do(req)
	if err != nil {
		return RecoveryJobsClientGetResponse{}, err
	}
	if !runtime.HasStatusCode(httpResp, http.StatusOK) {
		err = runtime.NewResponseError(httpResp)
		return RecoveryJobsClientGetResponse{}, err
	}
	resp, err := client.getHandleResponse(httpResp)
	return resp, err
}

// getCreateRequest creates the Get request.
func (client *RecoveryJobsClient) getCreateRequest(ctx context.Context, serviceGroupName string, recoveryPlanName string, recoveryJobName string, _ *RecoveryJobsClientGetOptions) (*policy.Request, error) {
	urlPath := "/providers/Microsoft.Management/serviceGroups/{serviceGroupName}/providers/Microsoft.AzureResilienceManagement/recoveryPlans/{recoveryPlanName}/recoveryJobs/{recoveryJobName}"
	if serviceGroupName == "" {
		return nil, errors.New("parameter serviceGroupName cannot be empty")
	}
	urlPath = strings.ReplaceAll(urlPath, "{serviceGroupName}", url.PathEscape(serviceGroupName))
	if recoveryPlanName == "" {
		return nil, errors.New("parameter recoveryPlanName cannot be empty")
	}
	urlPath = strings.ReplaceAll(urlPath, "{recoveryPlanName}", url.PathEscape(recoveryPlanName))
	if recoveryJobName == "" {
		return nil, errors.New("parameter recoveryJobName cannot be empty")
	}
	urlPath = strings.ReplaceAll(urlPath, "{recoveryJobName}", url.PathEscape(recoveryJobName))
	req, err := runtime.NewRequest(ctx, http.MethodGet, runtime.JoinPaths(client.internal.Endpoint(), urlPath))
	if err != nil {
		return nil, err
	}
	reqQP := req.Raw().URL.Query()
	reqQP.Set("api-version", version20260401Preview)
	req.Raw().URL.RawQuery = strings.ReplaceAll(reqQP.Encode(), "+", "%20")
	req.Raw().Header["Accept"] = []string{"application/json"}
	return req, nil
}

// getHandleResponse handles the Get response.
func (client *RecoveryJobsClient) getHandleResponse(resp *http.Response) (RecoveryJobsClientGetResponse, error) {
	result := RecoveryJobsClientGetResponse{}
	if err := runtime.UnmarshalAsJSON(resp, &result.RecoveryJob); err != nil {
		return RecoveryJobsClientGetResponse{}, err
	}
	return result, nil
}

// NewListPager - List RecoveryJob resources by RecoveryPlan
//   - serviceGroupName - The name of the service group.
//   - recoveryPlanName - The name of the recovery orchestration plan.
//   - options - RecoveryJobsClientListOptions contains the optional parameters for the RecoveryJobsClient.NewListPager method.
func (client *RecoveryJobsClient) NewListPager(serviceGroupName string, recoveryPlanName string, options *RecoveryJobsClientListOptions) *runtime.Pager[RecoveryJobsClientListResponse] {
	return runtime.NewPager(runtime.PagingHandler[RecoveryJobsClientListResponse]{
		More: func(page RecoveryJobsClientListResponse) bool {
			return page.NextLink != nil && len(*page.NextLink) > 0
		},
		Fetcher: func(ctx context.Context, page *RecoveryJobsClientListResponse) (RecoveryJobsClientListResponse, error) {
			ctx = context.WithValue(ctx, runtime.CtxAPINameKey{}, "RecoveryJobsClient.NewListPager")
			nextLink := ""
			if page != nil {
				nextLink = *page.NextLink
			}
			resp, err := runtime.FetcherForNextLink(ctx, client.internal.Pipeline(), nextLink, func(ctx context.Context) (*policy.Request, error) {
				return client.listCreateRequest(ctx, serviceGroupName, recoveryPlanName, options)
			}, nil)
			if err != nil {
				return RecoveryJobsClientListResponse{}, err
			}
			return client.listHandleResponse(resp)
		},
		Tracer: client.internal.Tracer(),
	})
}

// listCreateRequest creates the List request.
func (client *RecoveryJobsClient) listCreateRequest(ctx context.Context, serviceGroupName string, recoveryPlanName string, _ *RecoveryJobsClientListOptions) (*policy.Request, error) {
	urlPath := "/providers/Microsoft.Management/serviceGroups/{serviceGroupName}/providers/Microsoft.AzureResilienceManagement/recoveryPlans/{recoveryPlanName}/recoveryJobs"
	if serviceGroupName == "" {
		return nil, errors.New("parameter serviceGroupName cannot be empty")
	}
	urlPath = strings.ReplaceAll(urlPath, "{serviceGroupName}", url.PathEscape(serviceGroupName))
	if recoveryPlanName == "" {
		return nil, errors.New("parameter recoveryPlanName cannot be empty")
	}
	urlPath = strings.ReplaceAll(urlPath, "{recoveryPlanName}", url.PathEscape(recoveryPlanName))
	req, err := runtime.NewRequest(ctx, http.MethodGet, runtime.JoinPaths(client.internal.Endpoint(), urlPath))
	if err != nil {
		return nil, err
	}
	reqQP := req.Raw().URL.Query()
	reqQP.Set("api-version", version20260401Preview)
	req.Raw().URL.RawQuery = strings.ReplaceAll(reqQP.Encode(), "+", "%20")
	req.Raw().Header["Accept"] = []string{"application/json"}
	return req, nil
}

// listHandleResponse handles the List response.
func (client *RecoveryJobsClient) listHandleResponse(resp *http.Response) (RecoveryJobsClientListResponse, error) {
	result := RecoveryJobsClientListResponse{}
	if err := runtime.UnmarshalAsJSON(resp, &result.RecoveryJobListResult); err != nil {
		return RecoveryJobsClientListResponse{}, err
	}
	return result, nil
}

// BeginResume - This action resumes the ongoing recovery orchestration job that was paused for required user intervention.
// If the operation fails it returns an *azcore.ResponseError type.
//   - serviceGroupName - The name of the service group.
//   - operationID - A GUID that represents the Long Running OperationId.
//   - recoveryPlanName - The name of the recovery orchestration plan.
//   - recoveryJobName - The unique name (GUID) of the recovery job.
//   - body - The content of the action request
//   - options - RecoveryJobsClientBeginResumeOptions contains the optional parameters for the RecoveryJobsClient.BeginResume
//     method.
func (client *RecoveryJobsClient) BeginResume(ctx context.Context, serviceGroupName string, operationID string, recoveryPlanName string, recoveryJobName string, body RecoveryActionRequest, options *RecoveryJobsClientBeginResumeOptions) (*runtime.Poller[RecoveryJobsClientResumeResponse], error) {
	if options == nil || options.ResumeToken == "" {
		resp, err := client.resume(ctx, serviceGroupName, operationID, recoveryPlanName, recoveryJobName, body, options)
		if err != nil {
			return nil, err
		}
		poller, err := runtime.NewPoller(resp, client.internal.Pipeline(), &runtime.NewPollerOptions[RecoveryJobsClientResumeResponse]{
			Tracer: client.internal.Tracer(),
		})
		return poller, err
	} else {
		return runtime.NewPollerFromResumeToken(options.ResumeToken, client.internal.Pipeline(), &runtime.NewPollerFromResumeTokenOptions[RecoveryJobsClientResumeResponse]{
			Tracer: client.internal.Tracer(),
		})
	}
}

// Resume - This action resumes the ongoing recovery orchestration job that was paused for required user intervention.
// If the operation fails it returns an *azcore.ResponseError type.
func (client *RecoveryJobsClient) resume(ctx context.Context, serviceGroupName string, operationID string, recoveryPlanName string, recoveryJobName string, body RecoveryActionRequest, options *RecoveryJobsClientBeginResumeOptions) (*http.Response, error) {
	var err error
	const operationName = "RecoveryJobsClient.BeginResume"
	ctx = context.WithValue(ctx, runtime.CtxAPINameKey{}, operationName)
	ctx, endSpan := runtime.StartSpan(ctx, operationName, client.internal.Tracer(), nil)
	defer func() { endSpan(err) }()
	req, err := client.resumeCreateRequest(ctx, serviceGroupName, operationID, recoveryPlanName, recoveryJobName, body, options)
	if err != nil {
		return nil, err
	}
	httpResp, err := client.internal.Pipeline().Do(req)
	if err != nil {
		return nil, err
	}
	if !runtime.HasStatusCode(httpResp, http.StatusAccepted) {
		err = runtime.NewResponseError(httpResp)
		return nil, err
	}
	return httpResp, nil
}

// resumeCreateRequest creates the Resume request.
func (client *RecoveryJobsClient) resumeCreateRequest(ctx context.Context, serviceGroupName string, operationID string, recoveryPlanName string, recoveryJobName string, body RecoveryActionRequest, _ *RecoveryJobsClientBeginResumeOptions) (*policy.Request, error) {
	urlPath := "/providers/Microsoft.Management/serviceGroups/{serviceGroupName}/providers/Microsoft.AzureResilienceManagement/recoveryPlans/{recoveryPlanName}/recoveryJobs/{recoveryJobName}/resume"
	if serviceGroupName == "" {
		return nil, errors.New("parameter serviceGroupName cannot be empty")
	}
	urlPath = strings.ReplaceAll(urlPath, "{serviceGroupName}", url.PathEscape(serviceGroupName))
	if recoveryPlanName == "" {
		return nil, errors.New("parameter recoveryPlanName cannot be empty")
	}
	urlPath = strings.ReplaceAll(urlPath, "{recoveryPlanName}", url.PathEscape(recoveryPlanName))
	if recoveryJobName == "" {
		return nil, errors.New("parameter recoveryJobName cannot be empty")
	}
	urlPath = strings.ReplaceAll(urlPath, "{recoveryJobName}", url.PathEscape(recoveryJobName))
	req, err := runtime.NewRequest(ctx, http.MethodPost, runtime.JoinPaths(client.internal.Endpoint(), urlPath))
	if err != nil {
		return nil, err
	}
	reqQP := req.Raw().URL.Query()
	reqQP.Set("api-version", version20260401Preview)
	req.Raw().URL.RawQuery = strings.ReplaceAll(reqQP.Encode(), "+", "%20")
	req.Raw().Header["operation-id"] = []string{operationID}
	req.Raw().Header["Content-Type"] = []string{"application/json"}
	if err := runtime.MarshalAsJSON(req, body); err != nil {
		return nil, err
	}
	return req, nil
}

// BeginRetry - This action retries the ongoing recovery orchestration job for resources that failed in previous attempts.
// If the operation fails it returns an *azcore.ResponseError type.
//   - serviceGroupName - The name of the service group.
//   - operationID - A GUID that represents the Long Running OperationId.
//   - recoveryPlanName - The name of the recovery orchestration plan.
//   - recoveryJobName - The unique name (GUID) of the recovery job.
//   - options - RecoveryJobsClientBeginRetryOptions contains the optional parameters for the RecoveryJobsClient.BeginRetry method.
func (client *RecoveryJobsClient) BeginRetry(ctx context.Context, serviceGroupName string, operationID string, recoveryPlanName string, recoveryJobName string, options *RecoveryJobsClientBeginRetryOptions) (*runtime.Poller[RecoveryJobsClientRetryResponse], error) {
	if options == nil || options.ResumeToken == "" {
		resp, err := client.retry(ctx, serviceGroupName, operationID, recoveryPlanName, recoveryJobName, options)
		if err != nil {
			return nil, err
		}
		poller, err := runtime.NewPoller(resp, client.internal.Pipeline(), &runtime.NewPollerOptions[RecoveryJobsClientRetryResponse]{
			Tracer: client.internal.Tracer(),
		})
		return poller, err
	} else {
		return runtime.NewPollerFromResumeToken(options.ResumeToken, client.internal.Pipeline(), &runtime.NewPollerFromResumeTokenOptions[RecoveryJobsClientRetryResponse]{
			Tracer: client.internal.Tracer(),
		})
	}
}

// Retry - This action retries the ongoing recovery orchestration job for resources that failed in previous attempts.
// If the operation fails it returns an *azcore.ResponseError type.
func (client *RecoveryJobsClient) retry(ctx context.Context, serviceGroupName string, operationID string, recoveryPlanName string, recoveryJobName string, options *RecoveryJobsClientBeginRetryOptions) (*http.Response, error) {
	var err error
	const operationName = "RecoveryJobsClient.BeginRetry"
	ctx = context.WithValue(ctx, runtime.CtxAPINameKey{}, operationName)
	ctx, endSpan := runtime.StartSpan(ctx, operationName, client.internal.Tracer(), nil)
	defer func() { endSpan(err) }()
	req, err := client.retryCreateRequest(ctx, serviceGroupName, operationID, recoveryPlanName, recoveryJobName, options)
	if err != nil {
		return nil, err
	}
	httpResp, err := client.internal.Pipeline().Do(req)
	if err != nil {
		return nil, err
	}
	if !runtime.HasStatusCode(httpResp, http.StatusAccepted) {
		err = runtime.NewResponseError(httpResp)
		return nil, err
	}
	return httpResp, nil
}

// retryCreateRequest creates the Retry request.
func (client *RecoveryJobsClient) retryCreateRequest(ctx context.Context, serviceGroupName string, operationID string, recoveryPlanName string, recoveryJobName string, _ *RecoveryJobsClientBeginRetryOptions) (*policy.Request, error) {
	urlPath := "/providers/Microsoft.Management/serviceGroups/{serviceGroupName}/providers/Microsoft.AzureResilienceManagement/recoveryPlans/{recoveryPlanName}/recoveryJobs/{recoveryJobName}/retry"
	if serviceGroupName == "" {
		return nil, errors.New("parameter serviceGroupName cannot be empty")
	}
	urlPath = strings.ReplaceAll(urlPath, "{serviceGroupName}", url.PathEscape(serviceGroupName))
	if recoveryPlanName == "" {
		return nil, errors.New("parameter recoveryPlanName cannot be empty")
	}
	urlPath = strings.ReplaceAll(urlPath, "{recoveryPlanName}", url.PathEscape(recoveryPlanName))
	if recoveryJobName == "" {
		return nil, errors.New("parameter recoveryJobName cannot be empty")
	}
	urlPath = strings.ReplaceAll(urlPath, "{recoveryJobName}", url.PathEscape(recoveryJobName))
	req, err := runtime.NewRequest(ctx, http.MethodPost, runtime.JoinPaths(client.internal.Endpoint(), urlPath))
	if err != nil {
		return nil, err
	}
	reqQP := req.Raw().URL.Query()
	reqQP.Set("api-version", version20260401Preview)
	req.Raw().URL.RawQuery = strings.ReplaceAll(reqQP.Encode(), "+", "%20")
	req.Raw().Header["operation-id"] = []string{operationID}
	return req, nil
}
