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

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

// CheckEligibilityDefinition the check eligibility Connector credentials definition
type CheckEligibilityDefinition struct {
	// Kind - Connector kind (eg aws)
	Kind *string `json:"kind,omitempty"`
	// CredentialsKey - Credentials authentication key (eg AWS ARN)
	CredentialsKey *string `json:"credentialsKey,omitempty"`
	// CredentialsSecret - Credentials secret (eg AWS ExternalId)
	CredentialsSecret *string `json:"credentialsSecret,omitempty"`
	// ReportID - Identifying source report. (For AWS this is a CUR report name, defined with Daily and with Resources)
	ReportID *string `json:"reportId,omitempty"`
}

// ConnectorCollectionErrorInfo details of any error encountered on last collection attempt
type ConnectorCollectionErrorInfo struct {
	// ErrorMessage - READ-ONLY; Detailed error message
	ErrorMessage *string `json:"errorMessage,omitempty"`
	// ErrorInnerMessage - READ-ONLY; External Provider error message
	ErrorInnerMessage *string `json:"errorInnerMessage,omitempty"`
	// ErrorCode - READ-ONLY; Short error code
	ErrorCode *string `json:"errorCode,omitempty"`
	// ErrorStartTime - READ-ONLY; Time the error started occurring (Last time error occurred in lastChecked)
	ErrorStartTime *date.Time `json:"errorStartTime,omitempty"`
}

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

// ConnectorCollectionInfo collection and ingestion information
type ConnectorCollectionInfo struct {
	// LastChecked - READ-ONLY; Last time the data acquisition process initiated connecting to the external provider
	LastChecked *date.Time `json:"lastChecked,omitempty"`
	// SourceLastUpdated - READ-ONLY; Source timestamp of external data currently available in Azure (eg AWS last processed CUR file timestamp)
	SourceLastUpdated *date.Time `json:"sourceLastUpdated,omitempty"`
	// LastUpdated - READ-ONLY; Last time the external data was updated into Azure
	LastUpdated *date.Time `json:"lastUpdated,omitempty"`
	// Error - Error information of last collection
	Error *ConnectorCollectionErrorInfo `json:"error,omitempty"`
}

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

// ConnectorDefinition the Connector model definition
type ConnectorDefinition struct {
	autorest.Response `json:"-"`
	// Kind - Connector kind (eg aws)
	Kind *string `json:"kind,omitempty"`
	// ID - READ-ONLY; Connector id
	ID *string `json:"id,omitempty"`
	// Name - READ-ONLY; Connector name
	Name *string `json:"name,omitempty"`
	// Type - READ-ONLY; Connector type
	Type *string `json:"type,omitempty"`
	// ConnectorProperties - Connector properties
	*ConnectorProperties `json:"properties,omitempty"`
}

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

// UnmarshalJSON is the custom unmarshaler for ConnectorDefinition struct.
func (cd *ConnectorDefinition) 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 "kind":
			if v != nil {
				var kind string
				err = json.Unmarshal(*v, &kind)
				if err != nil {
					return err
				}
				cd.Kind = &kind
			}
		case "id":
			if v != nil {
				var ID string
				err = json.Unmarshal(*v, &ID)
				if err != nil {
					return err
				}
				cd.ID = &ID
			}
		case "name":
			if v != nil {
				var name string
				err = json.Unmarshal(*v, &name)
				if err != nil {
					return err
				}
				cd.Name = &name
			}
		case "type":
			if v != nil {
				var typeVar string
				err = json.Unmarshal(*v, &typeVar)
				if err != nil {
					return err
				}
				cd.Type = &typeVar
			}
		case "properties":
			if v != nil {
				var connectorProperties ConnectorProperties
				err = json.Unmarshal(*v, &connectorProperties)
				if err != nil {
					return err
				}
				cd.ConnectorProperties = &connectorProperties
			}
		}
	}

	return nil
}

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

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

