// Code generated by smithy-go-codegen DO NOT EDIT.

package backup

import (
	"context"
	"fmt"
	awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware"
	"github.com/aws/aws-sdk-go-v2/service/backup/types"
	"github.com/aws/smithy-go/middleware"
	smithyhttp "github.com/aws/smithy-go/transport/http"
	"time"
)

// Starts an on-demand backup job for the specified resource.
func (c *Client) StartBackupJob(ctx context.Context, params *StartBackupJobInput, optFns ...func(*Options)) (*StartBackupJobOutput, error) {
	if params == nil {
		params = &StartBackupJobInput{}
	}

	result, metadata, err := c.invokeOperation(ctx, "StartBackupJob", params, optFns, c.addOperationStartBackupJobMiddlewares)
	if err != nil {
		return nil, err
	}

	out := result.(*StartBackupJobOutput)
	out.ResultMetadata = metadata
	return out, nil
}

type StartBackupJobInput struct {

	// The name of a logical container where backups are stored. Backup vaults are
	// identified by names that are unique to the account used to create them and the
	// Amazon Web Services Region where they are created.
	//
	// This member is required.
	BackupVaultName *string

	// Specifies the IAM role ARN used to create the target recovery point; for
	// example, arn:aws:iam::123456789012:role/S3Access .
	//
	// This member is required.
	IamRoleArn *string

	// An Amazon Resource Name (ARN) that uniquely identifies a resource. The format
	// of the ARN depends on the resource type.
	//
	// This member is required.
	ResourceArn *string

	// The backup option for a selected resource. This option is only available for
	// Windows Volume Shadow Copy Service (VSS) backup jobs.
	//
	// Valid values: Set to "WindowsVSS":"enabled" to enable the WindowsVSS backup
	// option and create a Windows VSS backup. Set to "WindowsVSS""disabled" to create
	// a regular backup. The WindowsVSS option is not enabled by default.
	BackupOptions map[string]string

	// A value in minutes during which a successfully started backup must complete, or
	// else Backup will cancel the job. This value is optional. This value begins
	// counting down from when the backup was scheduled. It does not add additional
	// time for StartWindowMinutes , or if the backup started later than scheduled.
	//
	// Like StartWindowMinutes , this parameter has a maximum value of 100 years
	// (52,560,000 minutes).
	CompleteWindowMinutes *int64

	// A customer-chosen string that you can use to distinguish between otherwise
	// identical calls to StartBackupJob . Retrying a successful request with the same
	// idempotency token results in a success message with no action taken.
	IdempotencyToken *string

	// Include this parameter to enable index creation if your backup job has a
	// resource type that supports backup indexes.
	//
	// Resource types that support backup indexes include:
	//
	//   - EBS for Amazon Elastic Block Store
	//
	//   - S3 for Amazon Simple Storage Service (Amazon S3)
	//
	// Index can have 1 of 2 possible values, either ENABLED or DISABLED .
	//
	// To create a backup index for an eligible ACTIVE recovery point that does not
	// yet have a backup index, set value to ENABLED .
	//
	// To delete a backup index, set value to DISABLED .
	Index types.Index

	// The lifecycle defines when a protected resource is transitioned to cold storage
	// and when it expires. Backup will transition and expire backups automatically
	// according to the lifecycle that you define.
	//
	// Backups transitioned to cold storage must be stored in cold storage for a
	// minimum of 90 days. Therefore, the “retention” setting must be 90 days greater
	// than the “transition to cold after days” setting. The “transition to cold after
	// days” setting cannot be changed after a backup has been transitioned to cold.
	//
	// Resource types that can transition to cold storage are listed in the [Feature availability by resource] table.
	// Backup ignores this expression for other resource types.
	//
	// This parameter has a maximum value of 100 years (36,500 days).
	//
	// [Feature availability by resource]: https://docs.aws.amazon.com/aws-backup/latest/devguide/backup-feature-availability.html#features-by-resource
	Lifecycle *types.Lifecycle

	// The ARN of a logically air-gapped vault. ARN must be in the same account and
	// Region. If provided, supported fully managed resources back up directly to
	// logically air-gapped vault, while other supported resources create a temporary
	// (billable) snapshot in backup vault, then copy it to logically air-gapped vault.
	// Unsupported resources only back up to the specified backup vault.
	LogicallyAirGappedBackupVaultArn *string

	// The tags to assign to the resources.
	RecoveryPointTags map[string]string

	// A value in minutes after a backup is scheduled before a job will be canceled if
	// it doesn't start successfully. This value is optional, and the default is 8
	// hours. If this value is included, it must be at least 60 minutes to avoid
	// errors.
	//
	// This parameter has a maximum value of 100 years (52,560,000 minutes).
	//
	// During the start window, the backup job status remains in CREATED status until
	// it has successfully begun or until the start window time has run out. If within
	// the start window time Backup receives an error that allows the job to be
	// retried, Backup will automatically retry to begin the job at least every 10
	// minutes until the backup successfully begins (the job status changes to RUNNING
	// ) or until the job status changes to EXPIRED (which is expected to occur when
	// the start window time is over).
	StartWindowMinutes *int64

	noSmithyDocumentSerde
}

