// 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"
)

// Starts a query of one or more log groups or data sources using CloudWatch Logs
// Insights. You specify the log groups or data sources and time range to query and
// the query string to use. You can query up to 10 data sources in a single query.
//
// For more information, see [CloudWatch Logs Insights Query Syntax].
//
// After you run a query using StartQuery , the query results are stored by
// CloudWatch Logs. You can use [GetQueryResults]to retrieve the results of a query, using the
// queryId that StartQuery returns.
//
// Interactive queries started with StartQuery share concurrency limits with
// automated scheduled query executions. Both types of queries count toward the
// same regional concurrent query quota, so high scheduled query activity may
// affect the availability of concurrent slots for interactive queries.
//
// To specify the log groups to query, a StartQuery operation must include one of
// the following:
//
//   - Either exactly one of the following parameters: logGroupName , logGroupNames
//     , or logGroupIdentifiers
//
//   - Or the queryString must include a SOURCE command to select log groups for
//     the query. The SOURCE command can select log groups based on log group name
//     prefix, account ID, and log class, or select data sources using dataSource
//     syntax in LogsQL, PPL, and SQL. In LogsQL, the SOURCE command also supports
//     filtering by log group tags.
//
// For more information about the SOURCE command, see [SOURCE].
//
// If you have associated a KMS key with the query results in this account, then [StartQuery]
// uses that key to encrypt the results when it stores them. If no key is
// associated with query results, the query results are encrypted with the default
// CloudWatch Logs encryption method.
//
// Queries time out after 60 minutes of runtime. If your queries are timing out,
// reduce the time range being searched or partition your query into a number of
// queries.
//
// If you are using CloudWatch cross-account observability, you can use this
// operation in a monitoring account to start a query in a linked source account.
// For more information, see [CloudWatch cross-account observability]. For a cross-account StartQuery operation, the query
// definition must be defined in the monitoring account.
//
// You can have up to 100 concurrent CloudWatch Logs insights queries, including
// queries that have been added to dashboards.
//
// [CloudWatch Logs Insights Query Syntax]: https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/CWL_QuerySyntax.html
// [CloudWatch cross-account observability]: https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch-Unified-Cross-Account.html
// [SOURCE]: https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/CWL_QuerySyntax-Source.html
// [GetQueryResults]: https://docs.aws.amazon.com/AmazonCloudWatchLogs/latest/APIReference/API_GetQueryResults.html
// [StartQuery]: https://docs.aws.amazon.com/AmazonCloudWatchLogs/latest/APIReference/API_StartQuery.html
func (c *Client) StartQuery(ctx context.Context, params *StartQueryInput, optFns ...func(*Options)) (*StartQueryOutput, error) {
	if params == nil {
		params = &StartQueryInput{}
	}

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

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

type StartQueryInput struct {

	// The end of the time range to query. The range is inclusive, so the specified
	// end time is included in the query. Specified as epoch time, the number of
	// seconds since January 1, 1970, 00:00:00 UTC .
	//
	// This member is required.
	EndTime *int64

	// The query string to use. For more information, see [CloudWatch Logs Insights Query Syntax].
	//
	// [CloudWatch Logs Insights Query Syntax]: https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/CWL_QuerySyntax.html
	//
	// This member is required.
	QueryString *string

	// The beginning of the time range to query. The range is inclusive, so the
	// specified start time is included in the query. Specified as epoch time, the
	// number of seconds since January 1, 1970, 00:00:00 UTC .
	//
	// This member is required.
	StartTime *int64

	// The maximum number of log events to return in the query. If the query string
	// uses the fields command, only the specified fields and their values are
	// returned. The default is 10,000.
	Limit *int32

	// The list of log groups to query. You can include up to 50 log groups.
	//
	// You can specify them by the log group name or ARN. If a log group that you're
	// querying is in a source account and you're using a monitoring account, you must
	// specify the ARN of the log group here. The query definition must also be defined
	// in the monitoring account.
	//
	// 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.
	//
	// A StartQuery operation must include exactly one of the following parameters:
	// logGroupName , logGroupNames , or logGroupIdentifiers . The exception is queries
	// using the OpenSearch Service SQL query language, where you specify the log group
	// names inside the querystring instead of here.
	LogGroupIdentifiers []string

	// The log group on which to perform the query.
	//
	// A StartQuery operation must include exactly one of the following parameters:
	// logGroupName , logGroupNames , or logGroupIdentifiers . The exception is queries
	// using the OpenSearch Service SQL query language, where you specify the log group
	// names inside the querystring instead of here.
	LogGroupName *string

	// The list of log groups to be queried. You can include up to 50 log groups.
	//
	// A StartQuery operation must include exactly one of the following parameters:
	// logGroupName , logGroupNames , or logGroupIdentifiers . The exception is queries
	// using the OpenSearch Service SQL query language, where you specify the log group
	// names inside the querystring instead of here.
	LogGroupNames []string

	// Specify the query language to use for this query. The options are Logs Insights
	// QL, OpenSearch PPL, and OpenSearch SQL. For more information about the query
	// languages that CloudWatch Logs supports, see [Supported query languages].
	//
	// [Supported query languages]: https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/CWL_AnalyzeLogData_Languages.html
	QueryLanguage types.QueryLanguage

	noSmithyDocumentSerde
}

type StartQueryOutput struct {

	// The unique ID of the query.
	QueryId *string

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

	noSmithyDocumentSerde
}

func (c *Client) addOperationStartQueryMiddlewares(stack *middleware.Stack, options Options) (err error) {
	if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil {
		return err
	}
	err = stack.Serialize.Add(&awsAwsjson11_serializeOpStartQuery{}, middleware.After)
	if err != nil {
		return err
	}
	err = stack.Deserialize.Add(&awsAwsjson11_deserializeOpStartQuery{}, middleware.After)
	if err != nil {
		return err
	}
	if err := addProtocolFinalizerMiddlewares(stack, options, "StartQuery"); 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 = addOpStartQueryValidationMiddleware(stack); err != nil {
		return err
	}
	if err = stack.Initialize.Add(newServiceMetadataMiddleware_opStartQuery(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_opStartQuery(region string) *awsmiddleware.RegisterServiceMetadata {
	return &awsmiddleware.RegisterServiceMetadata{
		Region:        region,
		ServiceID:     ServiceID,
		OperationName: "StartQuery",
	}
}