// ConnectorProperties the properties of a Connector
type ConnectorProperties struct {
	// DisplayName - Connector DisplayName
	DisplayName *string `json:"displayName,omitempty"`
	// ProviderBillingAccountID - READ-ONLY; Connector providerBillingAccountId, determined from credentials (eg AWS Consolidated account number)
	ProviderBillingAccountID *string `json:"providerBillingAccountId,omitempty"`
	// ProviderBillingAccountDisplayName - READ-ONLY; The display name of the providerBillingAccountId as defined on the external provider
	ProviderBillingAccountDisplayName *string `json:"providerBillingAccountDisplayName,omitempty"`
	// CredentialsKey - Credentials authentication key (eg AWS ARN)
	CredentialsKey *string `json:"credentialsKey,omitempty"`
	// CredentialsSecret - Credentials secret (eg AWS ExternalId)
	CredentialsSecret *string `json:"credentialsSecret,omitempty"`
	// ReportID - Identifying source report. (For AWS this is a CUR report name, defined with Daily and with Resources)
	ReportID *string `json:"reportId,omitempty"`
	// CreatedOn - READ-ONLY; Connector definition creation datetime
	CreatedOn *date.Time `json:"createdOn,omitempty"`
	// ModifiedOn - READ-ONLY; Connector last modified datetime
	ModifiedOn *date.Time `json:"modifiedOn,omitempty"`
	// Status - READ-ONLY; Connector status. Possible values include: 'ConnectorStatusActive', 'ConnectorStatusError', 'ConnectorStatusExpired', 'ConnectorStatusWarning'
	Status ConnectorStatus `json:"status,omitempty"`
	// ExternalBillingAccountID - READ-ONLY; Associated ExternalBillingAccountId
	ExternalBillingAccountID *string `json:"externalBillingAccountId,omitempty"`
	// DefaultManagementGroupID - Default ManagementGroupId
	DefaultManagementGroupID *string `json:"defaultManagementGroupId,omitempty"`
	// SubscriptionID - Billing SubscriptionId
	SubscriptionID *string `json:"subscriptionId,omitempty"`
	// BillingModel - Connector billing model. Possible values include: 'Trial', 'AutoUpgrade', 'Premium', 'Expired'
	BillingModel ConnectorBillingModel `json:"billingModel,omitempty"`
	// DaysTrialRemaining - READ-ONLY; Number of days remaining of trial
	DaysTrialRemaining *int32 `json:"daysTrialRemaining,omitempty"`
	// CollectionInfo - READ-ONLY; Collection information
	CollectionInfo *ConnectorCollectionInfo `json:"collectionInfo,omitempty"`
}

// MarshalJSON is the custom marshaler for ConnectorProperties.
func (cp ConnectorProperties) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]interface{})
	if cp.DisplayName != nil {
		objectMap["displayName"] = cp.DisplayName
	}
	if cp.CredentialsKey != nil {
		objectMap["credentialsKey"] = cp.CredentialsKey
	}
	if cp.CredentialsSecret != nil {
		objectMap["credentialsSecret"] = cp.CredentialsSecret
	}
	if cp.ReportID != nil {
		objectMap["reportId"] = cp.ReportID
	}
	if cp.DefaultManagementGroupID != nil {
		objectMap["defaultManagementGroupId"] = cp.DefaultManagementGroupID
	}
	if cp.SubscriptionID != nil {
		objectMap["subscriptionId"] = cp.SubscriptionID
	}
	if cp.BillingModel != "" {
		objectMap["billingModel"] = cp.BillingModel
	}
	return json.Marshal(objectMap)
}

// CostAllocationDetails represents CostAllocation showback rule model
type CostAllocationDetails struct {
	// Policy - Cost allocation policy. Possible values include: 'Proportional', 'Evenly', 'Fixed'
	Policy CostAllocationPolicy `json:"policy,omitempty"`
}

// CostAllocationDetailsKind represents CostAllocation showback rule model
type CostAllocationDetailsKind struct {
	// CostAllocationDetails - The CostAllocation properties to validate.
	*CostAllocationDetails `json:"details,omitempty"`
	// Description - Description of a showback rule.
	Description *string `json:"description,omitempty"`
	// Status - The current status of the showback rule. Possible values include: 'NotActive', 'Active'
	Status ShowbackRuleStatus `json:"status,omitempty"`
	// Version - READ-ONLY; The current version of showback rule.
	Version *int32 `json:"version,omitempty"`
	// Scopes - List of authorized assigned scopes.
	Scopes *[]Scope `json:"scopes,omitempty"`
	// CreationTime - READ-ONLY; The time when the showback rule was created.
	CreationTime *date.Time `json:"creationTime,omitempty"`
	// DeprecationTime - READ-ONLY; The current time when showback rule was deprecate.
	DeprecationTime *date.Time `json:"deprecationTime,omitempty"`
	// ModificationTime - READ-ONLY; The current status when showback rule was modified.
	ModificationTime *date.Time `json:"modificationTime,omitempty"`
	// RuleType - Possible values include: 'RuleTypeShowbackRuleProperties', 'RuleTypeCustomPrice', 'RuleTypeCostAllocation'
	RuleType RuleType `json:"ruleType,omitempty"`
}