type StartBackupJobOutput struct {

	// Uniquely identifies a request to Backup to back up a resource.
	BackupJobId *string

	// The date and time that a backup job is created, in Unix format and Coordinated
	// Universal Time (UTC). The value of CreationDate is accurate to milliseconds.
	// For example, the value 1516925490.087 represents Friday, January 26, 2018
	// 12:11:30.087 AM.
	CreationDate *time.Time

	// This is a returned boolean value indicating this is a parent (composite) backup
	// job.
	IsParent bool

	//  Note: This field is only returned for Amazon EFS and Advanced DynamoDB
	// resources.
	//
	// An ARN that uniquely identifies a recovery point; for example,
	// arn:aws:backup:us-east-1:123456789012:recovery-point:1EB3B5E7-9EB0-435A-A80B-108B488B0D45
	// .
	RecoveryPointArn *string

	// Metadata pertaining to the operation's result.
	ResultMetadata middleware.Metadata

	noSmithyDocumentSerde
}

func (c *Client) addOperationStartBackupJobMiddlewares(stack *middleware.Stack, options Options) (err error) {
	if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil {
		return err
	}
	err = stack.Serialize.Add(&awsRestjson1_serializeOpStartBackupJob{}, middleware.After)
	if err != nil {
		return err
	}
	err = stack.Deserialize.Add(&awsRestjson1_deserializeOpStartBackupJob{}, middleware.After)
	if err != nil {
		return err
	}
	if err := addProtocolFinalizerMiddlewares(stack, options, "StartBackupJob"); err != nil {
		return fmt.Errorf("add protocol finalizers: %v", err)
	}

	if err = addlegacyEndpointContextSetter(stack, options); err != nil {
		return err
	}
	if err = addSetLoggerMiddleware(stack, options); err != nil {
		return err
	}
	if err = addClientRequestID(stack); err != nil {
		return err
	}
	if err = addComputeContentLength(stack); err != nil {
		return err
	}
	if err = addResolveEndpointMiddleware(stack, options); err != nil {
		return err
	}
	if err = addComputePayloadSHA256(stack); err != nil {
		return err
	}
	if err = addRetry(stack, options); err != nil {
		return err
	}
	if err = addRawResponseToMetadata(stack); err != nil {
		return err
	}
	if err = addRecordResponseTiming(stack); err != nil {
		return err
	}
	if err = addSpanRetryLoop(stack, options); err != nil {
		return err
	}
	if err = addClientUserAgent(stack, options); err != nil {
		return err
	}
	if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil {
		return err
	}
	if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil {
		return err
	}
	if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil {
		return err
	}
	if err = addTimeOffsetBuild(stack, c); err != nil {
		return err
	}
	if err = addUserAgentRetryMode(stack, options); err != nil {
		return err
	}
	if err = addCredentialSource(stack, options); err != nil {
		return err
	}
	if err = addIdempotencyToken_opStartBackupJobMiddleware(stack, options); err != nil {
		return err
	}
	if err = addOpStartBackupJobValidationMiddleware(stack); err != nil {
		return err
	}
	if err = stack.Initialize.Add(newServiceMetadataMiddleware_opStartBackupJob(options.Region), middleware.Before); err != nil {
		return err
	}
	if err = addRecursionDetection(stack); err != nil {
		return err
	}
	if err = addRequestIDRetrieverMiddleware(stack); err != nil {
		return err
	}
	if err = addResponseErrorMiddleware(stack); err != nil {
		return err
	}
	if err = addRequestResponseLogging(stack, options); err != nil {
		return err
	}
	if err = addDisableHTTPSMiddleware(stack, options); err != nil {
		return err
	}
	if err = addInterceptBeforeRetryLoop(stack, options); err != nil {
		return err
	}
	if err = addInterceptAttempt(stack, options); err != nil {
		return err
	}
	if err = addInterceptors(stack, options); err != nil {
		return err
	}
	return nil
}

type idempotencyToken_initializeOpStartBackupJob struct {
	tokenProvider IdempotencyTokenProvider
}

func (*idempotencyToken_initializeOpStartBackupJob) ID() string {
	return "OperationIdempotencyTokenAutoFill"
}

func (m *idempotencyToken_initializeOpStartBackupJob) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) (
	out middleware.InitializeOutput, metadata middleware.Metadata, err error,
) {
	if m.tokenProvider == nil {
		return next.HandleInitialize(ctx, in)
	}

	input, ok := in.Parameters.(*StartBackupJobInput)
	if !ok {
		return out, metadata, fmt.Errorf("expected middleware input to be of type *StartBackupJobInput ")
	}

	if input.IdempotencyToken == nil {
		t, err := m.tokenProvider.GetIdempotencyToken()
		if err != nil {
			return out, metadata, err
		}
		input.IdempotencyToken = &t
	}
	return next.HandleInitialize(ctx, in)
}
func addIdempotencyToken_opStartBackupJobMiddleware(stack *middleware.Stack, cfg Options) error {
	return stack.Initialize.Add(&idempotencyToken_initializeOpStartBackupJob{tokenProvider: cfg.IdempotencyTokenProvider}, middleware.Before)
}

func newServiceMetadataMiddleware_opStartBackupJob(region string) *awsmiddleware.RegisterServiceMetadata {
	return &awsmiddleware.RegisterServiceMetadata{
		Region:        region,
		ServiceID:     ServiceID,
		OperationName: "StartBackupJob",
	}
}
