// Code generated by private/model/cli/gen-api/main.go. DO NOT EDIT.

package cloudwatch

import (
	"context"
	"fmt"
	"time"

	"github.com/aws/aws-sdk-go-v2/aws"
	"github.com/aws/aws-sdk-go-v2/internal/awsutil"
)

// Please also see https://docs.aws.amazon.com/goto/WebAPI/monitoring-2010-08-01/GetMetricStatisticsInput
type GetMetricStatisticsInput struct {
	_ struct{} `type:"structure"`

	// The dimensions. If the metric contains multiple dimensions, you must include
	// a value for each dimension. CloudWatch treats each unique combination of
	// dimensions as a separate metric. If a specific combination of dimensions
	// was not published, you can't retrieve statistics for it. You must specify
	// the same dimensions that were used when the metrics were created. For an
	// example, see Dimension Combinations (https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/cloudwatch_concepts.html#dimension-combinations)
	// in the Amazon CloudWatch User Guide. For more information about specifying
	// dimensions, see Publishing Metrics (https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/publishingMetrics.html)
	// in the Amazon CloudWatch User Guide.
	Dimensions []Dimension `type:"list"`

	// The time stamp that determines the last data point to return.
	//
	// The value specified is exclusive; results include data points up to the specified
	// time stamp. The time stamp must be in ISO 8601 UTC format (for example, 2016-10-10T23:00:00Z).
	//
	// EndTime is a required field
	EndTime *time.Time `type:"timestamp" timestampFormat:"iso8601" required:"true"`

	// The percentile statistics. Specify values between p0.0 and p100. When calling
	// GetMetricStatistics, you must specify either Statistics or ExtendedStatistics,
	// but not both. Percentile statistics are not available for metrics when any
	// of the metric values are negative numbers.
	ExtendedStatistics []string `min:"1" type:"list"`

	// The name of the metric, with or without spaces.
	//
	// MetricName is a required field
	MetricName *string `min:"1" type:"string" required:"true"`

	// The namespace of the metric, with or without spaces.
	//
	// Namespace is a required field
	Namespace *string `min:"1" type:"string" required:"true"`

	// The granularity, in seconds, of the returned data points. For metrics with
	// regular resolution, a period can be as short as one minute (60 seconds) and
	// must be a multiple of 60. For high-resolution metrics that are collected
	// at intervals of less than one minute, the period can be 1, 5, 10, 30, 60,
	// or any multiple of 60. High-resolution metrics are those metrics stored by
	// a PutMetricData call that includes a StorageResolution of 1 second.
	//
	// If the StartTime parameter specifies a time stamp that is greater than 3
	// hours ago, you must specify the period as follows or no data points in that
	// time range is returned:
	//
	//    * Start time between 3 hours and 15 days ago - Use a multiple of 60 seconds
	//    (1 minute).
	//
	//    * Start time between 15 and 63 days ago - Use a multiple of 300 seconds
	//    (5 minutes).
	//
	//    * Start time greater than 63 days ago - Use a multiple of 3600 seconds
	//    (1 hour).
	//
	// Period is a required field
	Period *int64 `min:"1" type:"integer" required:"true"`

	// The time stamp that determines the first data point to return. Start times
	// are evaluated relative to the time that CloudWatch receives the request.
	//
	// The value specified is inclusive; results include data points with the specified
	// time stamp. The time stamp must be in ISO 8601 UTC format (for example, 2016-10-03T23:00:00Z).
	//
	// CloudWatch rounds the specified time stamp as follows:
	//
	//    * Start time less than 15 days ago - Round down to the nearest whole minute.
	//    For example, 12:32:34 is rounded down to 12:32:00.
	//
	//    * Start time between 15 and 63 days ago - Round down to the nearest 5-minute
	//    clock interval. For example, 12:32:34 is rounded down to 12:30:00.
	//
	//    * Start time greater than 63 days ago - Round down to the nearest 1-hour
	//    clock interval. For example, 12:32:34 is rounded down to 12:00:00.
	//
	// If you set Period to 5, 10, or 30, the start time of your request is rounded
	// down to the nearest time that corresponds to even 5-, 10-, or 30-second divisions
	// of a minute. For example, if you make a query at (HH:mm:ss) 01:05:23 for
	// the previous 10-second period, the start time of your request is rounded
	// down and you receive data from 01:05:10 to 01:05:20. If you make a query
	// at 15:07:17 for the previous 5 minutes of data, using a period of 5 seconds,
	// you receive data timestamped between 15:02:15 and 15:07:15.
	//
	// StartTime is a required field
	StartTime *time.Time `type:"timestamp" timestampFormat:"iso8601" required:"true"`

	// The metric statistics, other than percentile. For percentile statistics,
	// use ExtendedStatistics. When calling GetMetricStatistics, you must specify
	// either Statistics or ExtendedStatistics, but not both.
	Statistics []Statistic `min:"1" type:"list"`

	// The unit for a given metric. Metrics may be reported in multiple units. Not
	// supplying a unit results in all units being returned. If you specify only
	// a unit that the metric does not report, the results of the call are null.
	Unit StandardUnit `type:"string" enum:"true"`
}

