package costmanagement

// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
//
// Code generated by Microsoft (R) AutoRest Code Generator.
// Changes may cause incorrect behavior and will be lost if the code is regenerated.

import (
	"context"
	"encoding/json"
	"github.com/Azure/go-autorest/autorest"
	"github.com/Azure/go-autorest/autorest/date"
	"github.com/Azure/go-autorest/autorest/to"
	"github.com/Azure/go-autorest/tracing"
	"github.com/shopspring/decimal"
	"net/http"
)

// The package's fully qualified name.
const fqdn = "github.com/Azure/azure-sdk-for-go/services/costmanagement/mgmt/2020-06-01/costmanagement"

// Alert an individual alert.
type Alert struct {
	autorest.Response `json:"-"`
	*AlertProperties  `json:"properties,omitempty"`
	// ID - READ-ONLY; Resource Id.
	ID *string `json:"id,omitempty"`
	// Name - READ-ONLY; Resource name.
	Name *string `json:"name,omitempty"`
	// Type - READ-ONLY; Resource type.
	Type *string `json:"type,omitempty"`
	// Tags - READ-ONLY; Resource tags.
	Tags map[string]*string `json:"tags"`
}

// MarshalJSON is the custom marshaler for Alert.
func (a Alert) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]interface{})
	if a.AlertProperties != nil {
		objectMap["properties"] = a.AlertProperties
	}
	return json.Marshal(objectMap)
}

// UnmarshalJSON is the custom unmarshaler for Alert struct.
func (a *Alert) UnmarshalJSON(body []byte) error {
	var m map[string]*json.RawMessage
	err := json.Unmarshal(body, &m)
	if err != nil {
		return err
	}
	for k, v := range m {
		switch k {
		case "properties":
			if v != nil {
				var alertProperties AlertProperties
				err = json.Unmarshal(*v, &alertProperties)
				if err != nil {
					return err
				}
				a.AlertProperties = &alertProperties
			}
		case "id":
			if v != nil {
				var ID string
				err = json.Unmarshal(*v, &ID)
				if err != nil {
					return err
				}
				a.ID = &ID
			}
		case "name":
			if v != nil {
				var name string
				err = json.Unmarshal(*v, &name)
				if err != nil {
					return err
				}
				a.Name = &name
			}
		case "type":
			if v != nil {
				var typeVar string
				err = json.Unmarshal(*v, &typeVar)
				if err != nil {
					return err
				}
				a.Type = &typeVar
			}
		case "tags":
			if v != nil {
				var tags map[string]*string
				err = json.Unmarshal(*v, &tags)
				if err != nil {
					return err
				}
				a.Tags = tags
			}
		}
	}

	return nil
}

// AlertProperties ...
type AlertProperties struct {
	// Definition - defines the type of alert
	Definition *AlertPropertiesDefinition `json:"definition,omitempty"`
	// Description - Alert description
	Description *string `json:"description,omitempty"`
	// Source - Source of alert. Possible values include: 'Preset', 'User'
	Source AlertSource `json:"source,omitempty"`
	// Details - Alert details
	Details *AlertPropertiesDetails `json:"details,omitempty"`
	// CostEntityID - related budget
	CostEntityID *string `json:"costEntityId,omitempty"`
	// Status - alert status. Possible values include: 'AlertStatusNone', 'AlertStatusActive', 'AlertStatusOverridden', 'AlertStatusResolved', 'AlertStatusDismissed'
	Status AlertStatus `json:"status,omitempty"`
	// CreationTime - dateTime in which alert was created
	CreationTime *string `json:"creationTime,omitempty"`
	// CloseTime - dateTime in which alert was closed
	CloseTime *string `json:"closeTime,omitempty"`
	// ModificationTime - dateTime in which alert was last modified
	ModificationTime           *string `json:"modificationTime,omitempty"`
	StatusModificationUserName *string `json:"statusModificationUserName,omitempty"`
	// StatusModificationTime - dateTime in which the alert status was last modified
	StatusModificationTime *string `json:"statusModificationTime,omitempty"`
}

// AlertPropertiesDefinition defines the type of alert
type AlertPropertiesDefinition struct {
	// Type - type of alert. Possible values include: 'Budget', 'Invoice', 'Credit', 'Quota', 'General', 'XCloud', 'BudgetForecast'
	Type AlertType `json:"type,omitempty"`
	// Category - Alert category. Possible values include: 'Cost', 'Usage', 'Billing', 'System'
	Category AlertCategory `json:"category,omitempty"`
	// Criteria - Criteria that triggered alert. Possible values include: 'CostThresholdExceeded', 'UsageThresholdExceeded', 'CreditThresholdApproaching', 'CreditThresholdReached', 'QuotaThresholdApproaching', 'QuotaThresholdReached', 'MultiCurrency', 'ForecastCostThresholdExceeded', 'ForecastUsageThresholdExceeded', 'InvoiceDueDateApproaching', 'InvoiceDueDateReached', 'CrossCloudNewDataAvailable', 'CrossCloudCollectionError', 'GeneralThresholdError'
	Criteria AlertCriteria `json:"criteria,omitempty"`
}

// AlertPropertiesDetails alert details
type AlertPropertiesDetails struct {
	// TimeGrainType - Type of timegrain cadence. Possible values include: 'AlertTimeGrainTypeNone', 'AlertTimeGrainTypeMonthly', 'AlertTimeGrainTypeQuarterly', 'AlertTimeGrainTypeAnnually', 'AlertTimeGrainTypeBillingMonth', 'AlertTimeGrainTypeBillingQuarter', 'AlertTimeGrainTypeBillingAnnual'
	TimeGrainType AlertTimeGrainType `json:"timeGrainType,omitempty"`
	// PeriodStartDate - datetime of periodStartDate
	PeriodStartDate *string `json:"periodStartDate,omitempty"`
	// TriggeredBy - notificationId that triggered this alert
	TriggeredBy *string `json:"triggeredBy,omitempty"`
	// ResourceGroupFilter - array of resourceGroups to filter by
	ResourceGroupFilter *[]interface{} `json:"resourceGroupFilter,omitempty"`
	// ResourceFilter - array of resources to filter by
	ResourceFilter *[]interface{} `json:"resourceFilter,omitempty"`
	// MeterFilter - array of meters to filter by
	MeterFilter *[]interface{} `json:"meterFilter,omitempty"`
	// TagFilter - tags to filter by
	TagFilter interface{} `json:"tagFilter,omitempty"`
	// Threshold - notification threshold percentage as a decimal which activated this alert
	Threshold *decimal.Decimal `json:"threshold,omitempty"`
	// Operator - operator used to compare currentSpend with amount. Possible values include: 'None', 'EqualTo', 'GreaterThan', 'GreaterThanOrEqualTo', 'LessThan', 'LessThanOrEqualTo'
	Operator AlertOperator `json:"operator,omitempty"`
	// Amount - budget threshold amount
	Amount *decimal.Decimal `json:"amount,omitempty"`
	// Unit - unit of currency being used
	Unit *string `json:"unit,omitempty"`
	// CurrentSpend - current spend
	CurrentSpend *decimal.Decimal `json:"currentSpend,omitempty"`
	// ContactEmails - list of emails to contact
	ContactEmails *[]string `json:"contactEmails,omitempty"`
	// ContactGroups - list of action groups to broadcast to
	ContactGroups *[]string `json:"contactGroups,omitempty"`
	// ContactRoles - list of contact roles
	ContactRoles *[]string `json:"contactRoles,omitempty"`
	// OverridingAlert - overriding alert
	OverridingAlert *string `json:"overridingAlert,omitempty"`
}

// AlertsResult result of alerts.
type AlertsResult struct {
	autorest.Response `json:"-"`
	// Value - READ-ONLY; List of alerts.
	Value *[]Alert `json:"value,omitempty"`
	// NextLink - READ-ONLY; URL to get the next set of alerts results if there are any.
	NextLink *string `json:"nextLink,omitempty"`
}

// MarshalJSON is the custom marshaler for AlertsResult.
func (ar AlertsResult) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]interface{})
	return json.Marshal(objectMap)
}

