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

package cloudwatchlogs

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

// Creates or updates a field index policy for the specified log group. Only log
// groups in the Standard log class support field index policies. For more
// information about log classes, see [Log classes].
//
// You can use field index policies to create field indexes on fields found in log
// events in the log group. Creating field indexes speeds up and lowers the costs
// for CloudWatch Logs Insights queries that reference those field indexes, because
// these queries attempt to skip the processing of log events that are known to not
// match the indexed field. Good fields to index are fields that you often need to
// query for and fields or values that match only a small fraction of the total log
// events. Common examples of indexes include request ID, session ID, userID, and
// instance IDs. For more information, see [Create field indexes to improve query performance and reduce costs].
//
// You can configure indexed fields as facets to enable interactive exploration
// and filtering of your logs in the CloudWatch Logs Insights console. Facets allow
// you to view value distributions and counts for indexed fields without running
// queries. When you create a field index, you can optionally set it as a facet to
// enable this interactive analysis capability. For more information, see [Use facets to group and explore logs].
//
// To find the fields that are in your log group events, use the [GetLogGroupFields] operation.
//
// For example, suppose you have created a field index for requestId . Then, any
// CloudWatch Logs Insights query on that log group that includes requestId =
// value or requestId IN [value, value, ...] will process fewer log events to
// reduce costs, and have improved performance.
//
// CloudWatch Logs provides default field indexes for all log groups in the
// Standard log class. Default field indexes are automatically available for the
// following fields:
//
//   - @logStream
//
//   - @aws.region
//
//   - @aws.account
//
//   - @source.log
//
//   - traceId
//
// Default field indexes are in addition to any custom field indexes you define
// within your policy. Default field indexes are not counted towards your field
// index quota.
//
// Each index policy has the following quotas and restrictions:
//
//   - As many as 20 fields can be included in the policy.
//
//   - Each field name can include as many as 100 characters.
//
// Matches of log events to the names of indexed fields are case-sensitive. For
// example, a field index of RequestId won't match a log event containing requestId
// .
//
// Log group-level field index policies created with PutIndexPolicy override
// account-level field index policies created with [PutAccountPolicy]that apply to log groups. If
// you use PutIndexPolicy to create a field index policy for a log group, that log
// group uses only that policy for log group-level indexing, including any facet
// configurations. The log group ignores any account-wide field index policy that
// applies to log groups, but data source-based account policies may still apply.
//
// [Log classes]: https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/CloudWatch_Logs_Log_Classes.html
// [GetLogGroupFields]: https://docs.aws.amazon.com/AmazonCloudWatchLogs/latest/APIReference/API_GetLogGroupFields.html
// [PutAccountPolicy]: https://docs.aws.amazon.com/AmazonCloudWatchLogs/latest/APIReference/API_PutAccountPolicy.html
// [Create field indexes to improve query performance and reduce costs]: https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/CloudWatchLogs-Field-Indexing.html
// [Use facets to group and explore logs]: https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/CloudWatchLogs-Facets.html
func (c *Client) PutIndexPolicy(ctx context.Context, params *PutIndexPolicyInput, optFns ...func(*Options)) (*PutIndexPolicyOutput, error) {
	if params == nil {
		params = &PutIndexPolicyInput{}
	}

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

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

type PutIndexPolicyInput struct {

	// Specify either the log group name or log group ARN to apply this field index
	// policy to. If you specify an ARN, use the format
	// arn:aws:logs:region:account-id:log-group:log_group_name Don't include an * at
	// the end.
	//
	// This member is required.
	LogGroupIdentifier *string

	// The index policy document, in JSON format. The following is an example of an
	// index policy document that creates indexes with different types.
	//
	//     "policyDocument": "{"Fields": [ "TransactionId" ], "FieldsV2": {"RequestId":
	//     {"type": "FIELD_INDEX"}, "APIName": {"type": "FACET"}, "StatusCode": {"type":
	//     "FACET"}}}"
	//
	// You can use FieldsV2 to specify the type for each field. Supported types are
	// FIELD_INDEX and FACET . Field names within Fields and FieldsV2 must be mutually
	// exclusive.
	//
	// The policy document must include at least one field index. For more information
	// about the fields that can be included and other restrictions, see [Field index syntax and quotas].
	//
	// [Field index syntax and quotas]: https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/CloudWatchLogs-Field-Indexing-Syntax.html
	//
	// This member is required.
	PolicyDocument *string

	noSmithyDocumentSerde
}

type PutIndexPolicyOutput struct {

	// The index policy that you just created or updated.
	IndexPolicy *types.IndexPolicy

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

	noSmithyDocumentSerde
}

func (c *Client) addOperationPutIndexPolicyMiddlewares(stack *middleware.Stack, options Options) (err error) {
	if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil {
		return err
	}
	err = stack.Serialize.Add(&awsAwsjson11_serializeOpPutIndexPolicy{}, middleware.After)
	if err != nil {
		return err
	}
	err = stack.Deserialize.Add(&awsAwsjson11_deserializeOpPutIndexPolicy{}, middleware.After)
	if err != nil {
		return err
	}
	if err := addProtocolFinalizerMiddlewares(stack, options, "PutIndexPolicy"); 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, c); 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 = addUserAgentRetryMode(stack, options); err != nil {
		return err
	}
	if err = addCredentialSource(stack, options); err != nil {
		return err
	}
	if err = addOpPutIndexPolicyValidationMiddleware(stack); err != nil {
		return err
	}
	if err = stack.Initialize.Add(newServiceMetadataMiddleware_opPutIndexPolicy(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_opPutIndexPolicy(region string) *awsmiddleware.RegisterServiceMetadata {
	return &awsmiddleware.RegisterServiceMetadata{
		Region:        region,
		ServiceID:     ServiceID,
		OperationName: "PutIndexPolicy",
	}
}