// MarshalJSON is the custom marshaler for CostAllocationDetailsKind.
func (cadk CostAllocationDetailsKind) MarshalJSON() ([]byte, error) {
	cadk.RuleType = RuleTypeCostAllocation
	objectMap := make(map[string]interface{})
	if cadk.CostAllocationDetails != nil {
		objectMap["details"] = cadk.CostAllocationDetails
	}
	if cadk.Description != nil {
		objectMap["description"] = cadk.Description
	}
	if cadk.Status != "" {
		objectMap["status"] = cadk.Status
	}
	if cadk.Scopes != nil {
		objectMap["scopes"] = cadk.Scopes
	}
	if cadk.RuleType != "" {
		objectMap["ruleType"] = cadk.RuleType
	}
	return json.Marshal(objectMap)
}

// AsCustomPriceDetailsKind is the BasicShowbackRuleProperties implementation for CostAllocationDetailsKind.
func (cadk CostAllocationDetailsKind) AsCustomPriceDetailsKind() (*CustomPriceDetailsKind, bool) {
	return nil, false
}

// AsCostAllocationDetailsKind is the BasicShowbackRuleProperties implementation for CostAllocationDetailsKind.
func (cadk CostAllocationDetailsKind) AsCostAllocationDetailsKind() (*CostAllocationDetailsKind, bool) {
	return &cadk, true
}

// AsShowbackRuleProperties is the BasicShowbackRuleProperties implementation for CostAllocationDetailsKind.
func (cadk CostAllocationDetailsKind) AsShowbackRuleProperties() (*ShowbackRuleProperties, bool) {
	return nil, false
}

// AsBasicShowbackRuleProperties is the BasicShowbackRuleProperties implementation for CostAllocationDetailsKind.
func (cadk CostAllocationDetailsKind) AsBasicShowbackRuleProperties() (BasicShowbackRuleProperties, bool) {
	return &cadk, true
}

// UnmarshalJSON is the custom unmarshaler for CostAllocationDetailsKind struct.
func (cadk *CostAllocationDetailsKind) 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 "details":
			if v != nil {
				var costAllocationDetails CostAllocationDetails
				err = json.Unmarshal(*v, &costAllocationDetails)
				if err != nil {
					return err
				}
				cadk.CostAllocationDetails = &costAllocationDetails
			}
		case "description":
			if v != nil {
				var description string
				err = json.Unmarshal(*v, &description)
				if err != nil {
					return err
				}
				cadk.Description = &description
			}
		case "status":
			if v != nil {
				var status ShowbackRuleStatus
				err = json.Unmarshal(*v, &status)
				if err != nil {
					return err
				}
				cadk.Status = status
			}
		case "version":
			if v != nil {
				var version int32
				err = json.Unmarshal(*v, &version)
				if err != nil {
					return err
				}
				cadk.Version = &version
			}
		case "scopes":
			if v != nil {
				var scopes []Scope
				err = json.Unmarshal(*v, &scopes)
				if err != nil {
					return err
				}
				cadk.Scopes = &scopes
			}
		case "creationTime":
			if v != nil {
				var creationTime date.Time
				err = json.Unmarshal(*v, &creationTime)
				if err != nil {
					return err
				}
				cadk.CreationTime = &creationTime
			}
		case "deprecationTime":
			if v != nil {
				var deprecationTime date.Time
				err = json.Unmarshal(*v, &deprecationTime)
				if err != nil {
					return err
				}
				cadk.DeprecationTime = &deprecationTime
			}
		case "modificationTime":
			if v != nil {
				var modificationTime date.Time
				err = json.Unmarshal(*v, &modificationTime)
				if err != nil {
					return err
				}
				cadk.ModificationTime = &modificationTime
			}
		case "ruleType":
			if v != nil {
				var ruleType RuleType
				err = json.Unmarshal(*v, &ruleType)
				if err != nil {
					return err
				}
				cadk.RuleType = ruleType
			}
		}
	}

	return nil
}

