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

// Generates an account status report. The report is generated asynchronously, and
// can take several hours to complete.
//
// The report provides the current status of all attributes supported by
// declarative policies for the accounts within the specified scope. The scope is
// determined by the specified TargetId , which can represent an individual
// account, or all the accounts that fall under the specified organizational unit
// (OU) or root (the entire Amazon Web Services Organization).
//
// The report is saved to your specified S3 bucket, using the following path
// structure (with the italicized placeholders representing your specific values):
//
//	s3://amzn-s3-demo-bucket/your-optional-s3-prefix/ec2_targetId_reportId_yyyyMMddThhmmZ.csv
//
// Prerequisites for generating a report
//
//   - The StartDeclarativePoliciesReport API can only be called by the management
//     account or delegated administrators for the organization.
//
//   - An S3 bucket must be available before generating the report (you can create
//     a new one or use an existing one), it must be in the same Region where the
//     report generation request is made, and it must have an appropriate bucket
//     policy. For a sample S3 policy, see Sample Amazon S3 policy under [Examples].
//
//   - Trusted access must be enabled for the service for which the declarative
//     policy will enforce a baseline configuration. If you use the Amazon Web Services
//     Organizations console, this is done automatically when you enable declarative
//     policies. The API uses the following service principal to identify the EC2
//     service: ec2.amazonaws.com . For more information on how to enable trusted
//     access with the Amazon Web Services CLI and Amazon Web Services SDKs, see [Using Organizations with other Amazon Web Services services]in
//     the Amazon Web Services Organizations User Guide.
//
//   - Only one report per organization can be generated at a time. Attempting to
//     generate a report while another is in progress will result in an error.
//
// For more information, including the required IAM permissions to run this API,
// see [Generating the account status report for declarative policies]in the Amazon Web Services Organizations User Guide.
//
// [Generating the account status report for declarative policies]: https://docs.aws.amazon.com/organizations/latest/userguide/orgs_manage_policies_declarative_status-report.html
// [Using Organizations with other Amazon Web Services services]: https://docs.aws.amazon.com/organizations/latest/userguide/orgs_integrate_services.html
// [Examples]: https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_StartDeclarativePoliciesReport.html#API_StartDeclarativePoliciesReport_Examples
func (c *Client) StartDeclarativePoliciesReport(ctx context.Context, params *StartDeclarativePoliciesReportInput, optFns ...func(*Options)) (*StartDeclarativePoliciesReportOutput, error) {
	if params == nil {
		params = &StartDeclarativePoliciesReportInput{}
	}

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

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

type StartDeclarativePoliciesReportInput struct {

	// The name of the S3 bucket where the report will be saved. The bucket must be in
	// the same Region where the report generation request is made.
	//
	// This member is required.
	S3Bucket *string

	// The root ID, organizational unit ID, or account ID.
	//
	// Format:
	//
	//   - For root: r-ab12
	//
	//   - For OU: ou-ab12-cdef1234
	//
	//   - For account: 123456789012
	//
	// This member is required.
	TargetId *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

	// The prefix for your S3 object.
	S3Prefix *string

	// The tags to apply.
	TagSpecifications []types.TagSpecification

	noSmithyDocumentSerde
}

type StartDeclarativePoliciesReportOutput struct {

	// The ID of the report.
	ReportId *string

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

	noSmithyDocumentSerde
}

func (c *Client) addOperationStartDeclarativePoliciesReportMiddlewares(stack *middleware.Stack, options Options) (err error) {
	if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil {
		return err
	}
	err = stack.Serialize.Add(&awsEc2query_serializeOpStartDeclarativePoliciesReport{}, middleware.After)
	if err != nil {
		return err
	}
	err = stack.Deserialize.Add(&awsEc2query_deserializeOpStartDeclarativePoliciesReport{}, middleware.After)
	if err != nil {
		return err
	}
	if err := addProtocolFinalizerMiddlewares(stack, options, "StartDeclarativePoliciesReport"); 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 = addOpStartDeclarativePoliciesReportValidationMiddleware(stack); err != nil {
		return err
	}
	if err = stack.Initialize.Add(newServiceMetadataMiddleware_opStartDeclarativePoliciesReport(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 = addInterceptExecution(stack, options); err != nil {
		return err
	}
	if err = addInterceptBeforeSerialization(stack, options); err != nil {
		return err
	}
	if err = addInterceptAfterSerialization(stack, options); err != nil {
		return err
	}
	if err = addInterceptBeforeSigning(stack, options); err != nil {
		return err
	}
	if err = addInterceptAfterSigning(stack, options); err != nil {
		return err
	}
	if err = addInterceptTransmit(stack, options); err != nil {
		return err
	}
	if err = addInterceptBeforeDeserialization(stack, options); err != nil {
		return err
	}
	if err = addInterceptAfterDeserialization(stack, options); err != nil {
		return err
	}
	if err = addSpanInitializeStart(stack); err != nil {
		return err
	}
	if err = addSpanInitializeEnd(stack); err != nil {
		return err
	}
	if err = addSpanBuildRequestStart(stack); err != nil {
		return err
	}
	if err = addSpanBuildRequestEnd(stack); err != nil {
		return err
	}
	return nil
}

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