// CommonExportProperties the common properties of the export.
type CommonExportProperties struct {
	// Format - The format of the export being delivered. Currently only 'Csv' is supported. Possible values include: 'Csv'
	Format FormatType `json:"format,omitempty"`
	// DeliveryInfo - Has delivery information for the export.
	DeliveryInfo *ExportDeliveryInfo `json:"deliveryInfo,omitempty"`
	// Definition - Has the definition for the export.
	Definition *ExportDefinition `json:"definition,omitempty"`
	// RunHistory - If requested, has the most recent execution history for the export.
	RunHistory *ExportExecutionListResult `json:"runHistory,omitempty"`
	// NextRunTimeEstimate - READ-ONLY; If the export has an active schedule, provides an estimate of the next execution time.
	NextRunTimeEstimate *date.Time `json:"nextRunTimeEstimate,omitempty"`
}

// MarshalJSON is the custom marshaler for CommonExportProperties.
func (cep CommonExportProperties) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]interface{})
	if cep.Format != "" {
		objectMap["format"] = cep.Format
	}
	if cep.DeliveryInfo != nil {
		objectMap["deliveryInfo"] = cep.DeliveryInfo
	}
	if cep.Definition != nil {
		objectMap["definition"] = cep.Definition
	}
	if cep.RunHistory != nil {
		objectMap["runHistory"] = cep.RunHistory
	}
	return json.Marshal(objectMap)
}

// Dimension ...
type Dimension struct {
	*DimensionProperties `json:"properties,omitempty"`
	// ID - READ-ONLY; Resource Id.
	ID *string `json:"id,omitempty"`
	// Name - READ-ONLY; Resource name.
	Name *string `json:"name,omitempty"`
	// Type - READ-ONLY; Resource type.
	Type *string `json:"type,omitempty"`
	// Tags - READ-ONLY; Resource tags.
	Tags map[string]*string `json:"tags"`
}

// MarshalJSON is the custom marshaler for Dimension.
func (d Dimension) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]interface{})
	if d.DimensionProperties != nil {
		objectMap["properties"] = d.DimensionProperties
	}
	return json.Marshal(objectMap)
}

// UnmarshalJSON is the custom unmarshaler for Dimension struct.
func (d *Dimension) UnmarshalJSON(body []byte) error {
	var m map[string]*json.RawMessage
	err := json.Unmarshal(body, &m)
	if err != nil {
		return err
	}
	for k, v := range m {
		switch k {
		case "properties":
			if v != nil {
				var dimensionProperties DimensionProperties
				err = json.Unmarshal(*v, &dimensionProperties)
				if err != nil {
					return err
				}
				d.DimensionProperties = &dimensionProperties
			}
		case "id":
			if v != nil {
				var ID string
				err = json.Unmarshal(*v, &ID)
				if err != nil {
					return err
				}
				d.ID = &ID
			}
		case "name":
			if v != nil {
				var name string
				err = json.Unmarshal(*v, &name)
				if err != nil {
					return err
				}
				d.Name = &name
			}
		case "type":
			if v != nil {
				var typeVar string
				err = json.Unmarshal(*v, &typeVar)
				if err != nil {
					return err
				}
				d.Type = &typeVar
			}
		case "tags":
			if v != nil {
				var tags map[string]*string
				err = json.Unmarshal(*v, &tags)
				if err != nil {
					return err
				}
				d.Tags = tags
			}
		}
	}

	return nil
}

// DimensionProperties ...
type DimensionProperties struct {
	// Description - READ-ONLY; Dimension description.
	Description *string `json:"description,omitempty"`
	// FilterEnabled - READ-ONLY; Filter enabled.
	FilterEnabled *bool `json:"filterEnabled,omitempty"`
	// GroupingEnabled - READ-ONLY; Grouping enabled.
	GroupingEnabled *bool     `json:"groupingEnabled,omitempty"`
	Data            *[]string `json:"data,omitempty"`
	// Total - READ-ONLY; Total number of data for the dimension.
	Total *int32 `json:"total,omitempty"`
	// Category - READ-ONLY; Dimension category.
	Category *string `json:"category,omitempty"`
	// UsageStart - READ-ONLY; Usage start.
	UsageStart *date.Time `json:"usageStart,omitempty"`
	// UsageEnd - READ-ONLY; Usage end.
	UsageEnd *date.Time `json:"usageEnd,omitempty"`
	// NextLink - READ-ONLY; The link (url) to the next page of results.
	NextLink *string `json:"nextLink,omitempty"`
}

// MarshalJSON is the custom marshaler for DimensionProperties.
func (dp DimensionProperties) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]interface{})
	if dp.Data != nil {
		objectMap["data"] = dp.Data
	}
	return json.Marshal(objectMap)
}

// DimensionsListResult result of listing dimensions. It contains a list of available dimensions.
type DimensionsListResult struct {
	autorest.Response `json:"-"`
	// Value - READ-ONLY; The list of dimensions.
	Value *[]Dimension `json:"value,omitempty"`
}

// MarshalJSON is the custom marshaler for DimensionsListResult.
func (dlr DimensionsListResult) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]interface{})
	return json.Marshal(objectMap)
}

// DismissAlertPayload the request payload to update an alert
type DismissAlertPayload struct {
	*AlertProperties `json:"properties,omitempty"`
}

// MarshalJSON is the custom marshaler for DismissAlertPayload.
func (dap DismissAlertPayload) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]interface{})
	if dap.AlertProperties != nil {
		objectMap["properties"] = dap.AlertProperties
	}
	return json.Marshal(objectMap)
}

// UnmarshalJSON is the custom unmarshaler for DismissAlertPayload struct.
func (dap *DismissAlertPayload) UnmarshalJSON(body []byte) error {
	var m map[string]*json.RawMessage
	err := json.Unmarshal(body, &m)
	if err != nil {
		return err
	}
	for k, v := range m {
		switch k {
		case "properties":
			if v != nil {
				var alertProperties AlertProperties
				err = json.Unmarshal(*v, &alertProperties)
				if err != nil {
					return err
				}
				dap.AlertProperties = &alertProperties
			}
		}
	}

	return nil
}

// ErrorDetails the details of the error.
type ErrorDetails struct {
	// Code - READ-ONLY; Error code.
	Code *string `json:"code,omitempty"`
	// Message - READ-ONLY; Error message indicating why the operation failed.
	Message *string `json:"message,omitempty"`
}

// MarshalJSON is the custom marshaler for ErrorDetails.
func (ed ErrorDetails) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]interface{})
	return json.Marshal(objectMap)
}

// ErrorResponse error response indicates that the service is not able to process the incoming request. The
// reason is provided in the error message.
//
// Some Error responses:
//
// * 429 TooManyRequests - Request is throttled. Retry after waiting for the time specified in the
// "x-ms-ratelimit-microsoft.consumption-retry-after" header.
//
// * 503 ServiceUnavailable - Service is temporarily unavailable. Retry after waiting for the time
// specified in the "Retry-After" header.
type ErrorResponse struct {
	// Error - The details of the error.
	Error *ErrorDetails `json:"error,omitempty"`
}

// Export an export resource.
type Export struct {
	autorest.Response `json:"-"`
	*ExportProperties `json:"properties,omitempty"`
	// ID - READ-ONLY; Resource Id.
	ID *string `json:"id,omitempty"`
	// Name - READ-ONLY; Resource name.
	Name *string `json:"name,omitempty"`
	// Type - READ-ONLY; Resource type.
	Type *string `json:"type,omitempty"`
	// ETag - eTag of the resource. To handle concurrent update scenario, this field will be used to determine whether the user is updating the latest version or not.
	ETag *string `json:"eTag,omitempty"`
}

// MarshalJSON is the custom marshaler for Export.
func (e Export) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]interface{})
	if e.ExportProperties != nil {
		objectMap["properties"] = e.ExportProperties
	}
	if e.ETag != nil {
		objectMap["eTag"] = e.ETag
	}
	return json.Marshal(objectMap)
}

