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

package cloudformation

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

// Registers an extension with the CloudFormation service. Registering an
// extension makes it available for use in CloudFormation templates in your Amazon
// Web Services account, and includes:
//
//   - Validating the extension schema.
//
//   - Determining which handlers, if any, have been specified for the extension.
//
//   - Making the extension available for use in your account.
//
// For more information about how to develop extensions and ready them for
// registration, see [Creating resource types using the CloudFormation CLI]in the CloudFormation Command Line Interface (CLI) User Guide.
//
// You can have a maximum of 50 resource extension versions registered at a time.
// This maximum is per account and per Region. Use [DeregisterType]to deregister specific
// extension versions if necessary.
//
// Once you have initiated a registration request using RegisterType, you can use DescribeTypeRegistration to monitor
// the progress of the registration request.
//
// Once you have registered a private extension in your account and Region, use [SetTypeConfiguration]
// to specify configuration properties for the extension. For more information, see
// [Edit configuration data for extensions in your account]in the CloudFormation User Guide.
//
// [SetTypeConfiguration]: https://docs.aws.amazon.com/AWSCloudFormation/latest/APIReference/API_SetTypeConfiguration.html
// [Edit configuration data for extensions in your account]: https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/registry-set-configuration.html
// [Creating resource types using the CloudFormation CLI]: https://docs.aws.amazon.com/cloudformation-cli/latest/userguide/resource-types.html
// [DeregisterType]: https://docs.aws.amazon.com/AWSCloudFormation/latest/APIReference/API_DeregisterType.html
func (c *Client) RegisterType(ctx context.Context, params *RegisterTypeInput, optFns ...func(*Options)) (*RegisterTypeOutput, error) {
	if params == nil {
		params = &RegisterTypeInput{}
	}

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

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

type RegisterTypeInput struct {

	// A URL to the S3 bucket that contains the extension project package that
	// contains the necessary files for the extension you want to register.
	//
	// For information about generating a schema handler package for the extension you
	// want to register, see [submit]in the CloudFormation Command Line Interface (CLI) User
	// Guide.
	//
	// The user registering the extension must be able to access the package in the S3
	// bucket. That's, the user needs to have [GetObject]permissions for the schema handler
	// package. For more information, see [Actions, Resources, and Condition Keys for Amazon S3]in the Identity and Access Management User
	// Guide.
	//
	// [submit]: https://docs.aws.amazon.com/cloudformation-cli/latest/userguide/resource-type-cli-submit.html
	// [Actions, Resources, and Condition Keys for Amazon S3]: https://docs.aws.amazon.com/IAM/latest/UserGuide/list_amazons3.html
	// [GetObject]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObject.html
	//
	// This member is required.
	SchemaHandlerPackage *string

	// The name of the extension being registered.
	//
	// We suggest that extension names adhere to the following patterns:
	//
	//   - For resource types, company_or_organization::service::type .
	//
	//   - For modules, company_or_organization::service::type::MODULE .
	//
	//   - For Hooks, MyCompany::Testing::MyTestHook .
	//
	// The following organization namespaces are reserved and can't be used in your
	// extension names:
	//
	//   - Alexa
	//
	//   - AMZN
	//
	//   - Amazon
	//
	//   - AWS
	//
	//   - Custom
	//
	//   - Dev
	//
	// This member is required.
	TypeName *string

	// A unique identifier that acts as an idempotency key for this registration
	// request. Specifying a client request token prevents CloudFormation from
	// generating more than one version of an extension from the same registration
	// request, even if the request is submitted multiple times.
	ClientRequestToken *string

	// The Amazon Resource Name (ARN) of the IAM role for CloudFormation to assume
	// when invoking the extension.
	//
	// For CloudFormation to assume the specified execution role, the role must
	// contain a trust relationship with the CloudFormation service principal (
	// resources.cloudformation.amazonaws.com ). For more information about adding
	// trust relationships, see [Modifying a role trust policy]in the Identity and Access Management User Guide.
	//
	// If your extension calls Amazon Web Services APIs in any of its handlers, you
	// must create an [IAM execution role]that includes the necessary permissions to call those Amazon Web
	// Services APIs, and provision that execution role in your account. When
	// CloudFormation needs to invoke the resource type handler, CloudFormation assumes
	// this execution role to create a temporary session token, which it then passes to
	// the resource type handler, thereby supplying your resource type with the
	// appropriate credentials.
	//
	// [IAM execution role]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles.html
	// [Modifying a role trust policy]: https://docs.aws.amazon.com/IAM/latest/UserGuide/roles-managingrole-editing-console.html#roles-managingrole_edit-trust-policy
	ExecutionRoleArn *string

	// Specifies logging configuration information for an extension.
	LoggingConfig *types.LoggingConfig

	// The kind of extension.
	Type types.RegistryType

	noSmithyDocumentSerde
}

type RegisterTypeOutput struct {

	// The identifier for this registration request.
	//
	// Use this registration token when calling DescribeTypeRegistration, which returns information about the
	// status and IDs of the extension registration.
	RegistrationToken *string

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

	noSmithyDocumentSerde
}

func (c *Client) addOperationRegisterTypeMiddlewares(stack *middleware.Stack, options Options) (err error) {
	if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil {
		return err
	}
	err = stack.Serialize.Add(&awsAwsquery_serializeOpRegisterType{}, middleware.After)
	if err != nil {
		return err
	}
	err = stack.Deserialize.Add(&awsAwsquery_deserializeOpRegisterType{}, middleware.After)
	if err != nil {
		return err
	}
	if err := addProtocolFinalizerMiddlewares(stack, options, "RegisterType"); 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 = addOpRegisterTypeValidationMiddleware(stack); err != nil {
		return err
	}
	if err = stack.Initialize.Add(newServiceMetadataMiddleware_opRegisterType(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
}

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