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

package ec2

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

// Creates an Amazon EBS-backed AMI from an Amazon EBS-backed instance that is
// either running or stopped. If you customized your instance with instance store
// volumes or Amazon EBS volumes in addition to the root device volume, the new AMI
// contains block device mapping information for those volumes. When you launch an
// instance from this new AMI, the instance automatically launches with those
// additional volumes. For more information, see Create an Amazon EBS-backed Linux
// AMI (https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/creating-an-ami-ebs.html)
// in the Amazon Elastic Compute Cloud User Guide.
func (c *Client) CreateImage(ctx context.Context, params *CreateImageInput, optFns ...func(*Options)) (*CreateImageOutput, error) {
	if params == nil {
		params = &CreateImageInput{}
	}

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

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

type CreateImageInput struct {

	// The ID of the instance.
	//
	// This member is required.
	InstanceId *string

	// A name for the new image. Constraints: 3-128 alphanumeric characters,
	// parentheses (()), square brackets ([]), spaces ( ), periods (.), slashes (/),
	// dashes (-), single quotes ('), at-signs (@), or underscores(_)
	//
	// This member is required.
	Name *string

	// The block device mappings. When using the CreateImage action:
	//   - You can't change the volume size using the VolumeSize parameter. If you
	//   want a different volume size, you must first change the volume size of the
	//   source instance.
	//   - You can't modify the encryption status of existing volumes or snapshots. To
	//   create an AMI with volumes or snapshots that have a different encryption status
	//   (for example, where the source volume and snapshots are unencrypted, and you
	//   want to create an AMI with encrypted volumes or snapshots), use the CopyImage
	//   action.
	//   - The only option that can be changed for existing mappings or snapshots is
	//   DeleteOnTermination .
	BlockDeviceMappings []types.BlockDeviceMapping

	// A description for the new image.
	Description *string

	// Checks whether you have the required permissions for the action, without
	// actually making the request, and provides an error response. If you have the
	// required permissions, the error response is DryRunOperation . Otherwise, it is
	// UnauthorizedOperation .
	DryRun *bool

	// Indicates whether or not the instance should be automatically rebooted before
	// creating the image. Specify one of the following values:
	//   - true - The instance is not rebooted before creating the image. This creates
	//   crash-consistent snapshots that include only the data that has been written to
	//   the volumes at the time the snapshots are created. Buffered data and data in
	//   memory that has not yet been written to the volumes is not included in the
	//   snapshots.
	//   - false - The instance is rebooted before creating the image. This ensures
	//   that all buffered data and data in memory is written to the volumes before the
	//   snapshots are created.
	// Default: false
	NoReboot *bool

	// The tags to apply to the AMI and snapshots on creation. You can tag the AMI,
	// the snapshots, or both.
	//   - To tag the AMI, the value for ResourceType must be image .
	//   - To tag the snapshots that are created of the root volume and of other
	//   Amazon EBS volumes that are attached to the instance, the value for
	//   ResourceType must be snapshot . The same tag is applied to all of the
	//   snapshots that are created.
	// If you specify other values for ResourceType , the request fails. To tag an AMI
	// or snapshot after it has been created, see CreateTags (https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_CreateTags.html)
	// .
	TagSpecifications []types.TagSpecification

	noSmithyDocumentSerde
}

type CreateImageOutput struct {

	// The ID of the new AMI.
	ImageId *string

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

	noSmithyDocumentSerde
}

func (c *Client) addOperationCreateImageMiddlewares(stack *middleware.Stack, options Options) (err error) {
	if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil {
		return err
	}
	err = stack.Serialize.Add(&awsEc2query_serializeOpCreateImage{}, middleware.After)
	if err != nil {
		return err
	}
	err = stack.Deserialize.Add(&awsEc2query_deserializeOpCreateImage{}, middleware.After)
	if err != nil {
		return err
	}
	if err := addProtocolFinalizerMiddlewares(stack, options, "CreateImage"); 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 = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil {
		return err
	}
	if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil {
		return err
	}
	if err = addResolveEndpointMiddleware(stack, options); err != nil {
		return err
	}
	if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil {
		return err
	}
	if err = addRetryMiddlewares(stack, options); err != nil {
		return err
	}
	if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil {
		return err
	}
	if err = awsmiddleware.AddRecordResponseTiming(stack); 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 = addOpCreateImageValidationMiddleware(stack); err != nil {
		return err
	}
	if err = stack.Initialize.Add(newServiceMetadataMiddleware_opCreateImage(options.Region), middleware.Before); err != nil {
		return err
	}
	if err = awsmiddleware.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
	}
	return nil
}

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