// UnmarshalJSON is the custom unmarshaler for Export struct.
func (e *Export) UnmarshalJSON(body []byte) error {
	var m map[string]*json.RawMessage
	err := json.Unmarshal(body, &m)
	if err != nil {
		return err
	}
	for k, v := range m {
		switch k {
		case "properties":
			if v != nil {
				var exportProperties ExportProperties
				err = json.Unmarshal(*v, &exportProperties)
				if err != nil {
					return err
				}
				e.ExportProperties = &exportProperties
			}
		case "id":
			if v != nil {
				var ID string
				err = json.Unmarshal(*v, &ID)
				if err != nil {
					return err
				}
				e.ID = &ID
			}
		case "name":
			if v != nil {
				var name string
				err = json.Unmarshal(*v, &name)
				if err != nil {
					return err
				}
				e.Name = &name
			}
		case "type":
			if v != nil {
				var typeVar string
				err = json.Unmarshal(*v, &typeVar)
				if err != nil {
					return err
				}
				e.Type = &typeVar
			}
		case "eTag":
			if v != nil {
				var eTag string
				err = json.Unmarshal(*v, &eTag)
				if err != nil {
					return err
				}
				e.ETag = &eTag
			}
		}
	}

	return nil
}

// ExportDataset the definition for data in the export.
type ExportDataset struct {
	// Granularity - The granularity of rows in the export. Currently only 'Daily' is supported. Possible values include: 'Daily'
	Granularity GranularityType `json:"granularity,omitempty"`
	// Configuration - The export dataset configuration.
	Configuration *ExportDatasetConfiguration `json:"configuration,omitempty"`
}

// ExportDatasetConfiguration the export dataset configuration. Allows columns to be selected for the
// export. If not provided then the export will include all available columns.
type ExportDatasetConfiguration struct {
	// Columns - Array of column names to be included in the export. If not provided then the export will include all available columns. The available columns can vary by customer channel (see examples).
	Columns *[]string `json:"columns,omitempty"`
}

// ExportDefinition the definition of an export.
type ExportDefinition struct {
	// Type - The type of the export. Note that 'Usage' is equivalent to 'ActualCost' and is applicable to exports that do not yet provide data for charges or amortization for service reservations. Possible values include: 'ExportTypeUsage', 'ExportTypeActualCost', 'ExportTypeAmortizedCost'
	Type ExportType `json:"type,omitempty"`
	// Timeframe - The time frame for pulling data for the export. If custom, then a specific time period must be provided. Possible values include: 'TimeframeTypeMonthToDate', 'TimeframeTypeBillingMonthToDate', 'TimeframeTypeTheLastMonth', 'TimeframeTypeTheLastBillingMonth', 'TimeframeTypeWeekToDate', 'TimeframeTypeCustom'
	Timeframe TimeframeType `json:"timeframe,omitempty"`
	// TimePeriod - Has time period for pulling data for the export.
	TimePeriod *ExportTimePeriod `json:"timePeriod,omitempty"`
	// DataSet - The definition for data in the export.
	DataSet *ExportDataset `json:"dataSet,omitempty"`
}

// ExportDeliveryDestination the destination information for the delivery of the export. To allow access to
// a storage account, you must register the account's subscription with the Microsoft.CostManagementExports
// resource provider. This is required once per subscription. When creating an export in the Azure portal,
// it is done automatically, however API users need to register the subscription. For more information see
// https://docs.microsoft.com/en-us/azure/azure-resource-manager/resource-manager-supported-services .
type ExportDeliveryDestination struct {
	// ResourceID - The resource id of the storage account where exports will be delivered.
	ResourceID *string `json:"resourceId,omitempty"`
	// Container - The name of the container where exports will be uploaded.
	Container *string `json:"container,omitempty"`
	// RootFolderPath - The name of the directory where exports will be uploaded.
	RootFolderPath *string `json:"rootFolderPath,omitempty"`
}

// ExportDeliveryInfo the delivery information associated with a export.
type ExportDeliveryInfo struct {
	// Destination - Has destination for the export being delivered.
	Destination *ExportDeliveryDestination `json:"destination,omitempty"`
}

// ExportExecution an export execution.
type ExportExecution struct {
	*ExportExecutionProperties `json:"properties,omitempty"`
	// ID - READ-ONLY; Resource Id.
	ID *string `json:"id,omitempty"`
	// Name - READ-ONLY; Resource name.
	Name *string `json:"name,omitempty"`
	// Type - READ-ONLY; Resource type.
	Type *string `json:"type,omitempty"`
	// ETag - eTag of the resource. To handle concurrent update scenario, this field will be used to determine whether the user is updating the latest version or not.
	ETag *string `json:"eTag,omitempty"`
}

// MarshalJSON is the custom marshaler for ExportExecution.
func (ee ExportExecution) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]interface{})
	if ee.ExportExecutionProperties != nil {
		objectMap["properties"] = ee.ExportExecutionProperties
	}
	if ee.ETag != nil {
		objectMap["eTag"] = ee.ETag
	}
	return json.Marshal(objectMap)
}

// UnmarshalJSON is the custom unmarshaler for ExportExecution struct.
func (ee *ExportExecution) UnmarshalJSON(body []byte) error {
	var m map[string]*json.RawMessage
	err := json.Unmarshal(body, &m)
	if err != nil {
		return err
	}
	for k, v := range m {
		switch k {
		case "properties":
			if v != nil {
				var exportExecutionProperties ExportExecutionProperties
				err = json.Unmarshal(*v, &exportExecutionProperties)
				if err != nil {
					return err
				}
				ee.ExportExecutionProperties = &exportExecutionProperties
			}
		case "id":
			if v != nil {
				var ID string
				err = json.Unmarshal(*v, &ID)
				if err != nil {
					return err
				}
				ee.ID = &ID
			}
		case "name":
			if v != nil {
				var name string
				err = json.Unmarshal(*v, &name)
				if err != nil {
					return err
				}
				ee.Name = &name
			}
		case "type":
			if v != nil {
				var typeVar string
				err = json.Unmarshal(*v, &typeVar)
				if err != nil {
					return err
				}
				ee.Type = &typeVar
			}
		case "eTag":
			if v != nil {
				var eTag string
				err = json.Unmarshal(*v, &eTag)
				if err != nil {
					return err
				}
				ee.ETag = &eTag
			}
		}
	}

	return nil
}

// ExportExecutionListResult result of listing the execution history of an export.
type ExportExecutionListResult struct {
	autorest.Response `json:"-"`
	// Value - READ-ONLY; A list of export executions.
	Value *[]ExportExecution `json:"value,omitempty"`
}

// MarshalJSON is the custom marshaler for ExportExecutionListResult.
func (eelr ExportExecutionListResult) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]interface{})
	return json.Marshal(objectMap)
}

// ExportExecutionProperties the properties of the export execution.
type ExportExecutionProperties struct {
	// ExecutionType - The type of the export execution. Possible values include: 'OnDemand', 'Scheduled'
	ExecutionType ExecutionType `json:"executionType,omitempty"`
	// Status - The last known status of the export execution. Possible values include: 'Queued', 'InProgress', 'Completed', 'Failed', 'Timeout', 'NewDataNotAvailable', 'DataNotAvailable'
	Status ExecutionStatus `json:"status,omitempty"`
	// SubmittedBy - The identifier for the entity that executed the export. For OnDemand executions it is the user email. For scheduled executions it is 'System'.
	SubmittedBy *string `json:"submittedBy,omitempty"`
	// SubmittedTime - The time when export was queued to be executed.
	SubmittedTime *date.Time `json:"submittedTime,omitempty"`
	// ProcessingStartTime - The time when export was picked up to be executed.
	ProcessingStartTime *date.Time `json:"processingStartTime,omitempty"`
	// ProcessingEndTime - The time when the export execution finished.
	ProcessingEndTime *date.Time `json:"processingEndTime,omitempty"`
	// FileName - The name of the exported file.
	FileName *string `json:"fileName,omitempty"`
	// RunSettings - The export settings that were in effect for this execution.
	RunSettings *CommonExportProperties `json:"runSettings,omitempty"`
	// Error - The details of any error.
	Error *ErrorDetails `json:"error,omitempty"`
}

// ExportListResult result of listing exports. It contains a list of available exports in the scope
// provided.
type ExportListResult struct {
	autorest.Response `json:"-"`
	// Value - READ-ONLY; The list of exports.
	Value *[]Export `json:"value,omitempty"`
}

