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

package cloudtrail

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

// Returns Insights metrics data for trails that have enabled Insights. The
// request must include the EventSource , EventName , and InsightType parameters.
//
// If the InsightType is set to ApiErrorRateInsight , the request must also include
// the ErrorCode parameter.
//
// The following are the available time periods for ListInsightsMetricData . Each
// cutoff is inclusive.
//
//   - Data points with a period of 60 seconds (1-minute) are available for 15
//     days.
//
//   - Data points with a period of 300 seconds (5-minute) are available for 63
//     days.
//
//   - Data points with a period of 3600 seconds (1 hour) are available for 90
//     days.
//
// To use ListInsightsMetricData operation, you must have the following
// permissions:
//
//   - If ListInsightsMetricData is invoked with TrailName parameter, access to the
//     ListInsightsMetricData API operation is linked to the cloudtrail:LookupEvents
//     action and cloudtrail:ListInsightsData . To use this operation, you must have
//     permissions to perform the cloudtrail:LookupEvents and
//     cloudtrail:ListInsightsData action on the specific trail.
//
//   - If ListInsightsMetricData is invoked without TrailName parameter, access to
//     the ListInsightsMetricData API operation is linked to the
//     cloudtrail:LookupEvents action only. To use this operation, you must have
//     permissions to perform the cloudtrail:LookupEvents action.
func (c *Client) ListInsightsMetricData(ctx context.Context, params *ListInsightsMetricDataInput, optFns ...func(*Options)) (*ListInsightsMetricDataOutput, error) {
	if params == nil {
		params = &ListInsightsMetricDataInput{}
	}

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

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

type ListInsightsMetricDataInput struct {

	// The name of the event, typically the Amazon Web Services API on which unusual
	// levels of activity were recorded.
	//
	// This member is required.
	EventName *string

	// The Amazon Web Services service to which the request was made, such as
	// iam.amazonaws.com or s3.amazonaws.com .
	//
	// This member is required.
	EventSource *string

	// The type of CloudTrail Insights event, which is either ApiCallRateInsight or
	// ApiErrorRateInsight . The ApiCallRateInsight Insights type analyzes write-only
	// management API calls that are aggregated per minute against a baseline API call
	// volume. The ApiErrorRateInsight Insights type analyzes management API calls
	// that result in error codes.
	//
	// This member is required.
	InsightType types.InsightType

	// Type of data points to return. Valid values are NonZeroData and FillWithZeros .
	// The default is NonZeroData .
	DataType types.InsightsMetricDataType

	// Specifies, in UTC, the end time for time-series data. The value specified is
	// exclusive; results include data points up to the specified time stamp.
	//
	// The default is the time of request.
	EndTime *time.Time

	// Conditionally required if the InsightType parameter is set to
	// ApiErrorRateInsight .
	//
	// If returning metrics for the ApiErrorRateInsight Insights type, this is the
	// error to retrieve data for. For example, AccessDenied .
	ErrorCode *string

	// The maximum number of data points to return. Valid values are integers from 1
	// to 21600. The default value is 21600.
	MaxResults *int32

	// Returned if all datapoints can't be returned in a single call. For example, due
	// to reaching MaxResults .
	//
	// Add this parameter to the request to continue retrieving results starting from
	// the last evaluated point.
	NextToken *string

	// Granularity of data to retrieve, in seconds. Valid values are 60 , 300 , and
	// 3600 . If you specify any other value, you will get an error. The default is
	// 3600 seconds.
	Period *int32

	// Specifies, in UTC, the start time for time-series data. The value specified is
	// inclusive; results include data points with the specified time stamp.
	//
	// The default is 90 days before the time of request.
	StartTime *time.Time

	// The Amazon Resource Name(ARN) or name of the trail for which you want to
	// retrieve Insights metrics data. This parameter should only be provided to fetch
	// Insights metrics data generated on trails logging data events. This parameter is
	// not required for Insights metric data generated on trails logging management
	// events.
	TrailName *string

	noSmithyDocumentSerde
}

type ListInsightsMetricDataOutput struct {

	// Only returned if InsightType parameter was set to ApiErrorRateInsight .
	//
	// If returning metrics for the ApiErrorRateInsight Insights type, this is the
	// error to retrieve data for. For example, AccessDenied .
	ErrorCode *string

	// The name of the event, typically the Amazon Web Services API on which unusual
	// levels of activity were recorded.
	EventName *string

	// The Amazon Web Services service to which the request was made, such as
	// iam.amazonaws.com or s3.amazonaws.com .
	EventSource *string

	// The type of CloudTrail Insights event, which is either ApiCallRateInsight or
	// ApiErrorRateInsight . The ApiCallRateInsight Insights type analyzes write-only
	// management API calls that are aggregated per minute against a baseline API call
	// volume. The ApiErrorRateInsight Insights type analyzes management API calls
	// that result in error codes.
	InsightType types.InsightType

	// Only returned if the full results could not be returned in a single query. You
	// can set the NextToken parameter in the next request to this value to continue
	// retrieval.
	NextToken *string

	// List of timestamps at intervals corresponding to the specified time period.
	Timestamps []time.Time

	// Specifies the ARN of the trail. This is only returned when Insights is enabled
	// on a trail logging data events.
	TrailARN *string

	// List of values representing the API call rate or error rate at each timestamp.
	// The number of values is equal to the number of timestamps.
	Values []float64

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

	noSmithyDocumentSerde
}

func (c *Client) addOperationListInsightsMetricDataMiddlewares(stack *middleware.Stack, options Options) (err error) {
	if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil {
		return err
	}
	err = stack.Serialize.Add(&awsAwsjson11_serializeOpListInsightsMetricData{}, middleware.After)
	if err != nil {
		return err
	}
	err = stack.Deserialize.Add(&awsAwsjson11_deserializeOpListInsightsMetricData{}, middleware.After)
	if err != nil {
		return err
	}
	if err := addProtocolFinalizerMiddlewares(stack, options, "ListInsightsMetricData"); 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 = addOpListInsightsMetricDataValidationMiddleware(stack); err != nil {
		return err
	}
	if err = stack.Initialize.Add(newServiceMetadataMiddleware_opListInsightsMetricData(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
}

// ListInsightsMetricDataPaginatorOptions is the paginator options for
// ListInsightsMetricData
type ListInsightsMetricDataPaginatorOptions struct {
	// The maximum number of data points to return. Valid values are integers from 1
	// to 21600. The default value is 21600.
	Limit int32

	// Set to true if pagination should stop if the service returns a pagination token
	// that matches the most recent token provided to the service.
	StopOnDuplicateToken bool
}

// ListInsightsMetricDataPaginator is a paginator for ListInsightsMetricData
type ListInsightsMetricDataPaginator struct {
	options   ListInsightsMetricDataPaginatorOptions
	client    ListInsightsMetricDataAPIClient
	params    *ListInsightsMetricDataInput
	nextToken *string
	firstPage bool
}

// NewListInsightsMetricDataPaginator returns a new ListInsightsMetricDataPaginator
func NewListInsightsMetricDataPaginator(client ListInsightsMetricDataAPIClient, params *ListInsightsMetricDataInput, optFns ...func(*ListInsightsMetricDataPaginatorOptions)) *ListInsightsMetricDataPaginator {
	if params == nil {
		params = &ListInsightsMetricDataInput{}
	}

	options := ListInsightsMetricDataPaginatorOptions{}
	if params.MaxResults != nil {
		options.Limit = *params.MaxResults
	}

	for _, fn := range optFns {
		fn(&options)
	}

	return &ListInsightsMetricDataPaginator{
		options:   options,
		client:    client,
		params:    params,
		firstPage: true,
		nextToken: params.NextToken,
	}
}

// HasMorePages returns a boolean indicating whether more pages are available
func (p *ListInsightsMetricDataPaginator) HasMorePages() bool {
	return p.firstPage || (p.nextToken != nil && len(*p.nextToken) != 0)
}

// NextPage retrieves the next ListInsightsMetricData page.
func (p *ListInsightsMetricDataPaginator) NextPage(ctx context.Context, optFns ...func(*Options)) (*ListInsightsMetricDataOutput, error) {
	if !p.HasMorePages() {
		return nil, fmt.Errorf("no more pages available")
	}

	params := *p.params
	params.NextToken = p.nextToken

	var limit *int32
	if p.options.Limit > 0 {
		limit = &p.options.Limit
	}
	params.MaxResults = limit

	optFns = append([]func(*Options){
		addIsPaginatorUserAgent,
	}, optFns...)
	result, err := p.client.ListInsightsMetricData(ctx, &params, optFns...)
	if err != nil {
		return nil, err
	}
	p.firstPage = false

	prevToken := p.nextToken
	p.nextToken = result.NextToken

	if p.options.StopOnDuplicateToken &&
		prevToken != nil &&
		p.nextToken != nil &&
		*prevToken == *p.nextToken {
		p.nextToken = nil
	}

	return result, nil
}

// ListInsightsMetricDataAPIClient is a client that implements the
// ListInsightsMetricData operation.
type ListInsightsMetricDataAPIClient interface {
	ListInsightsMetricData(context.Context, *ListInsightsMetricDataInput, ...func(*Options)) (*ListInsightsMetricDataOutput, error)
}

var _ ListInsightsMetricDataAPIClient = (*Client)(nil)

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