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

package efs

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/efs/types"
	"github.com/aws/smithy-go/middleware"
	smithyhttp "github.com/aws/smithy-go/transport/http"
	"time"
)

// Creates a new, empty file system. The operation requires a creation token in the
// request that Amazon EFS uses to ensure idempotent creation (calling the
// operation with same creation token has no effect). If a file system does not
// currently exist that is owned by the caller's Amazon Web Services account with
// the specified creation token, this operation does the following:
//
// * Creates a
// new, empty file system. The file system will have an Amazon EFS assigned ID, and
// an initial lifecycle state creating.
//
// * Returns with the description of the
// created file system.
//
// Otherwise, this operation returns a
// FileSystemAlreadyExists error with the ID of the existing file system. For basic
// use cases, you can use a randomly generated UUID for the creation token. The
// idempotent operation allows you to retry a CreateFileSystem call without risk of
// creating an extra file system. This can happen when an initial call fails in a
// way that leaves it uncertain whether or not a file system was actually created.
// An example might be that a transport level timeout occurred or your connection
// was reset. As long as you use the same creation token, if the initial call had
// succeeded in creating a file system, the client can learn of its existence from
// the FileSystemAlreadyExists error. For more information, see Creating a file
// system
// (https://docs.aws.amazon.com/efs/latest/ug/creating-using-create-fs.html#creating-using-create-fs-part1)
// in the Amazon EFS User Guide. The CreateFileSystem call returns while the file
// system's lifecycle state is still creating. You can check the file system
// creation status by calling the DescribeFileSystems operation, which among other
// things returns the file system state. This operation accepts an optional
// PerformanceMode parameter that you choose for your file system. We recommend
// generalPurpose performance mode for most file systems. File systems using the
// maxIO performance mode can scale to higher levels of aggregate throughput and
// operations per second with a tradeoff of slightly higher latencies for most file
// operations. The performance mode can't be changed after the file system has been
// created. For more information, see Amazon EFS performance modes
// (https://docs.aws.amazon.com/efs/latest/ug/performance.html#performancemodes.html).
// You can set the throughput mode for the file system using the ThroughputMode
// parameter. After the file system is fully created, Amazon EFS sets its lifecycle
// state to available, at which point you can create one or more mount targets for
// the file system in your VPC. For more information, see CreateMountTarget. You
// mount your Amazon EFS file system on an EC2 instances in your VPC by using the
// mount target. For more information, see Amazon EFS: How it Works
// (https://docs.aws.amazon.com/efs/latest/ug/how-it-works.html). This operation
// requires permissions for the elasticfilesystem:CreateFileSystem action.
func (c *Client) CreateFileSystem(ctx context.Context, params *CreateFileSystemInput, optFns ...func(*Options)) (*CreateFileSystemOutput, error) {
	if params == nil {
		params = &CreateFileSystemInput{}
	}

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

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

type CreateFileSystemInput struct {

	// A string of up to 64 ASCII characters. Amazon EFS uses this to ensure idempotent
	// creation.
	//
	// This member is required.
	CreationToken *string

	// Used to create a file system that uses One Zone storage classes. It specifies
	// the Amazon Web Services Availability Zone in which to create the file system.
	// Use the format us-east-1a to specify the Availability Zone. For more information
	// about One Zone storage classes, see Using EFS storage classes
	// (https://docs.aws.amazon.com/efs/latest/ug/storage-classes.html) in the Amazon
	// EFS User Guide. One Zone storage classes are not available in all Availability
	// Zones in Amazon Web Services Regions where Amazon EFS is available.
	AvailabilityZoneName *string

	// Specifies whether automatic backups are enabled on the file system that you are
	// creating. Set the value to true to enable automatic backups. If you are creating
	// a file system that uses One Zone storage classes, automatic backups are enabled
	// by default. For more information, see Automatic backups
	// (https://docs.aws.amazon.com/efs/latest/ug/awsbackup.html#automatic-backups) in
	// the Amazon EFS User Guide. Default is false. However, if you specify an
	// AvailabilityZoneName, the default is true. Backup is not available in all Amazon
	// Web Services Regions where Amazon EFS is available.
	Backup *bool

	// A Boolean value that, if true, creates an encrypted file system. When creating
	// an encrypted file system, you have the option of specifying an existing Key
	// Management Service key (KMS key). If you don't specify a KMS key, then the
	// default KMS key for Amazon EFS, /aws/elasticfilesystem, is used to protect the
	// encrypted file system.
	Encrypted *bool

	// The ID of the KMS key that you want to use to protect the encrypted file system.
	// This parameter is required only if you want to use a non-default KMS key. If
	// this parameter is not specified, the default KMS key for Amazon EFS is used. You
	// can specify a KMS key ID using the following formats:
	//
	// * Key ID - A unique
	// identifier of the key, for example 1234abcd-12ab-34cd-56ef-1234567890ab.
	//
	// * ARN
	// - An Amazon Resource Name (ARN) for the key, for example
	// arn:aws:kms:us-west-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab.
	//
	// *
	// Key alias - A previously created display name for a key, for example
	// alias/projectKey1.
	//
	// * Key alias ARN - An ARN for a key alias, for example
	// arn:aws:kms:us-west-2:444455556666:alias/projectKey1.
	//
	// If you use KmsKeyId, you
	// must set the CreateFileSystemRequest$Encrypted parameter to true. EFS accepts
	// only symmetric KMS keys. You cannot use asymmetric KMS keys with Amazon EFS file
	// systems.
	KmsKeyId *string

	// The performance mode of the file system. We recommend generalPurpose performance
	// mode for most file systems. File systems using the maxIO performance mode can
	// scale to higher levels of aggregate throughput and operations per second with a
	// tradeoff of slightly higher latencies for most file operations. The performance
	// mode can't be changed after the file system has been created. The maxIO mode is
	// not supported on file systems using One Zone storage classes.
	PerformanceMode types.PerformanceMode

	// The throughput, measured in MiB/s, that you want to provision for a file system
	// that you're creating. Valid values are 1-1024. Required if ThroughputMode is set
	// to provisioned. The upper limit for throughput is 1024 MiB/s. To increase this
	// limit, contact Amazon Web Services Support. For more information, see Amazon EFS
	// quotas that you can increase
	// (https://docs.aws.amazon.com/efs/latest/ug/limits.html#soft-limits) in the
	// Amazon EFS User Guide.
	ProvisionedThroughputInMibps *float64

	// Use to create one or more tags associated with the file system. Each tag is a
	// user-defined key-value pair. Name your file system on creation by including a
	// "Key":"Name","Value":"{value}" key-value pair. Each key must be unique. For more
	// information, see Tagging Amazon Web Services resources
	// (https://docs.aws.amazon.com/general/latest/gr/aws_tagging.html) in the Amazon
	// Web Services General Reference Guide.
	Tags []types.Tag

	// Specifies the throughput mode for the file system, either bursting or
	// provisioned. If you set ThroughputMode to provisioned, you must also set a value
	// for ProvisionedThroughputInMibps. After you create the file system, you can
	// decrease your file system's throughput in Provisioned Throughput mode or change
	// between the throughput modes, as long as it’s been more than 24 hours since the
	// last decrease or throughput mode change. For more information, see Specifying
	// throughput with provisioned mode
	// (https://docs.aws.amazon.com/efs/latest/ug/performance.html#provisioned-throughput)
	// in the Amazon EFS User Guide. Default is bursting.
	ThroughputMode types.ThroughputMode

	noSmithyDocumentSerde
}

// A description of the file system.
type CreateFileSystemOutput struct {

	// The time that the file system was created, in seconds (since
	// 1970-01-01T00:00:00Z).
	//
	// This member is required.
	CreationTime *time.Time

	// The opaque string specified in the request.
	//
	// This member is required.
	CreationToken *string

	// The ID of the file system, assigned by Amazon EFS.
	//
	// This member is required.
	FileSystemId *string

	// The lifecycle phase of the file system.
	//
	// This member is required.
	LifeCycleState types.LifeCycleState

	// The current number of mount targets that the file system has. For more
	// information, see CreateMountTarget.
	//
	// This member is required.
	NumberOfMountTargets int32

	// The Amazon Web Services account that created the file system. If the file system
	// was created by an IAM user, the parent account to which the user belongs is the
	// owner.
	//
	// This member is required.
	OwnerId *string

	// The performance mode of the file system.
	//
	// This member is required.
	PerformanceMode types.PerformanceMode

	// The latest known metered size (in bytes) of data stored in the file system, in
	// its Value field, and the time at which that size was determined in its Timestamp
	// field. The Timestamp value is the integer number of seconds since
	// 1970-01-01T00:00:00Z. The SizeInBytes value doesn't represent the size of a
	// consistent snapshot of the file system, but it is eventually consistent when
	// there are no writes to the file system. That is, SizeInBytes represents actual
	// size only if the file system is not modified for a period longer than a couple
	// of hours. Otherwise, the value is not the exact size that the file system was at
	// any point in time.
	//
	// This member is required.
	SizeInBytes *types.FileSystemSize

	// The tags associated with the file system, presented as an array of Tag objects.
	//
	// This member is required.
	Tags []types.Tag

	// The unique and consistent identifier of the Availability Zone in which the file
	// system's One Zone storage classes exist. For example, use1-az1 is an
	// Availability Zone ID for the us-east-1 Amazon Web Services Region, and it has
	// the same location in every Amazon Web Services account.
	AvailabilityZoneId *string

	// Describes the Amazon Web Services Availability Zone in which the file system is
	// located, and is valid only for file systems using One Zone storage classes. For
	// more information, see Using EFS storage classes
	// (https://docs.aws.amazon.com/efs/latest/ug/storage-classes.html) in the Amazon
	// EFS User Guide.
	AvailabilityZoneName *string

	// A Boolean value that, if true, indicates that the file system is encrypted.
	Encrypted *bool

	// The Amazon Resource Name (ARN) for the EFS file system, in the format
	// arn:aws:elasticfilesystem:region:account-id:file-system/file-system-id . Example
	// with sample data:
	// arn:aws:elasticfilesystem:us-west-2:1111333322228888:file-system/fs-01234567
	FileSystemArn *string

	// The ID of an KMS key used to protect the encrypted file system.
	KmsKeyId *string

	// You can add tags to a file system, including a Name tag. For more information,
	// see CreateFileSystem. If the file system has a Name tag, Amazon EFS returns the
	// value in this field.
	Name *string

	// The amount of provisioned throughput, measured in MiB/s, for the file system.
	// Valid for file systems using ThroughputMode set to provisioned.
	ProvisionedThroughputInMibps *float64

	// Displays the file system's throughput mode. For more information, see Throughput
	// modes
	// (https://docs.aws.amazon.com/efs/latest/ug/performance.html#throughput-modes) in
	// the Amazon EFS User Guide.
	ThroughputMode types.ThroughputMode

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

	noSmithyDocumentSerde
}

func (c *Client) addOperationCreateFileSystemMiddlewares(stack *middleware.Stack, options Options) (err error) {
	err = stack.Serialize.Add(&awsRestjson1_serializeOpCreateFileSystem{}, middleware.After)
	if err != nil {
		return err
	}
	err = stack.Deserialize.Add(&awsRestjson1_deserializeOpCreateFileSystem{}, middleware.After)
	if 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 = addHTTPSignerV4Middleware(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); err != nil {
		return err
	}
	if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil {
		return err
	}
	if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil {
		return err
	}
	if err = addIdempotencyToken_opCreateFileSystemMiddleware(stack, options); err != nil {
		return err
	}
	if err = addOpCreateFileSystemValidationMiddleware(stack); err != nil {
		return err
	}
	if err = stack.Initialize.Add(newServiceMetadataMiddleware_opCreateFileSystem(options.Region), middleware.Before); 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
	}
	return nil
}

type idempotencyToken_initializeOpCreateFileSystem struct {
	tokenProvider IdempotencyTokenProvider
}

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

func (m *idempotencyToken_initializeOpCreateFileSystem) 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.(*CreateFileSystemInput)
	if !ok {
		return out, metadata, fmt.Errorf("expected middleware input to be of type *CreateFileSystemInput ")
	}

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

func newServiceMetadataMiddleware_opCreateFileSystem(region string) *awsmiddleware.RegisterServiceMetadata {
	return &awsmiddleware.RegisterServiceMetadata{
		Region:        region,
		ServiceID:     ServiceID,
		SigningName:   "elasticfilesystem",
		OperationName: "CreateFileSystem",
	}
}