// MarshalJSON is the custom marshaler for ExportListResult.
func (elr ExportListResult) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]interface{})
	return json.Marshal(objectMap)
}

// ExportProperties the properties of the export.
type ExportProperties struct {
	// Schedule - Has schedule information for the export.
	Schedule *ExportSchedule `json:"schedule,omitempty"`
	// Format - The format of the export being delivered. Currently only 'Csv' is supported. Possible values include: 'Csv'
	Format FormatType `json:"format,omitempty"`
	// DeliveryInfo - Has delivery information for the export.
	DeliveryInfo *ExportDeliveryInfo `json:"deliveryInfo,omitempty"`
	// Definition - Has the definition for the export.
	Definition *ExportDefinition `json:"definition,omitempty"`
	// RunHistory - If requested, has the most recent execution history for the export.
	RunHistory *ExportExecutionListResult `json:"runHistory,omitempty"`
	// NextRunTimeEstimate - READ-ONLY; If the export has an active schedule, provides an estimate of the next execution time.
	NextRunTimeEstimate *date.Time `json:"nextRunTimeEstimate,omitempty"`
}

// MarshalJSON is the custom marshaler for ExportProperties.
func (ep ExportProperties) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]interface{})
	if ep.Schedule != nil {
		objectMap["schedule"] = ep.Schedule
	}
	if ep.Format != "" {
		objectMap["format"] = ep.Format
	}
	if ep.DeliveryInfo != nil {
		objectMap["deliveryInfo"] = ep.DeliveryInfo
	}
	if ep.Definition != nil {
		objectMap["definition"] = ep.Definition
	}
	if ep.RunHistory != nil {
		objectMap["runHistory"] = ep.RunHistory
	}
	return json.Marshal(objectMap)
}

// ExportRecurrencePeriod the start and end date for recurrence schedule.
type ExportRecurrencePeriod struct {
	// From - The start date of recurrence.
	From *date.Time `json:"from,omitempty"`
	// To - The end date of recurrence.
	To *date.Time `json:"to,omitempty"`
}

// ExportSchedule the schedule associated with the export.
type ExportSchedule struct {
	// Status - The status of the export's schedule. If 'Inactive', the export's schedule is paused. Possible values include: 'Active', 'Inactive'
	Status StatusType `json:"status,omitempty"`
	// Recurrence - The schedule recurrence. Possible values include: 'RecurrenceTypeDaily', 'RecurrenceTypeWeekly', 'RecurrenceTypeMonthly', 'RecurrenceTypeAnnually'
	Recurrence RecurrenceType `json:"recurrence,omitempty"`
	// RecurrencePeriod - Has start and end date of the recurrence. The start date must be in future. If present, the end date must be greater than start date.
	RecurrencePeriod *ExportRecurrencePeriod `json:"recurrencePeriod,omitempty"`
}

// ExportTimePeriod the date range for data in the export. This should only be specified with timeFrame set
// to 'Custom'. The maximum date range is 3 months.
type ExportTimePeriod struct {
	// From - The start date for export data.
	From *date.Time `json:"from,omitempty"`
	// To - The end date for export data.
	To *date.Time `json:"to,omitempty"`
}

// ForecastDataset the definition of data present in the forecast.
type ForecastDataset struct {
	// Granularity - The granularity of rows in the forecast. Possible values include: 'Daily'
	Granularity GranularityType `json:"granularity,omitempty"`
	// Configuration - Has configuration information for the data in the export. The configuration will be ignored if aggregation and grouping are provided.
	Configuration *QueryDatasetConfiguration `json:"configuration,omitempty"`
	// Aggregation - Dictionary of aggregation expression to use in the forecast. The key of each item in the dictionary is the alias for the aggregated column. forecast can have up to 2 aggregation clauses.
	Aggregation map[string]*QueryAggregation `json:"aggregation"`
	// Filter - Has filter expression to use in the forecast.
	Filter *QueryFilter `json:"filter,omitempty"`
}

// MarshalJSON is the custom marshaler for ForecastDataset.
func (fd ForecastDataset) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]interface{})
	if fd.Granularity != "" {
		objectMap["granularity"] = fd.Granularity
	}
	if fd.Configuration != nil {
		objectMap["configuration"] = fd.Configuration
	}
	if fd.Aggregation != nil {
		objectMap["aggregation"] = fd.Aggregation
	}
	if fd.Filter != nil {
		objectMap["filter"] = fd.Filter
	}
	return json.Marshal(objectMap)
}

// ForecastDefinition the definition of a forecast.
type ForecastDefinition struct {
	// Type - The type of the forecast. Possible values include: 'ForecastTypeUsage', 'ForecastTypeActualCost', 'ForecastTypeAmortizedCost'
	Type ForecastType `json:"type,omitempty"`
	// Timeframe - The time frame for pulling data for the forecast. If custom, then a specific time period must be provided. Possible values include: 'MonthToDate', 'BillingMonthToDate', 'TheLastMonth', 'TheLastBillingMonth', 'WeekToDate', 'Custom'
	Timeframe ForecastTimeframeType `json:"timeframe,omitempty"`
	// TimePeriod - Has time period for pulling data for the forecast.
	TimePeriod *QueryTimePeriod `json:"timePeriod,omitempty"`
	// Dataset - Has definition for data in this forecast.
	Dataset *ForecastDataset `json:"dataset,omitempty"`
	// IncludeActualCost - a boolean determining if actualCost will be included
	IncludeActualCost *bool `json:"includeActualCost,omitempty"`
	// IncludeFreshPartialCost - a boolean determining if FreshPartialCost will be included
	IncludeFreshPartialCost *bool `json:"includeFreshPartialCost,omitempty"`
}

// KpiProperties each KPI must contain a 'type' and 'enabled' key.
type KpiProperties struct {
	// Type - KPI type (Forecast, Budget). Possible values include: 'KpiTypeTypeForecast', 'KpiTypeTypeBudget'
	Type KpiTypeType `json:"type,omitempty"`
	// ID - ID of resource related to metric (budget).
	ID *string `json:"id,omitempty"`
	// Enabled - show the KPI in the UI?
	Enabled *bool `json:"enabled,omitempty"`
}

// Operation a Cost management REST API operation.
type Operation struct {
	// Name - READ-ONLY; Operation name: {provider}/{resource}/{operation}.
	Name *string `json:"name,omitempty"`
	// Display - The object that represents the operation.
	Display *OperationDisplay `json:"display,omitempty"`
}

// MarshalJSON is the custom marshaler for Operation.
func (o Operation) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]interface{})
	if o.Display != nil {
		objectMap["display"] = o.Display
	}
	return json.Marshal(objectMap)
}

// OperationDisplay the object that represents the operation.
type OperationDisplay struct {
	// Provider - READ-ONLY; Service provider: Microsoft.CostManagement.
	Provider *string `json:"provider,omitempty"`
	// Resource - READ-ONLY; Resource on which the operation is performed: Dimensions, Query.
	Resource *string `json:"resource,omitempty"`
	// Operation - READ-ONLY; Operation type: Read, write, delete, etc.
	Operation *string `json:"operation,omitempty"`
}

// MarshalJSON is the custom marshaler for OperationDisplay.
func (o OperationDisplay) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]interface{})
	return json.Marshal(objectMap)
}

// OperationListResult result of listing cost management operations. It contains a list of operations and a
// URL link to get the next set of results.
type OperationListResult struct {
	autorest.Response `json:"-"`
	// Value - READ-ONLY; List of cost management operations supported by the Microsoft.CostManagement resource provider.
	Value *[]Operation `json:"value,omitempty"`
	// NextLink - READ-ONLY; URL to get the next set of operation list results if there are any.
	NextLink *string `json:"nextLink,omitempty"`
}

// MarshalJSON is the custom marshaler for OperationListResult.
func (olr OperationListResult) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]interface{})
	return json.Marshal(objectMap)
}

// OperationListResultIterator provides access to a complete listing of Operation values.
type OperationListResultIterator struct {
	i    int
	page OperationListResultPage
}