// String returns the string representation
func (s GetMetricStatisticsInput) String() string {
	return awsutil.Prettify(s)
}

// Validate inspects the fields of the type to determine if they are valid.
func (s *GetMetricStatisticsInput) Validate() error {
	invalidParams := aws.ErrInvalidParams{Context: "GetMetricStatisticsInput"}

	if s.EndTime == nil {
		invalidParams.Add(aws.NewErrParamRequired("EndTime"))
	}
	if s.ExtendedStatistics != nil && len(s.ExtendedStatistics) < 1 {
		invalidParams.Add(aws.NewErrParamMinLen("ExtendedStatistics", 1))
	}

	if s.MetricName == nil {
		invalidParams.Add(aws.NewErrParamRequired("MetricName"))
	}
	if s.MetricName != nil && len(*s.MetricName) < 1 {
		invalidParams.Add(aws.NewErrParamMinLen("MetricName", 1))
	}

	if s.Namespace == nil {
		invalidParams.Add(aws.NewErrParamRequired("Namespace"))
	}
	if s.Namespace != nil && len(*s.Namespace) < 1 {
		invalidParams.Add(aws.NewErrParamMinLen("Namespace", 1))
	}

	if s.Period == nil {
		invalidParams.Add(aws.NewErrParamRequired("Period"))
	}
	if s.Period != nil && *s.Period < 1 {
		invalidParams.Add(aws.NewErrParamMinValue("Period", 1))
	}

	if s.StartTime == nil {
		invalidParams.Add(aws.NewErrParamRequired("StartTime"))
	}
	if s.Statistics != nil && len(s.Statistics) < 1 {
		invalidParams.Add(aws.NewErrParamMinLen("Statistics", 1))
	}
	if s.Dimensions != nil {
		for i, v := range s.Dimensions {
			if err := v.Validate(); err != nil {
				invalidParams.AddNested(fmt.Sprintf("%s[%v]", "Dimensions", i), err.(aws.ErrInvalidParams))
			}
		}
	}

	if invalidParams.Len() > 0 {
		return invalidParams
	}
	return nil
}

// Please also see https://docs.aws.amazon.com/goto/WebAPI/monitoring-2010-08-01/GetMetricStatisticsOutput
type GetMetricStatisticsOutput struct {
	_ struct{} `type:"structure"`

	// The data points for the specified metric.
	Datapoints []Datapoint `type:"list"`

	// A label for the specified metric.
	Label *string `type:"string"`
}

// String returns the string representation
func (s GetMetricStatisticsOutput) String() string {
	return awsutil.Prettify(s)
}

const opGetMetricStatistics = "GetMetricStatistics"

