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

package budgets

import (
	"fmt"
	"time"

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

var _ aws.Config
var _ = awsutil.Prettify

// Represents the output of the CreateBudget operation. The content consists
// of the detailed metadata and data file information, and the current status
// of the budget object.
//
// This is the ARN pattern for a budget:
//
// arn:aws:budgetservice::AccountId:budget/budgetName
type Budget struct {
	_ struct{} `type:"structure"`

	// The total amount of cost, usage, RI utilization, RI coverage, Savings Plans
	// utilization, or Savings Plans coverage that you want to track with your budget.
	//
	// BudgetLimit is required for cost or usage budgets, but optional for RI or
	// Savings Plans utilization or coverage budgets. RI and Savings Plans utilization
	// or coverage budgets default to 100, which is the only valid value for RI
	// or Savings Plans utilization or coverage budgets. You can't use BudgetLimit
	// with PlannedBudgetLimits for CreateBudget and UpdateBudget actions.
	BudgetLimit *Spend `type:"structure"`

	// The name of a budget. The name must be unique within an account. The : and
	// \ characters aren't allowed in BudgetName.
	//
	// BudgetName is a required field
	BudgetName *string `min:"1" type:"string" required:"true"`

	// Whether this budget tracks costs, usage, RI utilization, RI coverage, Savings
	// Plans utilization, or Savings Plans coverage.
	//
	// BudgetType is a required field
	BudgetType BudgetType `type:"string" required:"true" enum:"true"`

	// The actual and forecasted cost or usage that the budget tracks.
	CalculatedSpend *CalculatedSpend `type:"structure"`

	// The cost filters, such as service or tag, that are applied to a budget.
	//
	// AWS Budgets supports the following services as a filter for RI budgets:
	//
	//    * Amazon Elastic Compute Cloud - Compute
	//
	//    * Amazon Redshift
	//
	//    * Amazon Relational Database Service
	//
	//    * Amazon ElastiCache
	//
	//    * Amazon Elasticsearch Service
	CostFilters map[string][]string `type:"map"`

	// The types of costs that are included in this COST budget.
	//
	// USAGE, RI_UTILIZATION, RI_COVERAGE, Savings_Plans_Utilization, and Savings_Plans_Coverage
	// budgets do not have CostTypes.
	CostTypes *CostTypes `type:"structure"`

	// The last time that you updated this budget.
	LastUpdatedTime *time.Time `type:"timestamp"`

	// A map containing multiple BudgetLimit, including current or future limits.
	//
	// PlannedBudgetLimits is available for cost or usage budget and supports monthly
	// and quarterly TimeUnit.
	//
	// For monthly budgets, provide 12 months of PlannedBudgetLimits values. This
	// must start from the current month and include the next 11 months. The key
	// is the start of the month, UTC in epoch seconds.
	//
	// For quarterly budgets, provide 4 quarters of PlannedBudgetLimits value entries
	// in standard calendar quarter increments. This must start from the current
	// quarter and include the next 3 quarters. The key is the start of the quarter,
	// UTC in epoch seconds.
	//
	// If the planned budget expires before 12 months for monthly or 4 quarters
	// for quarterly, provide the PlannedBudgetLimits values only for the remaining
	// periods.
	//
	// If the budget begins at a date in the future, provide PlannedBudgetLimits
	// values from the start date of the budget.
	//
	// After all of the BudgetLimit values in PlannedBudgetLimits are used, the
	// budget continues to use the last limit as the BudgetLimit. At that point,
	// the planned budget provides the same experience as a fixed budget.
	//
	// DescribeBudget and DescribeBudgets response along with PlannedBudgetLimits
	// will also contain BudgetLimit representing the current month or quarter limit
	// present in PlannedBudgetLimits. This only applies to budgets created with
	// PlannedBudgetLimits. Budgets created without PlannedBudgetLimits will only
	// contain BudgetLimit, and no PlannedBudgetLimits.
	PlannedBudgetLimits map[string]Spend `type:"map"`

	// The period of time that is covered by a budget. The period has a start date
	// and an end date. The start date must come before the end date. The end date
	// must come before 06/15/87 00:00 UTC.
	//
	// If you create your budget and don't specify a start date, AWS defaults to
	// the start of your chosen time period (DAILY, MONTHLY, QUARTERLY, or ANNUALLY).
	// For example, if you created your budget on January 24, 2018, chose DAILY,
	// and didn't set a start date, AWS set your start date to 01/24/18 00:00 UTC.
	// If you chose MONTHLY, AWS set your start date to 01/01/18 00:00 UTC. If you
	// didn't specify an end date, AWS set your end date to 06/15/87 00:00 UTC.
	// The defaults are the same for the AWS Billing and Cost Management console
	// and the API.
	//
	// You can change either date with the UpdateBudget operation.
	//
	// After the end date, AWS deletes the budget and all associated notifications
	// and subscribers.
	TimePeriod *TimePeriod `type:"structure"`

	// The length of time until a budget resets the actual and forecasted spend.
	// DAILY is available only for RI_UTILIZATION, RI_COVERAGE, Savings_Plans_Utilization,
	// and Savings_Plans_Coverage budgets.
	//
	// TimeUnit is a required field
	TimeUnit TimeUnit `type:"string" required:"true" enum:"true"`
}

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

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

	if s.BudgetName == nil {
		invalidParams.Add(aws.NewErrParamRequired("BudgetName"))
	}
	if s.BudgetName != nil && len(*s.BudgetName) < 1 {
		invalidParams.Add(aws.NewErrParamMinLen("BudgetName", 1))
	}
	if len(s.BudgetType) == 0 {
		invalidParams.Add(aws.NewErrParamRequired("BudgetType"))
	}
	if len(s.TimeUnit) == 0 {
		invalidParams.Add(aws.NewErrParamRequired("TimeUnit"))
	}
	if s.BudgetLimit != nil {
		if err := s.BudgetLimit.Validate(); err != nil {
			invalidParams.AddNested("BudgetLimit", err.(aws.ErrInvalidParams))
		}
	}
	if s.CalculatedSpend != nil {
		if err := s.CalculatedSpend.Validate(); err != nil {
			invalidParams.AddNested("CalculatedSpend", err.(aws.ErrInvalidParams))
		}
	}
	if s.PlannedBudgetLimits != nil {
		for i, v := range s.PlannedBudgetLimits {
			if err := v.Validate(); err != nil {
				invalidParams.AddNested(fmt.Sprintf("%s[%v]", "PlannedBudgetLimits", i), err.(aws.ErrInvalidParams))
			}
		}
	}

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

// A history of the state of a budget at the end of the budget's specified time
// period.
type BudgetPerformanceHistory struct {
	_ struct{} `type:"structure"`

	// A string that represents the budget name. The ":" and "\" characters aren't
	// allowed.
	BudgetName *string `min:"1" type:"string"`

	// The type of a budget. It must be one of the following types:
	//
	// COST, USAGE, RI_UTILIZATION, or RI_COVERAGE.
	BudgetType BudgetType `type:"string" enum:"true"`

	// A list of amounts of cost or usage that you created budgets for, compared
	// to your actual costs or usage.
	BudgetedAndActualAmountsList []BudgetedAndActualAmounts `type:"list"`

	// The history of the cost filters for a budget during the specified time period.
	CostFilters map[string][]string `type:"map"`

	// The history of the cost types for a budget during the specified time period.
	CostTypes *CostTypes `type:"structure"`

	// The time unit of the budget, such as MONTHLY or QUARTERLY.
	TimeUnit TimeUnit `type:"string" enum:"true"`
}

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

// The amount of cost or usage that you created the budget for, compared to
// your actual costs or usage.
type BudgetedAndActualAmounts struct {
	_ struct{} `type:"structure"`

	// Your actual costs or usage for a budget period.
	ActualAmount *Spend `type:"structure"`

	// The amount of cost or usage that you created the budget for.
	BudgetedAmount *Spend `type:"structure"`

	// The time period covered by this budget comparison.
	TimePeriod *TimePeriod `type:"structure"`
}

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

// The spend objects that are associated with this budget. The actualSpend tracks
// how much you've used, cost, usage, or RI units, and the forecastedSpend tracks
// how much you are predicted to spend if your current usage remains steady.
//
// For example, if it is the 20th of the month and you have spent 50 dollars
// on Amazon EC2, your actualSpend is 50 USD, and your forecastedSpend is 75
// USD.
type CalculatedSpend struct {
	_ struct{} `type:"structure"`

	// The amount of cost, usage, or RI units that you have used.
	//
	// ActualSpend is a required field
	ActualSpend *Spend `type:"structure" required:"true"`

	// The amount of cost, usage, or RI units that you are forecasted to use.
	ForecastedSpend *Spend `type:"structure"`
}

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

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

	if s.ActualSpend == nil {
		invalidParams.Add(aws.NewErrParamRequired("ActualSpend"))
	}
	if s.ActualSpend != nil {
		if err := s.ActualSpend.Validate(); err != nil {
			invalidParams.AddNested("ActualSpend", err.(aws.ErrInvalidParams))
		}
	}
	if s.ForecastedSpend != nil {
		if err := s.ForecastedSpend.Validate(); err != nil {
			invalidParams.AddNested("ForecastedSpend", err.(aws.ErrInvalidParams))
		}
	}

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

// The types of cost that are included in a COST budget, such as tax and subscriptions.
//
// USAGE, RI_UTILIZATION, and RI_COVERAGE budgets do not have CostTypes.
type CostTypes struct {
	_ struct{} `type:"structure"`

	// Specifies whether a budget includes credits.
	//
	// The default value is true.
	IncludeCredit *bool `type:"boolean"`

	// Specifies whether a budget includes discounts.
	//
	// The default value is true.
	IncludeDiscount *bool `type:"boolean"`

	// Specifies whether a budget includes non-RI subscription costs.
	//
	// The default value is true.
	IncludeOtherSubscription *bool `type:"boolean"`

	// Specifies whether a budget includes recurring fees such as monthly RI fees.
	//
	// The default value is true.
	IncludeRecurring *bool `type:"boolean"`

	// Specifies whether a budget includes refunds.
	//
	// The default value is true.
	IncludeRefund *bool `type:"boolean"`

	// Specifies whether a budget includes subscriptions.
	//
	// The default value is true.
	IncludeSubscription *bool `type:"boolean"`

	// Specifies whether a budget includes support subscription fees.
	//
	// The default value is true.
	IncludeSupport *bool `type:"boolean"`

	// Specifies whether a budget includes taxes.
	//
	// The default value is true.
	IncludeTax *bool `type:"boolean"`

	// Specifies whether a budget includes upfront RI costs.
	//
	// The default value is true.
	IncludeUpfront *bool `type:"boolean"`

	// Specifies whether a budget uses the amortized rate.
	//
	// The default value is false.
	UseAmortized *bool `type:"boolean"`

	// Specifies whether a budget uses a blended rate.
	//
	// The default value is false.
	UseBlended *bool `type:"boolean"`
}

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

// A notification that is associated with a budget. A budget can have up to
// five notifications.
//
// Each notification must have at least one subscriber. A notification can have
// one SNS subscriber and up to 10 email subscribers, for a total of 11 subscribers.
//
// For example, if you have a budget for 200 dollars and you want to be notified
// when you go over 160 dollars, create a notification with the following parameters:
//
//    * A notificationType of ACTUAL
//
//    * A thresholdType of PERCENTAGE
//
//    * A comparisonOperator of GREATER_THAN
//
//    * A notification threshold of 80
type Notification struct {
	_ struct{} `type:"structure"`

	// The comparison that is used for this notification.
	//
	// ComparisonOperator is a required field
	ComparisonOperator ComparisonOperator `type:"string" required:"true" enum:"true"`

	// Whether this notification is in alarm. If a budget notification is in the
	// ALARM state, you have passed the set threshold for the budget.
	NotificationState NotificationState `type:"string" enum:"true"`

	// Whether the notification is for how much you have spent (ACTUAL) or for how
	// much you're forecasted to spend (FORECASTED).
	//
	// NotificationType is a required field
	NotificationType NotificationType `type:"string" required:"true" enum:"true"`

	// The threshold that is associated with a notification. Thresholds are always
	// a percentage.
	//
	// Threshold is a required field
	Threshold *float64 `type:"double" required:"true"`

	// The type of threshold for a notification. For ABSOLUTE_VALUE thresholds,
	// AWS notifies you when you go over or are forecasted to go over your total
	// cost threshold. For PERCENTAGE thresholds, AWS notifies you when you go over
	// or are forecasted to go over a certain percentage of your forecasted spend.
	// For example, if you have a budget for 200 dollars and you have a PERCENTAGE
	// threshold of 80%, AWS notifies you when you go over 160 dollars.
	ThresholdType ThresholdType `type:"string" enum:"true"`
}

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

// Validate inspects the fields of the type to determine if they are valid.
func (s *Notification) Validate() error {
	invalidParams := aws.ErrInvalidParams{Context: "Notification"}
	if len(s.ComparisonOperator) == 0 {
		invalidParams.Add(aws.NewErrParamRequired("ComparisonOperator"))
	}
	if len(s.NotificationType) == 0 {
		invalidParams.Add(aws.NewErrParamRequired("NotificationType"))
	}

	if s.Threshold == nil {
		invalidParams.Add(aws.NewErrParamRequired("Threshold"))
	}

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

// A notification with subscribers. A notification can have one SNS subscriber
// and up to 10 email subscribers, for a total of 11 subscribers.
type NotificationWithSubscribers struct {
	_ struct{} `type:"structure"`

	// The notification that is associated with a budget.
	//
	// Notification is a required field
	Notification *Notification `type:"structure" required:"true"`

	// A list of subscribers who are subscribed to this notification.
	//
	// Subscribers is a required field
	Subscribers []Subscriber `min:"1" type:"list" required:"true"`
}

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

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

	if s.Notification == nil {
		invalidParams.Add(aws.NewErrParamRequired("Notification"))
	}

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

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

// The amount of cost or usage that is measured for a budget.
//
// For example, a Spend for 3 GB of S3 usage would have the following parameters:
//
//    * An Amount of 3
//
//    * A unit of GB
type Spend struct {
	_ struct{} `type:"structure"`

	// The cost or usage amount that is associated with a budget forecast, actual
	// spend, or budget threshold.
	//
	// Amount is a required field
	Amount *string `min:"1" type:"string" required:"true"`

	// The unit of measurement that is used for the budget forecast, actual spend,
	// or budget threshold, such as dollars or GB.
	//
	// Unit is a required field
	Unit *string `min:"1" type:"string" required:"true"`
}

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

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

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

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

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

// The subscriber to a budget notification. The subscriber consists of a subscription
// type and either an Amazon SNS topic or an email address.
//
// For example, an email subscriber would have the following parameters:
//
//    * A subscriptionType of EMAIL
//
//    * An address of example@example.com
type Subscriber struct {
	_ struct{} `type:"structure"`

	// The address that AWS sends budget notifications to, either an SNS topic or
	// an email.
	//
	// When you create a subscriber, the value of Address can't contain line breaks.
	//
	// Address is a required field
	Address *string `min:"1" type:"string" required:"true" sensitive:"true"`

	// The type of notification that AWS sends to a subscriber.
	//
	// SubscriptionType is a required field
	SubscriptionType SubscriptionType `type:"string" required:"true" enum:"true"`
}

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

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

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

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

// The period of time that is covered by a budget. The period has a start date
// and an end date. The start date must come before the end date. There are
// no restrictions on the end date.
type TimePeriod struct {
	_ struct{} `type:"structure"`

	// The end date for a budget. If you didn't specify an end date, AWS set your
	// end date to 06/15/87 00:00 UTC. The defaults are the same for the AWS Billing
	// and Cost Management console and the API.
	//
	// After the end date, AWS deletes the budget and all associated notifications
	// and subscribers. You can change your end date with the UpdateBudget operation.
	End *time.Time `type:"timestamp"`

	// The start date for a budget. If you created your budget and didn't specify
	// a start date, AWS defaults to the start of your chosen time period (DAILY,
	// MONTHLY, QUARTERLY, or ANNUALLY). For example, if you created your budget
	// on January 24, 2018, chose DAILY, and didn't set a start date, AWS set your
	// start date to 01/24/18 00:00 UTC. If you chose MONTHLY, AWS set your start
	// date to 01/01/18 00:00 UTC. The defaults are the same for the AWS Billing
	// and Cost Management console and the API.
	//
	// You can change your start date with the UpdateBudget operation.
	Start *time.Time `type:"timestamp"`
}

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