// NextWithContext advances to the next value.  If there was an error making
// the request the iterator does not advance and the error is returned.
func (iter *OperationListResultIterator) NextWithContext(ctx context.Context) (err error) {
	if tracing.IsEnabled() {
		ctx = tracing.StartSpan(ctx, fqdn+"/OperationListResultIterator.NextWithContext")
		defer func() {
			sc := -1
			if iter.Response().Response.Response != nil {
				sc = iter.Response().Response.Response.StatusCode
			}
			tracing.EndSpan(ctx, sc, err)
		}()
	}
	iter.i++
	if iter.i < len(iter.page.Values()) {
		return nil
	}
	err = iter.page.NextWithContext(ctx)
	if err != nil {
		iter.i--
		return err
	}
	iter.i = 0
	return nil
}

// Next advances to the next value.  If there was an error making
// the request the iterator does not advance and the error is returned.
// Deprecated: Use NextWithContext() instead.
func (iter *OperationListResultIterator) Next() error {
	return iter.NextWithContext(context.Background())
}

// NotDone returns true if the enumeration should be started or is not yet complete.
func (iter OperationListResultIterator) NotDone() bool {
	return iter.page.NotDone() && iter.i < len(iter.page.Values())
}

// Response returns the raw server response from the last page request.
func (iter OperationListResultIterator) Response() OperationListResult {
	return iter.page.Response()
}

// Value returns the current value or a zero-initialized value if the
// iterator has advanced beyond the end of the collection.
func (iter OperationListResultIterator) Value() Operation {
	if !iter.page.NotDone() {
		return Operation{}
	}
	return iter.page.Values()[iter.i]
}

// Creates a new instance of the OperationListResultIterator type.
func NewOperationListResultIterator(page OperationListResultPage) OperationListResultIterator {
	return OperationListResultIterator{page: page}
}

// IsEmpty returns true if the ListResult contains no values.
func (olr OperationListResult) IsEmpty() bool {
	return olr.Value == nil || len(*olr.Value) == 0
}

// hasNextLink returns true if the NextLink is not empty.
func (olr OperationListResult) hasNextLink() bool {
	return olr.NextLink != nil && len(*olr.NextLink) != 0
}

// operationListResultPreparer prepares a request to retrieve the next set of results.
// It returns nil if no more results exist.
func (olr OperationListResult) operationListResultPreparer(ctx context.Context) (*http.Request, error) {
	if !olr.hasNextLink() {
		return nil, nil
	}
	return autorest.Prepare((&http.Request{}).WithContext(ctx),
		autorest.AsJSON(),
		autorest.AsGet(),
		autorest.WithBaseURL(to.String(olr.NextLink)))
}

// OperationListResultPage contains a page of Operation values.
type OperationListResultPage struct {
	fn  func(context.Context, OperationListResult) (OperationListResult, error)
	olr OperationListResult
}

// NextWithContext advances to the next page of values.  If there was an error making
// the request the page does not advance and the error is returned.
func (page *OperationListResultPage) NextWithContext(ctx context.Context) (err error) {
	if tracing.IsEnabled() {
		ctx = tracing.StartSpan(ctx, fqdn+"/OperationListResultPage.NextWithContext")
		defer func() {
			sc := -1
			if page.Response().Response.Response != nil {
				sc = page.Response().Response.Response.StatusCode
			}
			tracing.EndSpan(ctx, sc, err)
		}()
	}
	for {
		next, err := page.fn(ctx, page.olr)
		if err != nil {
			return err
		}
		page.olr = next
		if !next.hasNextLink() || !next.IsEmpty() {
			break
		}
	}
	return nil
}

// Next advances to the next page of values.  If there was an error making
// the request the page does not advance and the error is returned.
// Deprecated: Use NextWithContext() instead.
func (page *OperationListResultPage) Next() error {
	return page.NextWithContext(context.Background())
}

// NotDone returns true if the page enumeration should be started or is not yet complete.
func (page OperationListResultPage) NotDone() bool {
	return !page.olr.IsEmpty()
}

// Response returns the raw server response from the last page request.
func (page OperationListResultPage) Response() OperationListResult {
	return page.olr
}

// Values returns the slice of values for the current page or nil if there are no values.
func (page OperationListResultPage) Values() []Operation {
	if page.olr.IsEmpty() {
		return nil
	}
	return *page.olr.Value
}

// Creates a new instance of the OperationListResultPage type.
func NewOperationListResultPage(cur OperationListResult, getNextPage func(context.Context, OperationListResult) (OperationListResult, error)) OperationListResultPage {
	return OperationListResultPage{
		fn:  getNextPage,
		olr: cur,
	}
}

// PivotProperties each pivot must contain a 'type' and 'name'.
type PivotProperties struct {
	// Type - Data type to show in view. Possible values include: 'PivotTypeTypeDimension', 'PivotTypeTypeTagKey'
	Type PivotTypeType `json:"type,omitempty"`
	// Name - Data field to show in view.
	Name *string `json:"name,omitempty"`
}

// ProxyResource the Resource model definition.
type ProxyResource struct {
	// ID - READ-ONLY; Resource Id.
	ID *string `json:"id,omitempty"`
	// Name - READ-ONLY; Resource name.
	Name *string `json:"name,omitempty"`
	// Type - READ-ONLY; Resource type.
	Type *string `json:"type,omitempty"`
	// ETag - eTag of the resource. To handle concurrent update scenario, this field will be used to determine whether the user is updating the latest version or not.
	ETag *string `json:"eTag,omitempty"`
}

// MarshalJSON is the custom marshaler for ProxyResource.
func (pr ProxyResource) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]interface{})
	if pr.ETag != nil {
		objectMap["eTag"] = pr.ETag
	}
	return json.Marshal(objectMap)
}

// QueryAggregation the aggregation expression to be used in the query.
type QueryAggregation struct {
	// Name - The name of the column to aggregate.
	Name *string `json:"name,omitempty"`
	// Function - The name of the aggregation function to use.
	Function *string `json:"function,omitempty"`
}

// QueryColumn ...
type QueryColumn struct {
	// Name - The name of column.
	Name *string `json:"name,omitempty"`
	// Type - The type of column.
	Type *string `json:"type,omitempty"`
}

// QueryComparisonExpression the comparison expression to be used in the query.
type QueryComparisonExpression struct {
	// Name - The name of the column to use in comparison.
	Name *string `json:"name,omitempty"`
	// Operator - The operator to use for comparison.
	Operator *string `json:"operator,omitempty"`
	// Values - Array of values to use for comparison
	Values *[]string `json:"values,omitempty"`
}

// QueryDataset the definition of data present in the query.
type QueryDataset struct {
	// Granularity - The granularity of rows in the query. Possible values include: 'Daily'
	Granularity GranularityType `json:"granularity,omitempty"`
	// Configuration - Has configuration information for the data in the export. The configuration will be ignored if aggregation and grouping are provided.
	Configuration *QueryDatasetConfiguration `json:"configuration,omitempty"`
	// Aggregation - Dictionary of aggregation expression to use in the query. The key of each item in the dictionary is the alias for the aggregated column. Query can have up to 2 aggregation clauses.
	Aggregation map[string]*QueryAggregation `json:"aggregation"`
	// Grouping - Array of group by expression to use in the query. Query can have up to 2 group by clauses.
	Grouping *[]QueryGrouping `json:"grouping,omitempty"`
	// Filter - Has filter expression to use in the query.
	Filter *QueryFilter `json:"filter,omitempty"`
}

// MarshalJSON is the custom marshaler for QueryDataset.
func (qd QueryDataset) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]interface{})
	if qd.Granularity != "" {
		objectMap["granularity"] = qd.Granularity
	}
	if qd.Configuration != nil {
		objectMap["configuration"] = qd.Configuration
	}
	if qd.Aggregation != nil {
		objectMap["aggregation"] = qd.Aggregation
	}
	if qd.Grouping != nil {
		objectMap["grouping"] = qd.Grouping
	}
	if qd.Filter != nil {
		objectMap["filter"] = qd.Filter
	}
	return json.Marshal(objectMap)
}