// CustomPriceDetails represents Custom price showback rule model
type CustomPriceDetails struct {
	Pricesheet *string `json:"pricesheet,omitempty"`
	// Benefits - Array of benefits.
	Benefits *[]FunctionType `json:"benefits,omitempty"`
	// Markups - List of markups.
	Markups *[]Markup `json:"markups,omitempty"`
}

// CustomPriceDetailsKind represents Custom price showback rule model
type CustomPriceDetailsKind struct {
	// CustomPriceDetails - The Custom price properties to validate.
	*CustomPriceDetails `json:"details,omitempty"`
	// Description - Description of a showback rule.
	Description *string `json:"description,omitempty"`
	// Status - The current status of the showback rule. Possible values include: 'NotActive', 'Active'
	Status ShowbackRuleStatus `json:"status,omitempty"`
	// Version - READ-ONLY; The current version of showback rule.
	Version *int32 `json:"version,omitempty"`
	// Scopes - List of authorized assigned scopes.
	Scopes *[]Scope `json:"scopes,omitempty"`
	// CreationTime - READ-ONLY; The time when the showback rule was created.
	CreationTime *date.Time `json:"creationTime,omitempty"`
	// DeprecationTime - READ-ONLY; The current time when showback rule was deprecate.
	DeprecationTime *date.Time `json:"deprecationTime,omitempty"`
	// ModificationTime - READ-ONLY; The current status when showback rule was modified.
	ModificationTime *date.Time `json:"modificationTime,omitempty"`
	// RuleType - Possible values include: 'RuleTypeShowbackRuleProperties', 'RuleTypeCustomPrice', 'RuleTypeCostAllocation'
	RuleType RuleType `json:"ruleType,omitempty"`
}

// MarshalJSON is the custom marshaler for CustomPriceDetailsKind.
func (cpdk CustomPriceDetailsKind) MarshalJSON() ([]byte, error) {
	cpdk.RuleType = RuleTypeCustomPrice
	objectMap := make(map[string]interface{})
	if cpdk.CustomPriceDetails != nil {
		objectMap["details"] = cpdk.CustomPriceDetails
	}
	if cpdk.Description != nil {
		objectMap["description"] = cpdk.Description
	}
	if cpdk.Status != "" {
		objectMap["status"] = cpdk.Status
	}
	if cpdk.Scopes != nil {
		objectMap["scopes"] = cpdk.Scopes
	}
	if cpdk.RuleType != "" {
		objectMap["ruleType"] = cpdk.RuleType
	}
	return json.Marshal(objectMap)
}

// AsCustomPriceDetailsKind is the BasicShowbackRuleProperties implementation for CustomPriceDetailsKind.
func (cpdk CustomPriceDetailsKind) AsCustomPriceDetailsKind() (*CustomPriceDetailsKind, bool) {
	return &cpdk, true
}

// AsCostAllocationDetailsKind is the BasicShowbackRuleProperties implementation for CustomPriceDetailsKind.
func (cpdk CustomPriceDetailsKind) AsCostAllocationDetailsKind() (*CostAllocationDetailsKind, bool) {
	return nil, false
}

// AsShowbackRuleProperties is the BasicShowbackRuleProperties implementation for CustomPriceDetailsKind.
func (cpdk CustomPriceDetailsKind) AsShowbackRuleProperties() (*ShowbackRuleProperties, bool) {
	return nil, false
}

// AsBasicShowbackRuleProperties is the BasicShowbackRuleProperties implementation for CustomPriceDetailsKind.
func (cpdk CustomPriceDetailsKind) AsBasicShowbackRuleProperties() (BasicShowbackRuleProperties, bool) {
	return &cpdk, true
}

