// THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT.

// Package marketplacemetering provides a client for AWSMarketplace Metering.
package marketplacemetering

import (
	"time"

	"github.com/aws/aws-sdk-go/aws/awsutil"
	"github.com/aws/aws-sdk-go/aws/request"
)

const opMeterUsage = "MeterUsage"

// MeterUsageRequest generates a "aws/request.Request" representing the
// client's request for the MeterUsage operation. The "output" return
// value can be used to capture response data after the request's "Send" method
// is called.
//
// See MeterUsage for usage and error information.
//
// Creating a request object using this method should be used when you want to inject
// custom logic into the request's lifecycle using a custom handler, or if you want to
// access properties on the request object before or after sending the request. If
// you just want the service response, call the MeterUsage method directly
// instead.
//
// Note: You must call the "Send" method on the returned request object in order
// to execute the request.
//
//    // Example sending a request using the MeterUsageRequest method.
//    req, resp := client.MeterUsageRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
func (c *MarketplaceMetering) MeterUsageRequest(input *MeterUsageInput) (req *request.Request, output *MeterUsageOutput) {
	op := &request.Operation{
		Name:       opMeterUsage,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &MeterUsageInput{}
	}

	req = c.newRequest(op, input, output)
	output = &MeterUsageOutput{}
	req.Data = output
	return
}

// MeterUsage API operation for AWSMarketplace Metering.
//
// API to emit metering records. For identical requests, the API is idempotent.
// It simply returns the metering record ID.
//
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
// with awserr.Error's Code and Message methods to get detailed information about
// the error.
//
// See the AWS API reference guide for AWSMarketplace Metering's
// API operation MeterUsage for usage and error information.
//
// Returned Error Codes:
//   * InternalServiceErrorException
//   An internal error has occurred. Retry your request. If the problem persists,
//   post a message with details on the AWS forums.
//
//   * InvalidProductCodeException
//   The product code passed does not match the product code used for publishing
//   the product.
//
//   * InvalidUsageDimensionException
//   The usage dimension does not match one of the UsageDimensions associated
//   with products.
//
//   * InvalidEndpointRegionException
//   The endpoint being called is in a region different from your EC2 instance.
//   The region of the Metering service endpoint and the region of the EC2 instance
//   must match.
//
//   * TimestampOutOfBoundsException
//   The timestamp value passed in the meterUsage() is out of allowed range.
//
//   * DuplicateRequestException
//   A metering record has already been emitted by the same EC2 instance for the
//   given {usageDimension, timestamp} with a different usageQuantity.
//
//   * ThrottlingException
//   The calls to the MeterUsage API are throttled.
//
func (c *MarketplaceMetering) MeterUsage(input *MeterUsageInput) (*MeterUsageOutput, error) {
	req, out := c.MeterUsageRequest(input)
	err := req.Send()
	return out, err
}

type MeterUsageInput struct {
	_ struct{} `type:"structure"`

	// Checks whether you have the permissions required for the action, but does
	// not make the request. If you have the permissions, the request returns DryRunOperation;
	// otherwise, it returns UnauthorizedException.
	//
	// DryRun is a required field
	DryRun *bool `type:"boolean" required:"true"`

	// Product code is used to uniquely identify a product in AWS Marketplace. The
	// product code should be the same as the one used during the publishing of
	// a new product.
	//
	// ProductCode is a required field
	ProductCode *string `min:"1" type:"string" required:"true"`

	// Timestamp of the hour, recorded in UTC. The seconds and milliseconds portions
	// of the timestamp will be ignored.
	//
	// Timestamp is a required field
	Timestamp *time.Time `type:"timestamp" timestampFormat:"unix" required:"true"`

	// It will be one of the 'fcp dimension name' provided during the publishing
	// of the product.
	//
	// UsageDimension is a required field
	UsageDimension *string `min:"1" type:"string" required:"true"`

	// Consumption value for the hour.
	//
	// UsageQuantity is a required field
	UsageQuantity *int64 `type:"integer" required:"true"`
}

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

// GoString returns the string representation
func (s MeterUsageInput) GoString() string {
	return s.String()
}

// Validate inspects the fields of the type to determine if they are valid.
func (s *MeterUsageInput) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "MeterUsageInput"}
	if s.DryRun == nil {
		invalidParams.Add(request.NewErrParamRequired("DryRun"))
	}
	if s.ProductCode == nil {
		invalidParams.Add(request.NewErrParamRequired("ProductCode"))
	}
	if s.ProductCode != nil && len(*s.ProductCode) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("ProductCode", 1))
	}
	if s.Timestamp == nil {
		invalidParams.Add(request.NewErrParamRequired("Timestamp"))
	}
	if s.UsageDimension == nil {
		invalidParams.Add(request.NewErrParamRequired("UsageDimension"))
	}
	if s.UsageDimension != nil && len(*s.UsageDimension) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("UsageDimension", 1))
	}
	if s.UsageQuantity == nil {
		invalidParams.Add(request.NewErrParamRequired("UsageQuantity"))
	}

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

type MeterUsageOutput struct {
	_ struct{} `type:"structure"`

	MeteringRecordId *string `type:"string"`
}

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

// GoString returns the string representation
func (s MeterUsageOutput) GoString() string {
	return s.String()
}