// QueryDatasetConfiguration the configuration of dataset in the query.
type QueryDatasetConfiguration struct {
	// Columns - Array of column names to be included in the query. Any valid query column name is allowed. If not provided, then query includes all columns.
	Columns *[]string `json:"columns,omitempty"`
}

// QueryDefinition the definition of a query.
type QueryDefinition struct {
	// Type - The type of the query. Possible values include: 'ExportTypeUsage', 'ExportTypeActualCost', 'ExportTypeAmortizedCost'
	Type ExportType `json:"type,omitempty"`
	// Timeframe - The time frame for pulling data for the query. If custom, then a specific time period must be provided. Possible values include: 'TimeframeTypeMonthToDate', 'TimeframeTypeBillingMonthToDate', 'TimeframeTypeTheLastMonth', 'TimeframeTypeTheLastBillingMonth', 'TimeframeTypeWeekToDate', 'TimeframeTypeCustom'
	Timeframe TimeframeType `json:"timeframe,omitempty"`
	// TimePeriod - Has time period for pulling data for the query.
	TimePeriod *QueryTimePeriod `json:"timePeriod,omitempty"`
	// Dataset - Has definition for data in this query.
	Dataset *QueryDataset `json:"dataset,omitempty"`
}

// QueryFilter the filter expression to be used in the export.
type QueryFilter struct {
	// And - The logical "AND" expression. Must have at least 2 items.
	And *[]QueryFilter `json:"and,omitempty"`
	// Or - The logical "OR" expression. Must have at least 2 items.
	Or *[]QueryFilter `json:"or,omitempty"`
	// Not - The logical "NOT" expression.
	Not *QueryFilter `json:"not,omitempty"`
	// Dimension - Has comparison expression for a dimension
	Dimension *QueryComparisonExpression `json:"dimension,omitempty"`
	// Tag - Has comparison expression for a tag
	Tag *QueryComparisonExpression `json:"tag,omitempty"`
}

// QueryGrouping the group by expression to be used in the query.
type QueryGrouping struct {
	// Type - Has type of the column to group. Possible values include: 'QueryColumnTypeTag', 'QueryColumnTypeDimension'
	Type QueryColumnType `json:"type,omitempty"`
	// Name - The name of the column to group.
	Name *string `json:"name,omitempty"`
}

// QueryProperties ...
type QueryProperties struct {
	// NextLink - The link (url) to the next page of results.
	NextLink *string `json:"nextLink,omitempty"`
	// Columns - Array of columns
	Columns *[]QueryColumn `json:"columns,omitempty"`
	// Rows - Array of rows
	Rows *[][]interface{} `json:"rows,omitempty"`
}

// QueryResult result of query. It contains all columns listed under groupings and aggregation.
type QueryResult struct {
	autorest.Response `json:"-"`
	*QueryProperties  `json:"properties,omitempty"`
	// ID - READ-ONLY; Resource Id.
	ID *string `json:"id,omitempty"`
	// Name - READ-ONLY; Resource name.
	Name *string `json:"name,omitempty"`
	// Type - READ-ONLY; Resource type.
	Type *string `json:"type,omitempty"`
	// Tags - READ-ONLY; Resource tags.
	Tags map[string]*string `json:"tags"`
}

// MarshalJSON is the custom marshaler for QueryResult.
func (qr QueryResult) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]interface{})
	if qr.QueryProperties != nil {
		objectMap["properties"] = qr.QueryProperties
	}
	return json.Marshal(objectMap)
}

// UnmarshalJSON is the custom unmarshaler for QueryResult struct.
func (qr *QueryResult) UnmarshalJSON(body []byte) error {
	var m map[string]*json.RawMessage
	err := json.Unmarshal(body, &m)
	if err != nil {
		return err
	}
	for k, v := range m {
		switch k {
		case "properties":
			if v != nil {
				var queryProperties QueryProperties
				err = json.Unmarshal(*v, &queryProperties)
				if err != nil {
					return err
				}
				qr.QueryProperties = &queryProperties
			}
		case "id":
			if v != nil {
				var ID string
				err = json.Unmarshal(*v, &ID)
				if err != nil {
					return err
				}
				qr.ID = &ID
			}
		case "name":
			if v != nil {
				var name string
				err = json.Unmarshal(*v, &name)
				if err != nil {
					return err
				}
				qr.Name = &name
			}
		case "type":
			if v != nil {
				var typeVar string
				err = json.Unmarshal(*v, &typeVar)
				if err != nil {
					return err
				}
				qr.Type = &typeVar
			}
		case "tags":
			if v != nil {
				var tags map[string]*string
				err = json.Unmarshal(*v, &tags)
				if err != nil {
					return err
				}
				qr.Tags = tags
			}
		}
	}

	return nil
}

// QueryTimePeriod the start and end date for pulling data for the query.
type QueryTimePeriod struct {
	// From - The start date to pull data from.
	From *date.Time `json:"from,omitempty"`
	// To - The end date to pull data to.
	To *date.Time `json:"to,omitempty"`
}

// ReportConfigAggregation the aggregation expression to be used in the report.
type ReportConfigAggregation struct {
	// Name - The name of the column to aggregate.
	Name *string `json:"name,omitempty"`
	// Function - The name of the aggregation function to use.
	Function *string `json:"function,omitempty"`
}

// ReportConfigComparisonExpression the comparison expression to be used in the report.
type ReportConfigComparisonExpression struct {
	// Name - The name of the column to use in comparison.
	Name *string `json:"name,omitempty"`
	// Operator - The operator to use for comparison. Possible values include: 'In', 'Contains'
	Operator OperatorType `json:"operator,omitempty"`
	// Values - Array of values to use for comparison
	Values *[]string `json:"values,omitempty"`
}

// ReportConfigDataset the definition of data present in the report.
type ReportConfigDataset struct {
	// Granularity - The granularity of rows in the report. Possible values include: 'ReportGranularityTypeDaily', 'ReportGranularityTypeMonthly'
	Granularity ReportGranularityType `json:"granularity,omitempty"`
	// Configuration - Has configuration information for the data in the report. The configuration will be ignored if aggregation and grouping are provided.
	Configuration *ReportConfigDatasetConfiguration `json:"configuration,omitempty"`
	// Aggregation - Dictionary of aggregation expression to use in the report. The key of each item in the dictionary is the alias for the aggregated column. Report can have up to 2 aggregation clauses.
	Aggregation map[string]*ReportConfigAggregation `json:"aggregation"`
	// Grouping - Array of group by expression to use in the report. Report can have up to 2 group by clauses.
	Grouping *[]ReportConfigGrouping `json:"grouping,omitempty"`
	// Sorting - Array of order by expression to use in the report.
	Sorting *[]ReportConfigSorting `json:"sorting,omitempty"`
	// Filter - Has filter expression to use in the report.
	Filter *ReportConfigFilter `json:"filter,omitempty"`
}

// MarshalJSON is the custom marshaler for ReportConfigDataset.
func (rcd ReportConfigDataset) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]interface{})
	if rcd.Granularity != "" {
		objectMap["granularity"] = rcd.Granularity
	}
	if rcd.Configuration != nil {
		objectMap["configuration"] = rcd.Configuration
	}
	if rcd.Aggregation != nil {
		objectMap["aggregation"] = rcd.Aggregation
	}
	if rcd.Grouping != nil {
		objectMap["grouping"] = rcd.Grouping
	}
	if rcd.Sorting != nil {
		objectMap["sorting"] = rcd.Sorting
	}
	if rcd.Filter != nil {
		objectMap["filter"] = rcd.Filter
	}
	return json.Marshal(objectMap)
}

// ReportConfigDatasetConfiguration the configuration of dataset in the report.
type ReportConfigDatasetConfiguration struct {
	// Columns - Array of column names to be included in the report. Any valid report column name is allowed. If not provided, then report includes all columns.
	Columns *[]string `json:"columns,omitempty"`
}