// UnmarshalJSON is the custom unmarshaler for CustomPriceDetailsKind struct.
func (cpdk *CustomPriceDetailsKind) 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 "details":
			if v != nil {
				var customPriceDetails CustomPriceDetails
				err = json.Unmarshal(*v, &customPriceDetails)
				if err != nil {
					return err
				}
				cpdk.CustomPriceDetails = &customPriceDetails
			}
		case "description":
			if v != nil {
				var description string
				err = json.Unmarshal(*v, &description)
				if err != nil {
					return err
				}
				cpdk.Description = &description
			}
		case "status":
			if v != nil {
				var status ShowbackRuleStatus
				err = json.Unmarshal(*v, &status)
				if err != nil {
					return err
				}
				cpdk.Status = status
			}
		case "version":
			if v != nil {
				var version int32
				err = json.Unmarshal(*v, &version)
				if err != nil {
					return err
				}
				cpdk.Version = &version
			}
		case "scopes":
			if v != nil {
				var scopes []Scope
				err = json.Unmarshal(*v, &scopes)
				if err != nil {
					return err
				}
				cpdk.Scopes = &scopes
			}
		case "creationTime":
			if v != nil {
				var creationTime date.Time
				err = json.Unmarshal(*v, &creationTime)
				if err != nil {
					return err
				}
				cpdk.CreationTime = &creationTime
			}
		case "deprecationTime":
			if v != nil {
				var deprecationTime date.Time
				err = json.Unmarshal(*v, &deprecationTime)
				if err != nil {
					return err
				}
				cpdk.DeprecationTime = &deprecationTime
			}
		case "modificationTime":
			if v != nil {
				var modificationTime date.Time
				err = json.Unmarshal(*v, &modificationTime)
				if err != nil {
					return err
				}
				cpdk.ModificationTime = &modificationTime
			}
		case "ruleType":
			if v != nil {
				var ruleType RuleType
				err = json.Unmarshal(*v, &ruleType)
				if err != nil {
					return err
				}
				cpdk.RuleType = ruleType
			}
		}
	}

	return nil
}

// 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     *string    `json:"description,omitempty"`
	FilterEnabled   *bool      `json:"filterEnabled,omitempty"`
	GroupingEnabled *bool      `json:"groupingEnabled,omitempty"`
	Data            *[]string  `json:"data,omitempty"`
	Total           *int32     `json:"total,omitempty"`
	Category        *string    `json:"category,omitempty"`
	UsageStart      *date.Time `json:"usageStart,omitempty"`
	UsageEnd        *date.Time `json:"usageEnd,omitempty"`
	NextLink        *string    `json:"nextLink,omitempty"`
}

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

// ErrorBase the details of the error.
type ErrorBase struct {
	// Code - READ-ONLY; A machine readable error code.
	Code *string `json:"code,omitempty"`
	// Message - READ-ONLY; A human readable error message.
	Message *string `json:"message,omitempty"`
	// Target - READ-ONLY; Indicates which property in the request is responsible for the error.
	Target *string `json:"target,omitempty"`
}

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

// ErrorDetails the details of the error.
type ErrorDetails struct {
	// Code - READ-ONLY; A machine readable error code.
	Code *string `json:"code,omitempty"`
	// Message - READ-ONLY; A human readable error message.
	Message *string `json:"message,omitempty"`
	// Target - Indicates which property in the request is responsible for the error.
	Target *string `json:"target,omitempty"`
	// Details - error details.
	Details *[]ErrorBase `json:"details,omitempty"`
}

// MarshalJSON is the custom marshaler for ErrorDetails.
func (ed ErrorDetails) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]interface{})
	if ed.Target != nil {
		objectMap["target"] = ed.Target
	}
	if ed.Details != nil {
		objectMap["details"] = ed.Details
	}
	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.
type ErrorResponse struct {
	// Error - The details of the error.
	Error *ErrorDetails `json:"error,omitempty"`
}

// ExternalBillingAccountDefinition the ExternalBillingAccount model definition
type ExternalBillingAccountDefinition struct {
	autorest.Response `json:"-"`
	// ID - READ-ONLY; ExternalBillingAccount id
	ID *string `json:"id,omitempty"`
	// Name - READ-ONLY; ExternalBillingAccount name
	Name *string `json:"name,omitempty"`
	// Type - READ-ONLY; ExternalBillingAccount type
	Type *string `json:"type,omitempty"`
	// Kind - READ-ONLY; ExternalBillingAccount kind (eg aws)
	Kind *string `json:"kind,omitempty"`
	// ExternalBillingAccountProperties - ExternalBillingAccount properties
	*ExternalBillingAccountProperties `json:"properties,omitempty"`
}

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