// GetMetricStatisticsRequest returns a request value for making API operation for
// Amazon CloudWatch.
//
// Gets statistics for the specified metric.
//
// The maximum number of data points returned from a single call is 1,440. If
// you request more than 1,440 data points, CloudWatch returns an error. To
// reduce the number of data points, you can narrow the specified time range
// and make multiple requests across adjacent time ranges, or you can increase
// the specified period. Data points are not returned in chronological order.
//
// CloudWatch aggregates data points based on the length of the period that
// you specify. For example, if you request statistics with a one-hour period,
// CloudWatch aggregates all data points with time stamps that fall within each
// one-hour period. Therefore, the number of values aggregated by CloudWatch
// is larger than the number of data points returned.
//
// CloudWatch needs raw data points to calculate percentile statistics. If you
// publish data using a statistic set instead, you can only retrieve percentile
// statistics for this data if one of the following conditions is true:
//
//    * The SampleCount value of the statistic set is 1.
//
//    * The Min and the Max values of the statistic set are equal.
//
// Percentile statistics are not available for metrics when any of the metric
// values are negative numbers.
//
// Amazon CloudWatch retains metric data as follows:
//
//    * Data points with a period of less than 60 seconds are available for
//    3 hours. These data points are high-resolution metrics and are available
//    only for custom metrics that have been defined with a StorageResolution
//    of 1.
//
//    * 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
//    455 days (15 months).
//
// Data points that are initially published with a shorter period are aggregated
// together for long-term storage. For example, if you collect data using a
// period of 1 minute, the data remains available for 15 days with 1-minute
// resolution. After 15 days, this data is still available, but is aggregated
// and retrievable only with a resolution of 5 minutes. After 63 days, the data
// is further aggregated and is available with a resolution of 1 hour.
//
// CloudWatch started retaining 5-minute and 1-hour metric data as of July 9,
// 2016.
//
// For information about metrics and dimensions supported by AWS services, see
// the Amazon CloudWatch Metrics and Dimensions Reference (https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CW_Support_For_AWS.html)
// in the Amazon CloudWatch User Guide.
//
//    // Example sending a request using GetMetricStatisticsRequest.
//    req := client.GetMetricStatisticsRequest(params)
//    resp, err := req.Send(context.TODO())
//    if err == nil {
//        fmt.Println(resp)
//    }
//
// Please also see https://docs.aws.amazon.com/goto/WebAPI/monitoring-2010-08-01/GetMetricStatistics
func (c *Client) GetMetricStatisticsRequest(input *GetMetricStatisticsInput) GetMetricStatisticsRequest {
	op := &aws.Operation{
		Name:       opGetMetricStatistics,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &GetMetricStatisticsInput{}
	}

	req := c.newRequest(op, input, &GetMetricStatisticsOutput{})
	return GetMetricStatisticsRequest{Request: req, Input: input, Copy: c.GetMetricStatisticsRequest}
}

// GetMetricStatisticsRequest is the request type for the
// GetMetricStatistics API operation.
type GetMetricStatisticsRequest struct {
	*aws.Request
	Input *GetMetricStatisticsInput
	Copy  func(*GetMetricStatisticsInput) GetMetricStatisticsRequest
}

// Send marshals and sends the GetMetricStatistics API request.
func (r GetMetricStatisticsRequest) Send(ctx context.Context) (*GetMetricStatisticsResponse, error) {
	r.Request.SetContext(ctx)
	err := r.Request.Send()
	if err != nil {
		return nil, err
	}

	resp := &GetMetricStatisticsResponse{
		GetMetricStatisticsOutput: r.Request.Data.(*GetMetricStatisticsOutput),
		response:                  &aws.Response{Request: r.Request},
	}

	return resp, nil
}

// GetMetricStatisticsResponse is the response type for the
// GetMetricStatistics API operation.
type GetMetricStatisticsResponse struct {
	*GetMetricStatisticsOutput

	response *aws.Response
}

// SDKResponseMetdata returns the response metadata for the
// GetMetricStatistics request.
func (r *GetMetricStatisticsResponse) SDKResponseMetdata() *aws.Response {
	return r.response
}