// ReportConfigDefinition the definition of a report config.
type ReportConfigDefinition struct {
	// Type - The type of the report. Usage represents actual usage, forecast represents forecasted data and UsageAndForecast represents both usage and forecasted data. Actual usage and forecasted data can be differentiated based on dates.
	Type *string `json:"type,omitempty"`
	// Timeframe - The time frame for pulling data for the report. If custom, then a specific time period must be provided. Possible values include: 'ReportTimeframeTypeWeekToDate', 'ReportTimeframeTypeMonthToDate', 'ReportTimeframeTypeYearToDate', 'ReportTimeframeTypeCustom'
	Timeframe ReportTimeframeType `json:"timeframe,omitempty"`
	// TimePeriod - Has time period for pulling data for the report.
	TimePeriod *ReportConfigTimePeriod `json:"timePeriod,omitempty"`
	// Dataset - Has definition for data in this report config.
	Dataset *ReportConfigDataset `json:"dataset,omitempty"`
}

// ReportConfigFilter the filter expression to be used in the report.
type ReportConfigFilter struct {
	// And - The logical "AND" expression. Must have at least 2 items.
	And *[]ReportConfigFilter `json:"and,omitempty"`
	// Or - The logical "OR" expression. Must have at least 2 items.
	Or *[]ReportConfigFilter `json:"or,omitempty"`
	// Not - The logical "NOT" expression.
	Not *ReportConfigFilter `json:"not,omitempty"`
	// Dimension - Has comparison expression for a dimension
	Dimension *ReportConfigComparisonExpression `json:"dimension,omitempty"`
	// Tag - Has comparison expression for a tag
	Tag *ReportConfigComparisonExpression `json:"tag,omitempty"`
}

// ReportConfigGrouping the group by expression to be used in the report.
type ReportConfigGrouping struct {
	// Type - Has type of the column to group. Possible values include: 'ReportConfigColumnTypeTag', 'ReportConfigColumnTypeDimension'
	Type ReportConfigColumnType `json:"type,omitempty"`
	// Name - The name of the column to group. This version supports subscription lowest possible grain.
	Name *string `json:"name,omitempty"`
}

// ReportConfigSorting the order by expression to be used in the report.
type ReportConfigSorting struct {
	// Direction - Direction of sort. Possible values include: 'Ascending', 'Descending'
	Direction Direction `json:"direction,omitempty"`
	// Name - The name of the column to sort.
	Name *string `json:"name,omitempty"`
}

// ReportConfigTimePeriod the start and end date for pulling data for the report.
type ReportConfigTimePeriod struct {
	// From - The start date to pull data from.
	From *date.Time `json:"from,omitempty"`
	// To - The end date to pull data to.
	To *date.Time `json:"to,omitempty"`
}

// Resource the Resource model definition.
type Resource struct {
	// ID - READ-ONLY; Resource Id.
	ID *string `json:"id,omitempty"`
	// Name - READ-ONLY; Resource name.
	Name *string `json:"name,omitempty"`
	// Type - READ-ONLY; Resource type.
	Type *string `json:"type,omitempty"`
	// Tags - READ-ONLY; Resource tags.
	Tags map[string]*string `json:"tags"`
}

// MarshalJSON is the custom marshaler for Resource.
func (r Resource) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]interface{})
	return json.Marshal(objectMap)
}

// View states and configurations of Cost Analysis.
type View struct {
	autorest.Response `json:"-"`
	*ViewProperties   `json:"properties,omitempty"`
	// ID - READ-ONLY; Resource Id.
	ID *string `json:"id,omitempty"`
	// Name - READ-ONLY; Resource name.
	Name *string `json:"name,omitempty"`
	// Type - READ-ONLY; Resource type.
	Type *string `json:"type,omitempty"`
	// ETag - eTag of the resource. To handle concurrent update scenario, this field will be used to determine whether the user is updating the latest version or not.
	ETag *string `json:"eTag,omitempty"`
}

// MarshalJSON is the custom marshaler for View.
func (vVar View) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]interface{})
	if vVar.ViewProperties != nil {
		objectMap["properties"] = vVar.ViewProperties
	}
	if vVar.ETag != nil {
		objectMap["eTag"] = vVar.ETag
	}
	return json.Marshal(objectMap)
}

// UnmarshalJSON is the custom unmarshaler for View struct.
func (vVar *View) UnmarshalJSON(body []byte) error {
	var m map[string]*json.RawMessage
	err := json.Unmarshal(body, &m)
	if err != nil {
		return err
	}
	for k, v := range m {
		switch k {
		case "properties":
			if v != nil {
				var viewProperties ViewProperties
				err = json.Unmarshal(*v, &viewProperties)
				if err != nil {
					return err
				}
				vVar.ViewProperties = &viewProperties
			}
		case "id":
			if v != nil {
				var ID string
				err = json.Unmarshal(*v, &ID)
				if err != nil {
					return err
				}
				vVar.ID = &ID
			}
		case "name":
			if v != nil {
				var name string
				err = json.Unmarshal(*v, &name)
				if err != nil {
					return err
				}
				vVar.Name = &name
			}
		case "type":
			if v != nil {
				var typeVar string
				err = json.Unmarshal(*v, &typeVar)
				if err != nil {
					return err
				}
				vVar.Type = &typeVar
			}
		case "eTag":
			if v != nil {
				var eTag string
				err = json.Unmarshal(*v, &eTag)
				if err != nil {
					return err
				}
				vVar.ETag = &eTag
			}
		}
	}

	return nil
}

// ViewListResult result of listing views. It contains a list of available views.
type ViewListResult struct {
	autorest.Response `json:"-"`
	// Value - READ-ONLY; The list of views.
	Value *[]View `json:"value,omitempty"`
	// NextLink - READ-ONLY; The link (url) to the next page of results.
	NextLink *string `json:"nextLink,omitempty"`
}

// MarshalJSON is the custom marshaler for ViewListResult.
func (vlr ViewListResult) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]interface{})
	return json.Marshal(objectMap)
}

// ViewListResultIterator provides access to a complete listing of View values.
type ViewListResultIterator struct {
	i    int
	page ViewListResultPage
}

// NextWithContext advances to the next value.  If there was an error making
// the request the iterator does not advance and the error is returned.
func (iter *ViewListResultIterator) NextWithContext(ctx context.Context) (err error) {
	if tracing.IsEnabled() {
		ctx = tracing.StartSpan(ctx, fqdn+"/ViewListResultIterator.NextWithContext")
		defer func() {
			sc := -1
			if iter.Response().Response.Response != nil {
				sc = iter.Response().Response.Response.StatusCode
			}
			tracing.EndSpan(ctx, sc, err)
		}()
	}
	iter.i++
	if iter.i < len(iter.page.Values()) {
		return nil
	}
	err = iter.page.NextWithContext(ctx)
	if err != nil {
		iter.i--
		return err
	}
	iter.i = 0
	return nil
}

// Next advances to the next value.  If there was an error making
// the request the iterator does not advance and the error is returned.
// Deprecated: Use NextWithContext() instead.
func (iter *ViewListResultIterator) Next() error {
	return iter.NextWithContext(context.Background())
}

// NotDone returns true if the enumeration should be started or is not yet complete.
func (iter ViewListResultIterator) NotDone() bool {
	return iter.page.NotDone() && iter.i < len(iter.page.Values())
}

// Response returns the raw server response from the last page request.
func (iter ViewListResultIterator) Response() ViewListResult {
	return iter.page.Response()
}

// Value returns the current value or a zero-initialized value if the
// iterator has advanced beyond the end of the collection.
func (iter ViewListResultIterator) Value() View {
	if !iter.page.NotDone() {
		return View{}
	}
	return iter.page.Values()[iter.i]
}

// Creates a new instance of the ViewListResultIterator type.
func NewViewListResultIterator(page ViewListResultPage) ViewListResultIterator {
	return ViewListResultIterator{page: page}
}

// IsEmpty returns true if the ListResult contains no values.
func (vlr ViewListResult) IsEmpty() bool {
	return vlr.Value == nil || len(*vlr.Value) == 0
}

// hasNextLink returns true if the NextLink is not empty.
func (vlr ViewListResult) hasNextLink() bool {
	return vlr.NextLink != nil && len(*vlr.NextLink) != 0
}

// viewListResultPreparer prepares a request to retrieve the next set of results.
// It returns nil if no more results exist.
func (vlr ViewListResult) viewListResultPreparer(ctx context.Context) (*http.Request, error) {
	if !vlr.hasNextLink() {
		return nil, nil
	}
	return autorest.Prepare((&http.Request{}).WithContext(ctx),
		autorest.AsJSON(),
		autorest.AsGet(),
		autorest.WithBaseURL(to.String(vlr.NextLink)))
}