// UnmarshalJSON is the custom unmarshaler for ExternalBillingAccountDefinition struct.
func (ebad *ExternalBillingAccountDefinition) 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 "id":
			if v != nil {
				var ID string
				err = json.Unmarshal(*v, &ID)
				if err != nil {
					return err
				}
				ebad.ID = &ID
			}
		case "name":
			if v != nil {
				var name string
				err = json.Unmarshal(*v, &name)
				if err != nil {
					return err
				}
				ebad.Name = &name
			}
		case "type":
			if v != nil {
				var typeVar string
				err = json.Unmarshal(*v, &typeVar)
				if err != nil {
					return err
				}
				ebad.Type = &typeVar
			}
		case "kind":
			if v != nil {
				var kind string
				err = json.Unmarshal(*v, &kind)
				if err != nil {
					return err
				}
				ebad.Kind = &kind
			}
		case "properties":
			if v != nil {
				var externalBillingAccountProperties ExternalBillingAccountProperties
				err = json.Unmarshal(*v, &externalBillingAccountProperties)
				if err != nil {
					return err
				}
				ebad.ExternalBillingAccountProperties = &externalBillingAccountProperties
			}
		}
	}

	return nil
}

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

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

// ExternalBillingAccountProperties the properties of a ExternalBillingAccount
type ExternalBillingAccountProperties struct {
	// DisplayName - READ-ONLY; ExternalBillingAccount DisplayName
	DisplayName *string `json:"displayName,omitempty"`
	// ProviderBillingAccountID - READ-ONLY; Provider BillingAccountId (eg AWS Consolidated Account number)
	ProviderBillingAccountID *string `json:"providerBillingAccountId,omitempty"`
	// ConnectorID - READ-ONLY; Underlying ConnectorId
	ConnectorID *string `json:"connectorId,omitempty"`
	// CollectionInfo - READ-ONLY; Collection information
	CollectionInfo *ConnectorCollectionInfo `json:"collectionInfo,omitempty"`
}

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

// ExternalSubscriptionDefinition the ExternalSubscription model definition
type ExternalSubscriptionDefinition struct {
	autorest.Response `json:"-"`
	// ID - READ-ONLY; ExternalSubscription id
	ID *string `json:"id,omitempty"`
	// Name - READ-ONLY; ExternalSubscription name
	Name *string `json:"name,omitempty"`
	// Type - READ-ONLY; ExternalSubscription type
	Type *string `json:"type,omitempty"`
	// Kind - READ-ONLY; ExternalSubscription kind (eg aws)
	Kind *string `json:"kind,omitempty"`
	// ExternalSubscriptionProperties - ExternalSubscription properties
	*ExternalSubscriptionProperties `json:"properties,omitempty"`
}

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

// UnmarshalJSON is the custom unmarshaler for ExternalSubscriptionDefinition struct.
func (esd *ExternalSubscriptionDefinition) 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 "id":
			if v != nil {
				var ID string
				err = json.Unmarshal(*v, &ID)
				if err != nil {
					return err
				}
				esd.ID = &ID
			}
		case "name":
			if v != nil {
				var name string
				err = json.Unmarshal(*v, &name)
				if err != nil {
					return err
				}
				esd.Name = &name
			}
		case "type":
			if v != nil {
				var typeVar string
				err = json.Unmarshal(*v, &typeVar)
				if err != nil {
					return err
				}
				esd.Type = &typeVar
			}
		case "kind":
			if v != nil {
				var kind string
				err = json.Unmarshal(*v, &kind)
				if err != nil {
					return err
				}
				esd.Kind = &kind
			}
		case "properties":
			if v != nil {
				var externalSubscriptionProperties ExternalSubscriptionProperties
				err = json.Unmarshal(*v, &externalSubscriptionProperties)
				if err != nil {
					return err
				}
				esd.ExternalSubscriptionProperties = &externalSubscriptionProperties
			}
		}
	}

	return nil
}

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

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

// ExternalSubscriptionIDListRequest the list of ExternalSubscriptionIds operation request.
type ExternalSubscriptionIDListRequest struct {
	// Value - The list of ExternalSubscriptionIds.
	Value *[]string `json:"value,omitempty"`
}

// ExternalSubscriptionProperties the properties of a ExternalSubscription
type ExternalSubscriptionProperties struct {
	// DisplayName - READ-ONLY; ExternalSubscription DisplayName
	DisplayName *string `json:"displayName,omitempty"`
	// ManagementGroupID - READ-ONLY; Assigned ManagementGroupId
	ManagementGroupID *string `json:"managementGroupId,omitempty"`
	// ProviderBillingAccountID - READ-ONLY; Provider BillingAccountId (eg AWS Consolidated Account number)
	ProviderBillingAccountID *string `json:"providerBillingAccountId,omitempty"`
	// ProviderAccountID - READ-ONLY; Provider AccountId (eg AWS Linked Account number)
	ProviderAccountID *string `json:"providerAccountId,omitempty"`
	// ExternalBillingAccountID - READ-ONLY; Parent ExternalBillingAccountId
	ExternalBillingAccountID *string `json:"externalBillingAccountId,omitempty"`
	// CollectionInfo - READ-ONLY; Collection information
	CollectionInfo *ConnectorCollectionInfo `json:"collectionInfo,omitempty"`
}

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