// ViewListResultPage contains a page of View values.
type ViewListResultPage struct {
	fn  func(context.Context, ViewListResult) (ViewListResult, error)
	vlr ViewListResult
}

// NextWithContext advances to the next page of values.  If there was an error making
// the request the page does not advance and the error is returned.
func (page *ViewListResultPage) NextWithContext(ctx context.Context) (err error) {
	if tracing.IsEnabled() {
		ctx = tracing.StartSpan(ctx, fqdn+"/ViewListResultPage.NextWithContext")
		defer func() {
			sc := -1
			if page.Response().Response.Response != nil {
				sc = page.Response().Response.Response.StatusCode
			}
			tracing.EndSpan(ctx, sc, err)
		}()
	}
	for {
		next, err := page.fn(ctx, page.vlr)
		if err != nil {
			return err
		}
		page.vlr = next
		if !next.hasNextLink() || !next.IsEmpty() {
			break
		}
	}
	return nil
}

// Next advances to the next page of values.  If there was an error making
// the request the page does not advance and the error is returned.
// Deprecated: Use NextWithContext() instead.
func (page *ViewListResultPage) Next() error {
	return page.NextWithContext(context.Background())
}

// NotDone returns true if the page enumeration should be started or is not yet complete.
func (page ViewListResultPage) NotDone() bool {
	return !page.vlr.IsEmpty()
}

// Response returns the raw server response from the last page request.
func (page ViewListResultPage) Response() ViewListResult {
	return page.vlr
}

// Values returns the slice of values for the current page or nil if there are no values.
func (page ViewListResultPage) Values() []View {
	if page.vlr.IsEmpty() {
		return nil
	}
	return *page.vlr.Value
}

// Creates a new instance of the ViewListResultPage type.
func NewViewListResultPage(cur ViewListResult, getNextPage func(context.Context, ViewListResult) (ViewListResult, error)) ViewListResultPage {
	return ViewListResultPage{
		fn:  getNextPage,
		vlr: cur,
	}
}

// ViewProperties the properties of the view.
type ViewProperties struct {
	// DisplayName - User input name of the view. Required.
	DisplayName *string `json:"displayName,omitempty"`
	// Scope - Cost Management scope to save the view on. This includes 'subscriptions/{subscriptionId}' for subscription scope, 'subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}' for resourceGroup scope, 'providers/Microsoft.Billing/billingAccounts/{billingAccountId}' for Billing Account scope, 'providers/Microsoft.Billing/billingAccounts/{billingAccountId}/departments/{departmentId}' for Department scope, 'providers/Microsoft.Billing/billingAccounts/{billingAccountId}/enrollmentAccounts/{enrollmentAccountId}' for EnrollmentAccount scope, 'providers/Microsoft.Billing/billingAccounts/{billingAccountId}/billingProfiles/{billingProfileId}' for BillingProfile scope, 'providers/Microsoft.Billing/billingAccounts/{billingAccountId}/invoiceSections/{invoiceSectionId}' for InvoiceSection scope, 'providers/Microsoft.Management/managementGroups/{managementGroupId}' for Management Group scope, '/providers/Microsoft.CostManagement/externalBillingAccounts/{externalBillingAccountName}' for ExternalBillingAccount scope, and '/providers/Microsoft.CostManagement/externalSubscriptions/{externalSubscriptionName}' for ExternalSubscription scope.
	Scope *string `json:"scope,omitempty"`
	// CreatedOn - READ-ONLY; Date the user created this view.
	CreatedOn *date.Time `json:"createdOn,omitempty"`
	// ModifiedOn - READ-ONLY; Date when the user last modified this view.
	ModifiedOn *date.Time `json:"modifiedOn,omitempty"`
	// ReportConfigDefinition - Query body configuration. Required.
	*ReportConfigDefinition `json:"query,omitempty"`
	// Chart - Chart type of the main view in Cost Analysis. Required. Possible values include: 'Area', 'Line', 'StackedColumn', 'GroupedColumn', 'Table'
	Chart ChartType `json:"chart,omitempty"`
	// Accumulated - Show costs accumulated over time. Possible values include: 'True', 'False'
	Accumulated AccumulatedType `json:"accumulated,omitempty"`
	// Metric - Metric to use when displaying costs. Possible values include: 'ActualCost', 'AmortizedCost', 'AHUB'
	Metric MetricType `json:"metric,omitempty"`
	// Kpis - List of KPIs to show in Cost Analysis UI.
	Kpis *[]KpiProperties `json:"kpis,omitempty"`
	// Pivots - Configuration of 3 sub-views in the Cost Analysis UI.
	Pivots *[]PivotProperties `json:"pivots,omitempty"`
}

// MarshalJSON is the custom marshaler for ViewProperties.
func (vp ViewProperties) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]interface{})
	if vp.DisplayName != nil {
		objectMap["displayName"] = vp.DisplayName
	}
	if vp.Scope != nil {
		objectMap["scope"] = vp.Scope
	}
	if vp.ReportConfigDefinition != nil {
		objectMap["query"] = vp.ReportConfigDefinition
	}
	if vp.Chart != "" {
		objectMap["chart"] = vp.Chart
	}
	if vp.Accumulated != "" {
		objectMap["accumulated"] = vp.Accumulated
	}
	if vp.Metric != "" {
		objectMap["metric"] = vp.Metric
	}
	if vp.Kpis != nil {
		objectMap["kpis"] = vp.Kpis
	}
	if vp.Pivots != nil {
		objectMap["pivots"] = vp.Pivots
	}
	return json.Marshal(objectMap)
}

// UnmarshalJSON is the custom unmarshaler for ViewProperties struct.
func (vp *ViewProperties) UnmarshalJSON(body []byte) error {
	var m map[string]*json.RawMessage
	err := json.Unmarshal(body, &m)
	if err != nil {
		return err
	}
	for k, v := range m {
		switch k {
		case "displayName":
			if v != nil {
				var displayName string
				err = json.Unmarshal(*v, &displayName)
				if err != nil {
					return err
				}
				vp.DisplayName = &displayName
			}
		case "scope":
			if v != nil {
				var scope string
				err = json.Unmarshal(*v, &scope)
				if err != nil {
					return err
				}
				vp.Scope = &scope
			}
		case "createdOn":
			if v != nil {
				var createdOn date.Time
				err = json.Unmarshal(*v, &createdOn)
				if err != nil {
					return err
				}
				vp.CreatedOn = &createdOn
			}
		case "modifiedOn":
			if v != nil {
				var modifiedOn date.Time
				err = json.Unmarshal(*v, &modifiedOn)
				if err != nil {
					return err
				}
				vp.ModifiedOn = &modifiedOn
			}
		case "query":
			if v != nil {
				var reportConfigDefinition ReportConfigDefinition
				err = json.Unmarshal(*v, &reportConfigDefinition)
				if err != nil {
					return err
				}
				vp.ReportConfigDefinition = &reportConfigDefinition
			}
		case "chart":
			if v != nil {
				var chart ChartType
				err = json.Unmarshal(*v, &chart)
				if err != nil {
					return err
				}
				vp.Chart = chart
			}
		case "accumulated":
			if v != nil {
				var accumulated AccumulatedType
				err = json.Unmarshal(*v, &accumulated)
				if err != nil {
					return err
				}
				vp.Accumulated = accumulated
			}
		case "metric":
			if v != nil {
				var metric MetricType
				err = json.Unmarshal(*v, &metric)
				if err != nil {
					return err
				}
				vp.Metric = metric
			}
		case "kpis":
			if v != nil {
				var kpis []KpiProperties
				err = json.Unmarshal(*v, &kpis)
				if err != nil {
					return err
				}
				vp.Kpis = &kpis
			}
		case "pivots":
			if v != nil {
				var pivots []PivotProperties
				err = json.Unmarshal(*v, &pivots)
				if err != nil {
					return err
				}
				vp.Pivots = &pivots
			}
		}
	}

	return nil
}