// Markup the Markup model definition
type Markup struct {
	Percentage *string `json:"percentage,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,
	}
}

// Query ...
type Query struct {
	*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 Query.
func (q Query) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]interface{})
	if q.QueryProperties != nil {
		objectMap["properties"] = q.QueryProperties
	}
	return json.Marshal(objectMap)
}

// UnmarshalJSON is the custom unmarshaler for Query struct.
func (q *Query) 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
				}
				q.QueryProperties = &queryProperties
			}
		case "id":
			if v != nil {
				var ID string
				err = json.Unmarshal(*v, &ID)
				if err != nil {
					return err
				}
				q.ID = &ID
			}
		case "name":
			if v != nil {
				var name string
				err = json.Unmarshal(*v, &name)
				if err != nil {
					return err
				}
				q.Name = &name
			}
		case "type":
			if v != nil {
				var typeVar string
				err = json.Unmarshal(*v, &typeVar)
				if err != nil {
					return err
				}
				q.Type = &typeVar
			}
		case "tags":
			if v != nil {
				var tags map[string]*string
				err = json.Unmarshal(*v, &tags)
				if err != nil {
					return err
				}
				q.Tags = tags
			}
		}
	}

	return nil
}

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

// QueryProperties ...
type QueryProperties struct {
	NextLink *string `json:"nextLink,omitempty"`
	// Columns - Array of columns
	Columns *[]QueryColumn   `json:"columns,omitempty"`
	Rows    *[][]interface{} `json:"rows,omitempty"`
}

// QueryResult result of query. It contains all columns listed under groupings and aggregation.
type QueryResult struct {
	autorest.Response `json:"-"`
	// Value - READ-ONLY; The list of usage data.
	Value *[]Query `json:"value,omitempty"`
}

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

// 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: 'Daily', 'Monthly'
	Granularity GranularityType `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: 'WeekToDate', 'MonthToDate', 'YearToDate', 'Custom'
	Timeframe TimeframeType `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)
}

// Scope the Scope model definition
type Scope struct {
	// ID - Scope id
	ID *string `json:"id,omitempty"`
	// Name - Scope name
	Name *string `json:"name,omitempty"`
	// Type - Scope type
	Type       *string `json:"type,omitempty"`
	ChildScope *Scope  `json:"childScope,omitempty"`
}

// ShowbackRule the showback rule model definition
type ShowbackRule struct {
	autorest.Response `json:"-"`
	// ID - READ-ONLY; Rule id
	ID *string `json:"id,omitempty"`
	// Name - READ-ONLY; Rule name
	Name *string `json:"name,omitempty"`
	// Type - READ-ONLY; Rule type
	Type *string `json:"type,omitempty"`
	// BasicShowbackRuleProperties - Showback rule properties
	BasicShowbackRuleProperties `json:"properties,omitempty"`
}

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

// UnmarshalJSON is the custom unmarshaler for ShowbackRule struct.
func (sr *ShowbackRule) 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 "id":
			if v != nil {
				var ID string
				err = json.Unmarshal(*v, &ID)
				if err != nil {
					return err
				}
				sr.ID = &ID
			}
		case "name":
			if v != nil {
				var name string
				err = json.Unmarshal(*v, &name)
				if err != nil {
					return err
				}
				sr.Name = &name
			}
		case "type":
			if v != nil {
				var typeVar string
				err = json.Unmarshal(*v, &typeVar)
				if err != nil {
					return err
				}
				sr.Type = &typeVar
			}
		case "properties":
			if v != nil {
				basicShowbackRuleProperties, err := unmarshalBasicShowbackRuleProperties(*v)
				if err != nil {
					return err
				}
				sr.BasicShowbackRuleProperties = basicShowbackRuleProperties
			}
		}
	}

	return nil
}

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

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

// BasicShowbackRuleProperties the properties of a showback rule.
type BasicShowbackRuleProperties interface {
	AsCustomPriceDetailsKind() (*CustomPriceDetailsKind, bool)
	AsCostAllocationDetailsKind() (*CostAllocationDetailsKind, bool)
	AsShowbackRuleProperties() (*ShowbackRuleProperties, bool)
}

// ShowbackRuleProperties the properties of a showback rule.
type ShowbackRuleProperties struct {
	// Description - Description of a showback rule.
	Description *string `json:"description,omitempty"`
	// Status - The current status of the showback rule. Possible values include: 'NotActive', 'Active'
	Status ShowbackRuleStatus `json:"status,omitempty"`
	// Version - READ-ONLY; The current version of showback rule.
	Version *int32 `json:"version,omitempty"`
	// Scopes - List of authorized assigned scopes.
	Scopes *[]Scope `json:"scopes,omitempty"`
	// CreationTime - READ-ONLY; The time when the showback rule was created.
	CreationTime *date.Time `json:"creationTime,omitempty"`
	// DeprecationTime - READ-ONLY; The current time when showback rule was deprecate.
	DeprecationTime *date.Time `json:"deprecationTime,omitempty"`
	// ModificationTime - READ-ONLY; The current status when showback rule was modified.
	ModificationTime *date.Time `json:"modificationTime,omitempty"`
	// RuleType - Possible values include: 'RuleTypeShowbackRuleProperties', 'RuleTypeCustomPrice', 'RuleTypeCostAllocation'
	RuleType RuleType `json:"ruleType,omitempty"`
}

func unmarshalBasicShowbackRuleProperties(body []byte) (BasicShowbackRuleProperties, error) {
	var m map[string]interface{}
	err := json.Unmarshal(body, &m)
	if err != nil {
		return nil, err
	}

	switch m["ruleType"] {
	case string(RuleTypeCustomPrice):
		var cpdk CustomPriceDetailsKind
		err := json.Unmarshal(body, &cpdk)
		return cpdk, err
	case string(RuleTypeCostAllocation):
		var cadk CostAllocationDetailsKind
		err := json.Unmarshal(body, &cadk)
		return cadk, err
	default:
		var srp ShowbackRuleProperties
		err := json.Unmarshal(body, &srp)
		return srp, err
	}
}
func unmarshalBasicShowbackRulePropertiesArray(body []byte) ([]BasicShowbackRuleProperties, error) {
	var rawMessages []*json.RawMessage
	err := json.Unmarshal(body, &rawMessages)
	if err != nil {
		return nil, err
	}

	srpArray := make([]BasicShowbackRuleProperties, len(rawMessages))

	for index, rawMessage := range rawMessages {
		srp, err := unmarshalBasicShowbackRuleProperties(*rawMessage)
		if err != nil {
			return nil, err
		}
		srpArray[index] = srp
	}
	return srpArray, nil
}

// MarshalJSON is the custom marshaler for ShowbackRuleProperties.
func (srp ShowbackRuleProperties) MarshalJSON() ([]byte, error) {
	srp.RuleType = RuleTypeShowbackRuleProperties
	objectMap := make(map[string]interface{})
	if srp.Description != nil {
		objectMap["description"] = srp.Description
	}
	if srp.Status != "" {
		objectMap["status"] = srp.Status
	}
	if srp.Scopes != nil {
		objectMap["scopes"] = srp.Scopes
	}
	if srp.RuleType != "" {
		objectMap["ruleType"] = srp.RuleType
	}
	return json.Marshal(objectMap)
}

// AsCustomPriceDetailsKind is the BasicShowbackRuleProperties implementation for ShowbackRuleProperties.
func (srp ShowbackRuleProperties) AsCustomPriceDetailsKind() (*CustomPriceDetailsKind, bool) {
	return nil, false
}

// AsCostAllocationDetailsKind is the BasicShowbackRuleProperties implementation for ShowbackRuleProperties.
func (srp ShowbackRuleProperties) AsCostAllocationDetailsKind() (*CostAllocationDetailsKind, bool) {
	return nil, false
}

// AsShowbackRuleProperties is the BasicShowbackRuleProperties implementation for ShowbackRuleProperties.
func (srp ShowbackRuleProperties) AsShowbackRuleProperties() (*ShowbackRuleProperties, bool) {
	return &srp, true
}

// AsBasicShowbackRuleProperties is the BasicShowbackRuleProperties implementation for ShowbackRuleProperties.
func (srp ShowbackRuleProperties) AsBasicShowbackRuleProperties() (BasicShowbackRuleProperties, bool) {
	return &srp, true
}
