package metrics

// 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 (
	"encoding/json"
	"github.com/Azure/go-autorest/autorest"
	"github.com/Azure/go-autorest/autorest/date"
)

// The package's fully qualified name.
const fqdn = "github.com/Azure/azure-sdk-for-go/services/preview/monitor/mgmt/2021-05-01-preview/metrics"

// AlertAction an alert action.
type AlertAction struct {
	// ActionGroupID - the id of the action group to use.
	ActionGroupID *string `json:"actionGroupId,omitempty"`
	// WebHookProperties - This field allows specifying custom properties, which would be appended to the alert payload sent as input to the webhook.
	WebHookProperties map[string]*string `json:"webHookProperties"`
}

// MarshalJSON is the custom marshaler for AlertAction.
func (aa AlertAction) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]interface{})
	if aa.ActionGroupID != nil {
		objectMap["actionGroupId"] = aa.ActionGroupID
	}
	if aa.WebHookProperties != nil {
		objectMap["webHookProperties"] = aa.WebHookProperties
	}
	return json.Marshal(objectMap)
}

// BasicAlertCriteria the rule criteria that defines the conditions of the alert rule.
type BasicAlertCriteria interface {
	AsAlertSingleResourceMultipleMetricCriteria() (*AlertSingleResourceMultipleMetricCriteria, bool)
	AsWebtestLocationAvailabilityCriteria() (*WebtestLocationAvailabilityCriteria, bool)
	AsAlertMultipleResourceMultipleMetricCriteria() (*AlertMultipleResourceMultipleMetricCriteria, bool)
	AsAlertCriteria() (*AlertCriteria, bool)
}

// AlertCriteria the rule criteria that defines the conditions of the alert rule.
type AlertCriteria struct {
	// AdditionalProperties - Unmatched properties from the message are deserialized this collection
	AdditionalProperties map[string]interface{} `json:""`
	// OdataType - Possible values include: 'OdataTypeMetricAlertCriteria', 'OdataTypeMicrosoftAzureMonitorSingleResourceMultipleMetricCriteria', 'OdataTypeMicrosoftAzureMonitorWebtestLocationAvailabilityCriteria', 'OdataTypeMicrosoftAzureMonitorMultipleResourceMultipleMetricCriteria'
	OdataType OdataType `json:"odata.type,omitempty"`
}

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

	switch m["odata.type"] {
	case string(OdataTypeMicrosoftAzureMonitorSingleResourceMultipleMetricCriteria):
		var asrmmc AlertSingleResourceMultipleMetricCriteria
		err := json.Unmarshal(body, &asrmmc)
		return asrmmc, err
	case string(OdataTypeMicrosoftAzureMonitorWebtestLocationAvailabilityCriteria):
		var wlac WebtestLocationAvailabilityCriteria
		err := json.Unmarshal(body, &wlac)
		return wlac, err
	case string(OdataTypeMicrosoftAzureMonitorMultipleResourceMultipleMetricCriteria):
		var amrmmc AlertMultipleResourceMultipleMetricCriteria
		err := json.Unmarshal(body, &amrmmc)
		return amrmmc, err
	default:
		var ac AlertCriteria
		err := json.Unmarshal(body, &ac)
		return ac, err
	}
}
func unmarshalBasicAlertCriteriaArray(body []byte) ([]BasicAlertCriteria, error) {
	var rawMessages []*json.RawMessage
	err := json.Unmarshal(body, &rawMessages)
	if err != nil {
		return nil, err
	}

	acArray := make([]BasicAlertCriteria, len(rawMessages))

	for index, rawMessage := range rawMessages {
		ac, err := unmarshalBasicAlertCriteria(*rawMessage)
		if err != nil {
			return nil, err
		}
		acArray[index] = ac
	}
	return acArray, nil
}

// MarshalJSON is the custom marshaler for AlertCriteria.
func (ac AlertCriteria) MarshalJSON() ([]byte, error) {
	ac.OdataType = OdataTypeMetricAlertCriteria
	objectMap := make(map[string]interface{})
	if ac.OdataType != "" {
		objectMap["odata.type"] = ac.OdataType
	}
	for k, v := range ac.AdditionalProperties {
		objectMap[k] = v
	}
	return json.Marshal(objectMap)
}

// AsAlertSingleResourceMultipleMetricCriteria is the BasicAlertCriteria implementation for AlertCriteria.
func (ac AlertCriteria) AsAlertSingleResourceMultipleMetricCriteria() (*AlertSingleResourceMultipleMetricCriteria, bool) {
	return nil, false
}

// AsWebtestLocationAvailabilityCriteria is the BasicAlertCriteria implementation for AlertCriteria.
func (ac AlertCriteria) AsWebtestLocationAvailabilityCriteria() (*WebtestLocationAvailabilityCriteria, bool) {
	return nil, false
}

// AsAlertMultipleResourceMultipleMetricCriteria is the BasicAlertCriteria implementation for AlertCriteria.
func (ac AlertCriteria) AsAlertMultipleResourceMultipleMetricCriteria() (*AlertMultipleResourceMultipleMetricCriteria, bool) {
	return nil, false
}

// AsAlertCriteria is the BasicAlertCriteria implementation for AlertCriteria.
func (ac AlertCriteria) AsAlertCriteria() (*AlertCriteria, bool) {
	return &ac, true
}

// AsBasicAlertCriteria is the BasicAlertCriteria implementation for AlertCriteria.
func (ac AlertCriteria) AsBasicAlertCriteria() (BasicAlertCriteria, bool) {
	return &ac, true
}

// UnmarshalJSON is the custom unmarshaler for AlertCriteria struct.
func (ac *AlertCriteria) 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 {
		default:
			if v != nil {
				var additionalProperties interface{}
				err = json.Unmarshal(*v, &additionalProperties)
				if err != nil {
					return err
				}
				if ac.AdditionalProperties == nil {
					ac.AdditionalProperties = make(map[string]interface{})
				}
				ac.AdditionalProperties[k] = additionalProperties
			}
		case "odata.type":
			if v != nil {
				var odataType OdataType
				err = json.Unmarshal(*v, &odataType)
				if err != nil {
					return err
				}
				ac.OdataType = odataType
			}
		}
	}

	return nil
}

// AlertMultipleResourceMultipleMetricCriteria specifies the metric alert criteria for multiple resource
// that has multiple metric criteria.
type AlertMultipleResourceMultipleMetricCriteria struct {
	// AllOf - the list of multiple metric criteria for this 'all of' operation.
	AllOf *[]BasicMultiMetricCriteria `json:"allOf,omitempty"`
	// AdditionalProperties - Unmatched properties from the message are deserialized this collection
	AdditionalProperties map[string]interface{} `json:""`
	// OdataType - Possible values include: 'OdataTypeMetricAlertCriteria', 'OdataTypeMicrosoftAzureMonitorSingleResourceMultipleMetricCriteria', 'OdataTypeMicrosoftAzureMonitorWebtestLocationAvailabilityCriteria', 'OdataTypeMicrosoftAzureMonitorMultipleResourceMultipleMetricCriteria'
	OdataType OdataType `json:"odata.type,omitempty"`
}

// MarshalJSON is the custom marshaler for AlertMultipleResourceMultipleMetricCriteria.
func (amrmmc AlertMultipleResourceMultipleMetricCriteria) MarshalJSON() ([]byte, error) {
	amrmmc.OdataType = OdataTypeMicrosoftAzureMonitorMultipleResourceMultipleMetricCriteria
	objectMap := make(map[string]interface{})
	if amrmmc.AllOf != nil {
		objectMap["allOf"] = amrmmc.AllOf
	}
	if amrmmc.OdataType != "" {
		objectMap["odata.type"] = amrmmc.OdataType
	}
	for k, v := range amrmmc.AdditionalProperties {
		objectMap[k] = v
	}
	return json.Marshal(objectMap)
}

// AsAlertSingleResourceMultipleMetricCriteria is the BasicAlertCriteria implementation for AlertMultipleResourceMultipleMetricCriteria.
func (amrmmc AlertMultipleResourceMultipleMetricCriteria) AsAlertSingleResourceMultipleMetricCriteria() (*AlertSingleResourceMultipleMetricCriteria, bool) {
	return nil, false
}

// AsWebtestLocationAvailabilityCriteria is the BasicAlertCriteria implementation for AlertMultipleResourceMultipleMetricCriteria.
func (amrmmc AlertMultipleResourceMultipleMetricCriteria) AsWebtestLocationAvailabilityCriteria() (*WebtestLocationAvailabilityCriteria, bool) {
	return nil, false
}

// AsAlertMultipleResourceMultipleMetricCriteria is the BasicAlertCriteria implementation for AlertMultipleResourceMultipleMetricCriteria.
func (amrmmc AlertMultipleResourceMultipleMetricCriteria) AsAlertMultipleResourceMultipleMetricCriteria() (*AlertMultipleResourceMultipleMetricCriteria, bool) {
	return &amrmmc, true
}

// AsAlertCriteria is the BasicAlertCriteria implementation for AlertMultipleResourceMultipleMetricCriteria.
func (amrmmc AlertMultipleResourceMultipleMetricCriteria) AsAlertCriteria() (*AlertCriteria, bool) {
	return nil, false
}

// AsBasicAlertCriteria is the BasicAlertCriteria implementation for AlertMultipleResourceMultipleMetricCriteria.
func (amrmmc AlertMultipleResourceMultipleMetricCriteria) AsBasicAlertCriteria() (BasicAlertCriteria, bool) {
	return &amrmmc, true
}

// UnmarshalJSON is the custom unmarshaler for AlertMultipleResourceMultipleMetricCriteria struct.
func (amrmmc *AlertMultipleResourceMultipleMetricCriteria) 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 "allOf":
			if v != nil {
				allOf, err := unmarshalBasicMultiMetricCriteriaArray(*v)
				if err != nil {
					return err
				}
				amrmmc.AllOf = &allOf
			}
		default:
			if v != nil {
				var additionalProperties interface{}
				err = json.Unmarshal(*v, &additionalProperties)
				if err != nil {
					return err
				}
				if amrmmc.AdditionalProperties == nil {
					amrmmc.AdditionalProperties = make(map[string]interface{})
				}
				amrmmc.AdditionalProperties[k] = additionalProperties
			}
		case "odata.type":
			if v != nil {
				var odataType OdataType
				err = json.Unmarshal(*v, &odataType)
				if err != nil {
					return err
				}
				amrmmc.OdataType = odataType
			}
		}
	}

	return nil
}

// AlertProperties an alert rule.
type AlertProperties struct {
	// Description - the description of the metric alert that will be included in the alert email.
	Description *string `json:"description,omitempty"`
	// Severity - Alert severity {0, 1, 2, 3, 4}
	Severity *int32 `json:"severity,omitempty"`
	// Enabled - the flag that indicates whether the metric alert is enabled.
	Enabled *bool `json:"enabled,omitempty"`
	// Scopes - the list of resource id's that this metric alert is scoped to.
	Scopes *[]string `json:"scopes,omitempty"`
	// EvaluationFrequency - how often the metric alert is evaluated represented in ISO 8601 duration format.
	EvaluationFrequency *string `json:"evaluationFrequency,omitempty"`
	// WindowSize - the period of time (in ISO 8601 duration format) that is used to monitor alert activity based on the threshold.
	WindowSize *string `json:"windowSize,omitempty"`
	// TargetResourceType - the resource type of the target resource(s) on which the alert is created/updated. Mandatory if the scope contains a subscription, resource group, or more than one resource.
	TargetResourceType *string `json:"targetResourceType,omitempty"`
	// TargetResourceRegion - the region of the target resource(s) on which the alert is created/updated. Mandatory if the scope contains a subscription, resource group, or more than one resource.
	TargetResourceRegion *string `json:"targetResourceRegion,omitempty"`
	// Criteria - defines the specific alert criteria information.
	Criteria BasicAlertCriteria `json:"criteria,omitempty"`
	// AutoMitigate - the flag that indicates whether the alert should be auto resolved or not. The default is true.
	AutoMitigate *bool `json:"autoMitigate,omitempty"`
	// Actions - the array of actions that are performed when the alert rule becomes active, and when an alert condition is resolved.
	Actions *[]AlertAction `json:"actions,omitempty"`
	// LastUpdatedTime - READ-ONLY; Last time the rule was updated in ISO8601 format.
	LastUpdatedTime *date.Time `json:"lastUpdatedTime,omitempty"`
	// IsMigrated - READ-ONLY; the value indicating whether this alert rule is migrated.
	IsMigrated *bool `json:"isMigrated,omitempty"`
}

// MarshalJSON is the custom marshaler for AlertProperties.
func (ap AlertProperties) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]interface{})
	if ap.Description != nil {
		objectMap["description"] = ap.Description
	}
	if ap.Severity != nil {
		objectMap["severity"] = ap.Severity
	}
	if ap.Enabled != nil {
		objectMap["enabled"] = ap.Enabled
	}
	if ap.Scopes != nil {
		objectMap["scopes"] = ap.Scopes
	}
	if ap.EvaluationFrequency != nil {
		objectMap["evaluationFrequency"] = ap.EvaluationFrequency
	}
	if ap.WindowSize != nil {
		objectMap["windowSize"] = ap.WindowSize
	}
	if ap.TargetResourceType != nil {
		objectMap["targetResourceType"] = ap.TargetResourceType
	}
	if ap.TargetResourceRegion != nil {
		objectMap["targetResourceRegion"] = ap.TargetResourceRegion
	}
	objectMap["criteria"] = ap.Criteria
	if ap.AutoMitigate != nil {
		objectMap["autoMitigate"] = ap.AutoMitigate
	}
	if ap.Actions != nil {
		objectMap["actions"] = ap.Actions
	}
	return json.Marshal(objectMap)
}

// UnmarshalJSON is the custom unmarshaler for AlertProperties struct.
func (ap *AlertProperties) 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 "description":
			if v != nil {
				var description string
				err = json.Unmarshal(*v, &description)
				if err != nil {
					return err
				}
				ap.Description = &description
			}
		case "severity":
			if v != nil {
				var severity int32
				err = json.Unmarshal(*v, &severity)
				if err != nil {
					return err
				}
				ap.Severity = &severity
			}
		case "enabled":
			if v != nil {
				var enabled bool
				err = json.Unmarshal(*v, &enabled)
				if err != nil {
					return err
				}
				ap.Enabled = &enabled
			}
		case "scopes":
			if v != nil {
				var scopes []string
				err = json.Unmarshal(*v, &scopes)
				if err != nil {
					return err
				}
				ap.Scopes = &scopes
			}
		case "evaluationFrequency":
			if v != nil {
				var evaluationFrequency string
				err = json.Unmarshal(*v, &evaluationFrequency)
				if err != nil {
					return err
				}
				ap.EvaluationFrequency = &evaluationFrequency
			}
		case "windowSize":
			if v != nil {
				var windowSize string
				err = json.Unmarshal(*v, &windowSize)
				if err != nil {
					return err
				}
				ap.WindowSize = &windowSize
			}
		case "targetResourceType":
			if v != nil {
				var targetResourceType string
				err = json.Unmarshal(*v, &targetResourceType)
				if err != nil {
					return err
				}
				ap.TargetResourceType = &targetResourceType
			}
		case "targetResourceRegion":
			if v != nil {
				var targetResourceRegion string
				err = json.Unmarshal(*v, &targetResourceRegion)
				if err != nil {
					return err
				}
				ap.TargetResourceRegion = &targetResourceRegion
			}
		case "criteria":
			if v != nil {
				criteria, err := unmarshalBasicAlertCriteria(*v)
				if err != nil {
					return err
				}
				ap.Criteria = criteria
			}
		case "autoMitigate":
			if v != nil {
				var autoMitigate bool
				err = json.Unmarshal(*v, &autoMitigate)
				if err != nil {
					return err
				}
				ap.AutoMitigate = &autoMitigate
			}
		case "actions":
			if v != nil {
				var actions []AlertAction
				err = json.Unmarshal(*v, &actions)
				if err != nil {
					return err
				}
				ap.Actions = &actions
			}
		case "lastUpdatedTime":
			if v != nil {
				var lastUpdatedTime date.Time
				err = json.Unmarshal(*v, &lastUpdatedTime)
				if err != nil {
					return err
				}
				ap.LastUpdatedTime = &lastUpdatedTime
			}
		case "isMigrated":
			if v != nil {
				var isMigrated bool
				err = json.Unmarshal(*v, &isMigrated)
				if err != nil {
					return err
				}
				ap.IsMigrated = &isMigrated
			}
		}
	}

	return nil
}

// AlertPropertiesPatch an alert rule properties for patch.
type AlertPropertiesPatch struct {
	// Description - the description of the metric alert that will be included in the alert email.
	Description *string `json:"description,omitempty"`
	// Severity - Alert severity {0, 1, 2, 3, 4}
	Severity *int32 `json:"severity,omitempty"`
	// Enabled - the flag that indicates whether the metric alert is enabled.
	Enabled *bool `json:"enabled,omitempty"`
	// Scopes - the list of resource id's that this metric alert is scoped to.
	Scopes *[]string `json:"scopes,omitempty"`
	// EvaluationFrequency - how often the metric alert is evaluated represented in ISO 8601 duration format.
	EvaluationFrequency *string `json:"evaluationFrequency,omitempty"`
	// WindowSize - the period of time (in ISO 8601 duration format) that is used to monitor alert activity based on the threshold.
	WindowSize *string `json:"windowSize,omitempty"`
	// TargetResourceType - the resource type of the target resource(s) on which the alert is created/updated. Mandatory for MultipleResourceMultipleMetricCriteria.
	TargetResourceType *string `json:"targetResourceType,omitempty"`
	// TargetResourceRegion - the region of the target resource(s) on which the alert is created/updated. Mandatory for MultipleResourceMultipleMetricCriteria.
	TargetResourceRegion *string `json:"targetResourceRegion,omitempty"`
	// Criteria - defines the specific alert criteria information.
	Criteria BasicAlertCriteria `json:"criteria,omitempty"`
	// AutoMitigate - the flag that indicates whether the alert should be auto resolved or not. The default is true.
	AutoMitigate *bool `json:"autoMitigate,omitempty"`
	// Actions - the array of actions that are performed when the alert rule becomes active, and when an alert condition is resolved.
	Actions *[]AlertAction `json:"actions,omitempty"`
	// LastUpdatedTime - READ-ONLY; Last time the rule was updated in ISO8601 format.
	LastUpdatedTime *date.Time `json:"lastUpdatedTime,omitempty"`
	// IsMigrated - READ-ONLY; the value indicating whether this alert rule is migrated.
	IsMigrated *bool `json:"isMigrated,omitempty"`
}

// MarshalJSON is the custom marshaler for AlertPropertiesPatch.
func (app AlertPropertiesPatch) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]interface{})
	if app.Description != nil {
		objectMap["description"] = app.Description
	}
	if app.Severity != nil {
		objectMap["severity"] = app.Severity
	}
	if app.Enabled != nil {
		objectMap["enabled"] = app.Enabled
	}
	if app.Scopes != nil {
		objectMap["scopes"] = app.Scopes
	}
	if app.EvaluationFrequency != nil {
		objectMap["evaluationFrequency"] = app.EvaluationFrequency
	}
	if app.WindowSize != nil {
		objectMap["windowSize"] = app.WindowSize
	}
	if app.TargetResourceType != nil {
		objectMap["targetResourceType"] = app.TargetResourceType
	}
	if app.TargetResourceRegion != nil {
		objectMap["targetResourceRegion"] = app.TargetResourceRegion
	}
	objectMap["criteria"] = app.Criteria
	if app.AutoMitigate != nil {
		objectMap["autoMitigate"] = app.AutoMitigate
	}
	if app.Actions != nil {
		objectMap["actions"] = app.Actions
	}
	return json.Marshal(objectMap)
}

// UnmarshalJSON is the custom unmarshaler for AlertPropertiesPatch struct.
func (app *AlertPropertiesPatch) 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 "description":
			if v != nil {
				var description string
				err = json.Unmarshal(*v, &description)
				if err != nil {
					return err
				}
				app.Description = &description
			}
		case "severity":
			if v != nil {
				var severity int32
				err = json.Unmarshal(*v, &severity)
				if err != nil {
					return err
				}
				app.Severity = &severity
			}
		case "enabled":
			if v != nil {
				var enabled bool
				err = json.Unmarshal(*v, &enabled)
				if err != nil {
					return err
				}
				app.Enabled = &enabled
			}
		case "scopes":
			if v != nil {
				var scopes []string
				err = json.Unmarshal(*v, &scopes)
				if err != nil {
					return err
				}
				app.Scopes = &scopes
			}
		case "evaluationFrequency":
			if v != nil {
				var evaluationFrequency string
				err = json.Unmarshal(*v, &evaluationFrequency)
				if err != nil {
					return err
				}
				app.EvaluationFrequency = &evaluationFrequency
			}
		case "windowSize":
			if v != nil {
				var windowSize string
				err = json.Unmarshal(*v, &windowSize)
				if err != nil {
					return err
				}
				app.WindowSize = &windowSize
			}
		case "targetResourceType":
			if v != nil {
				var targetResourceType string
				err = json.Unmarshal(*v, &targetResourceType)
				if err != nil {
					return err
				}
				app.TargetResourceType = &targetResourceType
			}
		case "targetResourceRegion":
			if v != nil {
				var targetResourceRegion string
				err = json.Unmarshal(*v, &targetResourceRegion)
				if err != nil {
					return err
				}
				app.TargetResourceRegion = &targetResourceRegion
			}
		case "criteria":
			if v != nil {
				criteria, err := unmarshalBasicAlertCriteria(*v)
				if err != nil {
					return err
				}
				app.Criteria = criteria
			}
		case "autoMitigate":
			if v != nil {
				var autoMitigate bool
				err = json.Unmarshal(*v, &autoMitigate)
				if err != nil {
					return err
				}
				app.AutoMitigate = &autoMitigate
			}
		case "actions":
			if v != nil {
				var actions []AlertAction
				err = json.Unmarshal(*v, &actions)
				if err != nil {
					return err
				}
				app.Actions = &actions
			}
		case "lastUpdatedTime":
			if v != nil {
				var lastUpdatedTime date.Time
				err = json.Unmarshal(*v, &lastUpdatedTime)
				if err != nil {
					return err
				}
				app.LastUpdatedTime = &lastUpdatedTime
			}
		case "isMigrated":
			if v != nil {
				var isMigrated bool
				err = json.Unmarshal(*v, &isMigrated)
				if err != nil {
					return err
				}
				app.IsMigrated = &isMigrated
			}
		}
	}

	return nil
}

// AlertResource the metric alert resource.
type AlertResource struct {
	autorest.Response `json:"-"`
	// AlertProperties - The alert rule properties of the resource.
	*AlertProperties `json:"properties,omitempty"`
	// ID - READ-ONLY; Azure resource Id
	ID *string `json:"id,omitempty"`
	// Name - READ-ONLY; Azure resource name
	Name *string `json:"name,omitempty"`
	// Type - READ-ONLY; Azure resource type
	Type *string `json:"type,omitempty"`
	// Location - Resource location
	Location *string `json:"location,omitempty"`
	// Tags - Resource tags
	Tags map[string]*string `json:"tags"`
}

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

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

	return nil
}

// AlertResourceCollection represents a collection of alert rule resources.
type AlertResourceCollection struct {
	autorest.Response `json:"-"`
	// Value - the values for the alert rule resources.
	Value *[]AlertResource `json:"value,omitempty"`
}

// AlertResourcePatch the metric alert resource for patch operations.
type AlertResourcePatch struct {
	// Tags - Resource tags
	Tags map[string]*string `json:"tags"`
	// AlertPropertiesPatch - The alert rule properties of the resource.
	*AlertPropertiesPatch `json:"properties,omitempty"`
}

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

// UnmarshalJSON is the custom unmarshaler for AlertResourcePatch struct.
func (arp *AlertResourcePatch) 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 "tags":
			if v != nil {
				var tags map[string]*string
				err = json.Unmarshal(*v, &tags)
				if err != nil {
					return err
				}
				arp.Tags = tags
			}
		case "properties":
			if v != nil {
				var alertPropertiesPatch AlertPropertiesPatch
				err = json.Unmarshal(*v, &alertPropertiesPatch)
				if err != nil {
					return err
				}
				arp.AlertPropertiesPatch = &alertPropertiesPatch
			}
		}
	}

	return nil
}

// AlertSingleResourceMultipleMetricCriteria specifies the metric alert criteria for a single resource that
// has multiple metric criteria.
type AlertSingleResourceMultipleMetricCriteria struct {
	// AllOf - The list of metric criteria for this 'all of' operation.
	AllOf *[]Criteria `json:"allOf,omitempty"`
	// AdditionalProperties - Unmatched properties from the message are deserialized this collection
	AdditionalProperties map[string]interface{} `json:""`
	// OdataType - Possible values include: 'OdataTypeMetricAlertCriteria', 'OdataTypeMicrosoftAzureMonitorSingleResourceMultipleMetricCriteria', 'OdataTypeMicrosoftAzureMonitorWebtestLocationAvailabilityCriteria', 'OdataTypeMicrosoftAzureMonitorMultipleResourceMultipleMetricCriteria'
	OdataType OdataType `json:"odata.type,omitempty"`
}

// MarshalJSON is the custom marshaler for AlertSingleResourceMultipleMetricCriteria.
func (asrmmc AlertSingleResourceMultipleMetricCriteria) MarshalJSON() ([]byte, error) {
	asrmmc.OdataType = OdataTypeMicrosoftAzureMonitorSingleResourceMultipleMetricCriteria
	objectMap := make(map[string]interface{})
	if asrmmc.AllOf != nil {
		objectMap["allOf"] = asrmmc.AllOf
	}
	if asrmmc.OdataType != "" {
		objectMap["odata.type"] = asrmmc.OdataType
	}
	for k, v := range asrmmc.AdditionalProperties {
		objectMap[k] = v
	}
	return json.Marshal(objectMap)
}

// AsAlertSingleResourceMultipleMetricCriteria is the BasicAlertCriteria implementation for AlertSingleResourceMultipleMetricCriteria.
func (asrmmc AlertSingleResourceMultipleMetricCriteria) AsAlertSingleResourceMultipleMetricCriteria() (*AlertSingleResourceMultipleMetricCriteria, bool) {
	return &asrmmc, true
}

// AsWebtestLocationAvailabilityCriteria is the BasicAlertCriteria implementation for AlertSingleResourceMultipleMetricCriteria.
func (asrmmc AlertSingleResourceMultipleMetricCriteria) AsWebtestLocationAvailabilityCriteria() (*WebtestLocationAvailabilityCriteria, bool) {
	return nil, false
}

// AsAlertMultipleResourceMultipleMetricCriteria is the BasicAlertCriteria implementation for AlertSingleResourceMultipleMetricCriteria.
func (asrmmc AlertSingleResourceMultipleMetricCriteria) AsAlertMultipleResourceMultipleMetricCriteria() (*AlertMultipleResourceMultipleMetricCriteria, bool) {
	return nil, false
}

// AsAlertCriteria is the BasicAlertCriteria implementation for AlertSingleResourceMultipleMetricCriteria.
func (asrmmc AlertSingleResourceMultipleMetricCriteria) AsAlertCriteria() (*AlertCriteria, bool) {
	return nil, false
}

// AsBasicAlertCriteria is the BasicAlertCriteria implementation for AlertSingleResourceMultipleMetricCriteria.
func (asrmmc AlertSingleResourceMultipleMetricCriteria) AsBasicAlertCriteria() (BasicAlertCriteria, bool) {
	return &asrmmc, true
}

// UnmarshalJSON is the custom unmarshaler for AlertSingleResourceMultipleMetricCriteria struct.
func (asrmmc *AlertSingleResourceMultipleMetricCriteria) 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 "allOf":
			if v != nil {
				var allOf []Criteria
				err = json.Unmarshal(*v, &allOf)
				if err != nil {
					return err
				}
				asrmmc.AllOf = &allOf
			}
		default:
			if v != nil {
				var additionalProperties interface{}
				err = json.Unmarshal(*v, &additionalProperties)
				if err != nil {
					return err
				}
				if asrmmc.AdditionalProperties == nil {
					asrmmc.AdditionalProperties = make(map[string]interface{})
				}
				asrmmc.AdditionalProperties[k] = additionalProperties
			}
		case "odata.type":
			if v != nil {
				var odataType OdataType
				err = json.Unmarshal(*v, &odataType)
				if err != nil {
					return err
				}
				asrmmc.OdataType = odataType
			}
		}
	}

	return nil
}

// AlertStatus an alert status.
type AlertStatus struct {
	// Name - The status name.
	Name *string `json:"name,omitempty"`
	// ID - The alert rule arm id.
	ID *string `json:"id,omitempty"`
	// Type - The extended resource type name.
	Type *string `json:"type,omitempty"`
	// Properties - The alert status properties of the metric alert status.
	Properties *AlertStatusProperties `json:"properties,omitempty"`
}

// AlertStatusCollection represents a collection of alert rule resources.
type AlertStatusCollection struct {
	autorest.Response `json:"-"`
	// Value - the values for the alert rule resources.
	Value *[]AlertStatus `json:"value,omitempty"`
}

// AlertStatusProperties an alert status properties.
type AlertStatusProperties struct {
	// Dimensions - An object describing the type of the dimensions.
	Dimensions map[string]*string `json:"dimensions"`
	// Status - status value
	Status *string `json:"status,omitempty"`
	// Timestamp - UTC time when the status was checked.
	Timestamp *date.Time `json:"timestamp,omitempty"`
}

// MarshalJSON is the custom marshaler for AlertStatusProperties.
func (asp AlertStatusProperties) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]interface{})
	if asp.Dimensions != nil {
		objectMap["dimensions"] = asp.Dimensions
	}
	if asp.Status != nil {
		objectMap["status"] = asp.Status
	}
	if asp.Timestamp != nil {
		objectMap["timestamp"] = asp.Timestamp
	}
	return json.Marshal(objectMap)
}

// Availability metric availability specifies the time grain (aggregation interval or frequency) and the
// retention period for that time grain.
type Availability struct {
	// TimeGrain - the time grain specifies the aggregation interval for the metric. Expressed as a duration 'PT1M', 'P1D', etc.
	TimeGrain *string `json:"timeGrain,omitempty"`
	// Retention - the retention period for the metric at the specified timegrain.  Expressed as a duration 'PT1M', 'P1D', etc.
	Retention *string `json:"retention,omitempty"`
}

// BaselineMetadata represents a baseline metadata value.
type BaselineMetadata struct {
	// Name - Name of the baseline metadata.
	Name *string `json:"name,omitempty"`
	// Value - Value of the baseline metadata.
	Value *string `json:"value,omitempty"`
}

// BaselinesProperties the response to a metric baselines query.
type BaselinesProperties struct {
	// Timespan - The timespan for which the data was retrieved. Its value consists of two datetimes concatenated, separated by '/'.  This may be adjusted in the future and returned back from what was originally requested.
	Timespan *string `json:"timespan,omitempty"`
	// Interval - The interval (window size) for which the metric data was returned in.  This may be adjusted in the future and returned back from what was originally requested.  This is not present if a metadata request was made.
	Interval *string `json:"interval,omitempty"`
	// Namespace - The namespace of the metrics been queried.
	Namespace *string `json:"namespace,omitempty"`
	// Baselines - The baseline for each time series that was queried.
	Baselines *[]TimeSeriesBaseline `json:"baselines,omitempty"`
}

// BaselinesResponse a list of metric baselines.
type BaselinesResponse struct {
	autorest.Response `json:"-"`
	// Value - The list of metric baselines.
	Value *[]SingleMetricBaseline `json:"value,omitempty"`
}

// Criteria criterion to filter metrics.
type Criteria struct {
	// Operator - the criteria operator. Possible values include: 'OperatorEquals', 'OperatorGreaterThan', 'OperatorGreaterThanOrEqual', 'OperatorLessThan', 'OperatorLessThanOrEqual'
	Operator Operator `json:"operator,omitempty"`
	// Threshold - the criteria threshold value that activates the alert.
	Threshold *float64 `json:"threshold,omitempty"`
	// AdditionalProperties - Unmatched properties from the message are deserialized this collection
	AdditionalProperties map[string]interface{} `json:""`
	// Name - Name of the criteria.
	Name *string `json:"name,omitempty"`
	// MetricName - Name of the metric.
	MetricName *string `json:"metricName,omitempty"`
	// MetricNamespace - Namespace of the metric.
	MetricNamespace *string `json:"metricNamespace,omitempty"`
	// TimeAggregation - the criteria time aggregation types. Possible values include: 'AggregationTypeEnumAverage', 'AggregationTypeEnumCount', 'AggregationTypeEnumMinimum', 'AggregationTypeEnumMaximum', 'AggregationTypeEnumTotal'
	TimeAggregation AggregationTypeEnum `json:"timeAggregation,omitempty"`
	// Dimensions - List of dimension conditions.
	Dimensions *[]Dimension `json:"dimensions,omitempty"`
	// SkipMetricValidation - Allows creating an alert rule on a custom metric that isn't yet emitted, by causing the metric validation to be skipped.
	SkipMetricValidation *bool `json:"skipMetricValidation,omitempty"`
	// CriterionType - Possible values include: 'CriterionTypeMultiMetricCriteria', 'CriterionTypeStaticThresholdCriterion', 'CriterionTypeDynamicThresholdCriterion'
	CriterionType CriterionType `json:"criterionType,omitempty"`
}

// MarshalJSON is the custom marshaler for Criteria.
func (c Criteria) MarshalJSON() ([]byte, error) {
	c.CriterionType = CriterionTypeStaticThresholdCriterion
	objectMap := make(map[string]interface{})
	if c.Operator != "" {
		objectMap["operator"] = c.Operator
	}
	if c.Threshold != nil {
		objectMap["threshold"] = c.Threshold
	}
	if c.Name != nil {
		objectMap["name"] = c.Name
	}
	if c.MetricName != nil {
		objectMap["metricName"] = c.MetricName
	}
	if c.MetricNamespace != nil {
		objectMap["metricNamespace"] = c.MetricNamespace
	}
	if c.TimeAggregation != "" {
		objectMap["timeAggregation"] = c.TimeAggregation
	}
	if c.Dimensions != nil {
		objectMap["dimensions"] = c.Dimensions
	}
	if c.SkipMetricValidation != nil {
		objectMap["skipMetricValidation"] = c.SkipMetricValidation
	}
	if c.CriterionType != "" {
		objectMap["criterionType"] = c.CriterionType
	}
	for k, v := range c.AdditionalProperties {
		objectMap[k] = v
	}
	return json.Marshal(objectMap)
}

// AsCriteria is the BasicMultiMetricCriteria implementation for Criteria.
func (c Criteria) AsCriteria() (*Criteria, bool) {
	return &c, true
}

// AsDynamicMetricCriteria is the BasicMultiMetricCriteria implementation for Criteria.
func (c Criteria) AsDynamicMetricCriteria() (*DynamicMetricCriteria, bool) {
	return nil, false
}

// AsMultiMetricCriteria is the BasicMultiMetricCriteria implementation for Criteria.
func (c Criteria) AsMultiMetricCriteria() (*MultiMetricCriteria, bool) {
	return nil, false
}

// AsBasicMultiMetricCriteria is the BasicMultiMetricCriteria implementation for Criteria.
func (c Criteria) AsBasicMultiMetricCriteria() (BasicMultiMetricCriteria, bool) {
	return &c, true
}

// UnmarshalJSON is the custom unmarshaler for Criteria struct.
func (c *Criteria) 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 "operator":
			if v != nil {
				var operator Operator
				err = json.Unmarshal(*v, &operator)
				if err != nil {
					return err
				}
				c.Operator = operator
			}
		case "threshold":
			if v != nil {
				var threshold float64
				err = json.Unmarshal(*v, &threshold)
				if err != nil {
					return err
				}
				c.Threshold = &threshold
			}
		default:
			if v != nil {
				var additionalProperties interface{}
				err = json.Unmarshal(*v, &additionalProperties)
				if err != nil {
					return err
				}
				if c.AdditionalProperties == nil {
					c.AdditionalProperties = make(map[string]interface{})
				}
				c.AdditionalProperties[k] = additionalProperties
			}
		case "name":
			if v != nil {
				var name string
				err = json.Unmarshal(*v, &name)
				if err != nil {
					return err
				}
				c.Name = &name
			}
		case "metricName":
			if v != nil {
				var metricName string
				err = json.Unmarshal(*v, &metricName)
				if err != nil {
					return err
				}
				c.MetricName = &metricName
			}
		case "metricNamespace":
			if v != nil {
				var metricNamespace string
				err = json.Unmarshal(*v, &metricNamespace)
				if err != nil {
					return err
				}
				c.MetricNamespace = &metricNamespace
			}
		case "timeAggregation":
			if v != nil {
				var timeAggregation AggregationTypeEnum
				err = json.Unmarshal(*v, &timeAggregation)
				if err != nil {
					return err
				}
				c.TimeAggregation = timeAggregation
			}
		case "dimensions":
			if v != nil {
				var dimensions []Dimension
				err = json.Unmarshal(*v, &dimensions)
				if err != nil {
					return err
				}
				c.Dimensions = &dimensions
			}
		case "skipMetricValidation":
			if v != nil {
				var skipMetricValidation bool
				err = json.Unmarshal(*v, &skipMetricValidation)
				if err != nil {
					return err
				}
				c.SkipMetricValidation = &skipMetricValidation
			}
		case "criterionType":
			if v != nil {
				var criterionType CriterionType
				err = json.Unmarshal(*v, &criterionType)
				if err != nil {
					return err
				}
				c.CriterionType = criterionType
			}
		}
	}

	return nil
}

// Definition metric definition class specifies the metadata for a metric.
type Definition struct {
	// IsDimensionRequired - Flag to indicate whether the dimension is required.
	IsDimensionRequired *bool `json:"isDimensionRequired,omitempty"`
	// ResourceID - the resource identifier of the resource that emitted the metric.
	ResourceID *string `json:"resourceId,omitempty"`
	// Namespace - the namespace the metric belongs to.
	Namespace *string `json:"namespace,omitempty"`
	// Name - the name and the display name of the metric, i.e. it is a localizable string.
	Name *LocalizableString `json:"name,omitempty"`
	// DisplayDescription - Detailed description of this metric.
	DisplayDescription *string `json:"displayDescription,omitempty"`
	// Category - Custom category name for this metric.
	Category *string `json:"category,omitempty"`
	// MetricClass - The class of the metric. Possible values include: 'MetricClassAvailability', 'MetricClassTransactions', 'MetricClassErrors', 'MetricClassLatency', 'MetricClassSaturation'
	MetricClass MetricClass `json:"metricClass,omitempty"`
	// Unit - the unit of the metric. Possible values include: 'MetricUnitCount', 'MetricUnitBytes', 'MetricUnitSeconds', 'MetricUnitCountPerSecond', 'MetricUnitBytesPerSecond', 'MetricUnitPercent', 'MetricUnitMilliSeconds', 'MetricUnitByteSeconds', 'MetricUnitUnspecified', 'MetricUnitCores', 'MetricUnitMilliCores', 'MetricUnitNanoCores', 'MetricUnitBitsPerSecond'
	Unit MetricUnit `json:"unit,omitempty"`
	// PrimaryAggregationType - the primary aggregation type value defining how to use the values for display. Possible values include: 'None', 'Average', 'Count', 'Minimum', 'Maximum', 'Total'
	PrimaryAggregationType AggregationType `json:"primaryAggregationType,omitempty"`
	// SupportedAggregationTypes - the collection of what aggregation types are supported.
	SupportedAggregationTypes *[]AggregationType `json:"supportedAggregationTypes,omitempty"`
	// MetricAvailabilities - the collection of what aggregation intervals are available to be queried.
	MetricAvailabilities *[]Availability `json:"metricAvailabilities,omitempty"`
	// ID - the resource identifier of the metric definition.
	ID *string `json:"id,omitempty"`
	// Dimensions - the name and the display name of the dimension, i.e. it is a localizable string.
	Dimensions *[]LocalizableString `json:"dimensions,omitempty"`
}

// DefinitionCollection represents collection of metric definitions.
type DefinitionCollection struct {
	autorest.Response `json:"-"`
	// Value - the values for the metric definitions.
	Value *[]Definition `json:"value,omitempty"`
}

// Dimension specifies a metric dimension.
type Dimension struct {
	// Name - Name of the dimension.
	Name *string `json:"name,omitempty"`
	// Operator - the dimension operator. Only 'Include' and 'Exclude' are supported
	Operator *string `json:"operator,omitempty"`
	// Values - list of dimension values.
	Values *[]string `json:"values,omitempty"`
}

// DimensionProperties type of operation: get, read, delete, etc.
type DimensionProperties struct {
	// Name - Name of dimension.
	Name *string `json:"name,omitempty"`
	// DisplayName - Display name of dimension.
	DisplayName *string `json:"displayName,omitempty"`
	// ToBeExportedForShoebox - Legacy usage, should not set.
	ToBeExportedForShoebox *bool `json:"toBeExportedForShoebox,omitempty"`
	// IsHidden - When set, the dimension is hidden from the customer, used in conjunction with the defaultDimensionValues field below
	IsHidden *bool `json:"isHidden,omitempty"`
	// DefaultDimensionValues - Default dimension value to be sent down for the hidden dimension during query
	DefaultDimensionValues interface{} `json:"defaultDimensionValues,omitempty"`
}

// DynamicMetricCriteria criterion for dynamic threshold.
type DynamicMetricCriteria struct {
	// Operator - The operator used to compare the metric value against the threshold. Possible values include: 'GreaterThan', 'LessThan', 'GreaterOrLessThan'
	Operator DynamicThresholdOperator `json:"operator,omitempty"`
	// AlertSensitivity - The extent of deviation required to trigger an alert. This will affect how tight the threshold is to the metric series pattern. Possible values include: 'DynamicThresholdSensitivityLow', 'DynamicThresholdSensitivityMedium', 'DynamicThresholdSensitivityHigh'
	AlertSensitivity DynamicThresholdSensitivity `json:"alertSensitivity,omitempty"`
	// FailingPeriods - The minimum number of violations required within the selected lookback time window required to raise an alert.
	FailingPeriods *DynamicThresholdFailingPeriods `json:"failingPeriods,omitempty"`
	// IgnoreDataBefore - Use this option to set the date from which to start learning the metric historical data and calculate the dynamic thresholds (in ISO8601 format)
	IgnoreDataBefore *date.Time `json:"ignoreDataBefore,omitempty"`
	// AdditionalProperties - Unmatched properties from the message are deserialized this collection
	AdditionalProperties map[string]interface{} `json:""`
	// Name - Name of the criteria.
	Name *string `json:"name,omitempty"`
	// MetricName - Name of the metric.
	MetricName *string `json:"metricName,omitempty"`
	// MetricNamespace - Namespace of the metric.
	MetricNamespace *string `json:"metricNamespace,omitempty"`
	// TimeAggregation - the criteria time aggregation types. Possible values include: 'AggregationTypeEnumAverage', 'AggregationTypeEnumCount', 'AggregationTypeEnumMinimum', 'AggregationTypeEnumMaximum', 'AggregationTypeEnumTotal'
	TimeAggregation AggregationTypeEnum `json:"timeAggregation,omitempty"`
	// Dimensions - List of dimension conditions.
	Dimensions *[]Dimension `json:"dimensions,omitempty"`
	// SkipMetricValidation - Allows creating an alert rule on a custom metric that isn't yet emitted, by causing the metric validation to be skipped.
	SkipMetricValidation *bool `json:"skipMetricValidation,omitempty"`
	// CriterionType - Possible values include: 'CriterionTypeMultiMetricCriteria', 'CriterionTypeStaticThresholdCriterion', 'CriterionTypeDynamicThresholdCriterion'
	CriterionType CriterionType `json:"criterionType,omitempty"`
}

// MarshalJSON is the custom marshaler for DynamicMetricCriteria.
func (dmc DynamicMetricCriteria) MarshalJSON() ([]byte, error) {
	dmc.CriterionType = CriterionTypeDynamicThresholdCriterion
	objectMap := make(map[string]interface{})
	if dmc.Operator != "" {
		objectMap["operator"] = dmc.Operator
	}
	if dmc.AlertSensitivity != "" {
		objectMap["alertSensitivity"] = dmc.AlertSensitivity
	}
	if dmc.FailingPeriods != nil {
		objectMap["failingPeriods"] = dmc.FailingPeriods
	}
	if dmc.IgnoreDataBefore != nil {
		objectMap["ignoreDataBefore"] = dmc.IgnoreDataBefore
	}
	if dmc.Name != nil {
		objectMap["name"] = dmc.Name
	}
	if dmc.MetricName != nil {
		objectMap["metricName"] = dmc.MetricName
	}
	if dmc.MetricNamespace != nil {
		objectMap["metricNamespace"] = dmc.MetricNamespace
	}
	if dmc.TimeAggregation != "" {
		objectMap["timeAggregation"] = dmc.TimeAggregation
	}
	if dmc.Dimensions != nil {
		objectMap["dimensions"] = dmc.Dimensions
	}
	if dmc.SkipMetricValidation != nil {
		objectMap["skipMetricValidation"] = dmc.SkipMetricValidation
	}
	if dmc.CriterionType != "" {
		objectMap["criterionType"] = dmc.CriterionType
	}
	for k, v := range dmc.AdditionalProperties {
		objectMap[k] = v
	}
	return json.Marshal(objectMap)
}

// AsCriteria is the BasicMultiMetricCriteria implementation for DynamicMetricCriteria.
func (dmc DynamicMetricCriteria) AsCriteria() (*Criteria, bool) {
	return nil, false
}

// AsDynamicMetricCriteria is the BasicMultiMetricCriteria implementation for DynamicMetricCriteria.
func (dmc DynamicMetricCriteria) AsDynamicMetricCriteria() (*DynamicMetricCriteria, bool) {
	return &dmc, true
}

// AsMultiMetricCriteria is the BasicMultiMetricCriteria implementation for DynamicMetricCriteria.
func (dmc DynamicMetricCriteria) AsMultiMetricCriteria() (*MultiMetricCriteria, bool) {
	return nil, false
}

// AsBasicMultiMetricCriteria is the BasicMultiMetricCriteria implementation for DynamicMetricCriteria.
func (dmc DynamicMetricCriteria) AsBasicMultiMetricCriteria() (BasicMultiMetricCriteria, bool) {
	return &dmc, true
}

// UnmarshalJSON is the custom unmarshaler for DynamicMetricCriteria struct.
func (dmc *DynamicMetricCriteria) 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 "operator":
			if v != nil {
				var operator DynamicThresholdOperator
				err = json.Unmarshal(*v, &operator)
				if err != nil {
					return err
				}
				dmc.Operator = operator
			}
		case "alertSensitivity":
			if v != nil {
				var alertSensitivity DynamicThresholdSensitivity
				err = json.Unmarshal(*v, &alertSensitivity)
				if err != nil {
					return err
				}
				dmc.AlertSensitivity = alertSensitivity
			}
		case "failingPeriods":
			if v != nil {
				var failingPeriods DynamicThresholdFailingPeriods
				err = json.Unmarshal(*v, &failingPeriods)
				if err != nil {
					return err
				}
				dmc.FailingPeriods = &failingPeriods
			}
		case "ignoreDataBefore":
			if v != nil {
				var ignoreDataBefore date.Time
				err = json.Unmarshal(*v, &ignoreDataBefore)
				if err != nil {
					return err
				}
				dmc.IgnoreDataBefore = &ignoreDataBefore
			}
		default:
			if v != nil {
				var additionalProperties interface{}
				err = json.Unmarshal(*v, &additionalProperties)
				if err != nil {
					return err
				}
				if dmc.AdditionalProperties == nil {
					dmc.AdditionalProperties = make(map[string]interface{})
				}
				dmc.AdditionalProperties[k] = additionalProperties
			}
		case "name":
			if v != nil {
				var name string
				err = json.Unmarshal(*v, &name)
				if err != nil {
					return err
				}
				dmc.Name = &name
			}
		case "metricName":
			if v != nil {
				var metricName string
				err = json.Unmarshal(*v, &metricName)
				if err != nil {
					return err
				}
				dmc.MetricName = &metricName
			}
		case "metricNamespace":
			if v != nil {
				var metricNamespace string
				err = json.Unmarshal(*v, &metricNamespace)
				if err != nil {
					return err
				}
				dmc.MetricNamespace = &metricNamespace
			}
		case "timeAggregation":
			if v != nil {
				var timeAggregation AggregationTypeEnum
				err = json.Unmarshal(*v, &timeAggregation)
				if err != nil {
					return err
				}
				dmc.TimeAggregation = timeAggregation
			}
		case "dimensions":
			if v != nil {
				var dimensions []Dimension
				err = json.Unmarshal(*v, &dimensions)
				if err != nil {
					return err
				}
				dmc.Dimensions = &dimensions
			}
		case "skipMetricValidation":
			if v != nil {
				var skipMetricValidation bool
				err = json.Unmarshal(*v, &skipMetricValidation)
				if err != nil {
					return err
				}
				dmc.SkipMetricValidation = &skipMetricValidation
			}
		case "criterionType":
			if v != nil {
				var criterionType CriterionType
				err = json.Unmarshal(*v, &criterionType)
				if err != nil {
					return err
				}
				dmc.CriterionType = criterionType
			}
		}
	}

	return nil
}

// DynamicThresholdFailingPeriods the minimum number of violations required within the selected lookback
// time window required to raise an alert.
type DynamicThresholdFailingPeriods struct {
	// NumberOfEvaluationPeriods - The number of aggregated lookback points. The lookback time window is calculated based on the aggregation granularity (windowSize) and the selected number of aggregated points.
	NumberOfEvaluationPeriods *float64 `json:"numberOfEvaluationPeriods,omitempty"`
	// MinFailingPeriodsToAlert - The number of violations to trigger an alert. Should be smaller or equal to numberOfEvaluationPeriods.
	MinFailingPeriodsToAlert *float64 `json:"minFailingPeriodsToAlert,omitempty"`
}

// ErrorContract common error response for all Azure Resource Manager APIs to return error details for
// failed operations. (This also follows the OData error response format.)
type ErrorContract struct {
	// Error - The error object.
	Error *ErrorResponse `json:"error,omitempty"`
}

// ErrorResponse describes the format of Error response.
type ErrorResponse struct {
	// Code - Error code
	Code *string `json:"code,omitempty"`
	// Message - Error message indicating why the operation failed.
	Message *string `json:"message,omitempty"`
}

// LocalizableString the localizable string class.
type LocalizableString struct {
	// Value - the invariant value.
	Value *string `json:"value,omitempty"`
	// LocalizedValue - the locale specific value.
	LocalizedValue *string `json:"localizedValue,omitempty"`
}

// LogSpecification log specification of operation.
type LogSpecification struct {
	// Name - Name of log specification.
	Name *string `json:"name,omitempty"`
	// DisplayName - Display name of log specification.
	DisplayName *string `json:"displayName,omitempty"`
	// BlobDuration - Blob duration of specification.
	BlobDuration *string `json:"blobDuration,omitempty"`
}

// MetadataValue represents a metric metadata value.
type MetadataValue struct {
	// Name - the name of the metadata.
	Name *LocalizableString `json:"name,omitempty"`
	// Value - the value of the metadata.
	Value *string `json:"value,omitempty"`
}

// Metric the result data of a query.
type Metric struct {
	// ID - the metric Id.
	ID *string `json:"id,omitempty"`
	// Type - the resource type of the metric resource.
	Type *string `json:"type,omitempty"`
	// Name - the name and the display name of the metric, i.e. it is localizable string.
	Name *LocalizableString `json:"name,omitempty"`
	// DisplayDescription - Detailed description of this metric.
	DisplayDescription *string `json:"displayDescription,omitempty"`
	// ErrorCode - 'Success' or the error details on query failures for this metric.
	ErrorCode *string `json:"errorCode,omitempty"`
	// ErrorMessage - Error message encountered querying this specific metric.
	ErrorMessage *string `json:"errorMessage,omitempty"`
	// Unit - The unit of the metric. Possible values include: 'UnitCount', 'UnitBytes', 'UnitSeconds', 'UnitCountPerSecond', 'UnitBytesPerSecond', 'UnitPercent', 'UnitMilliSeconds', 'UnitByteSeconds', 'UnitUnspecified', 'UnitCores', 'UnitMilliCores', 'UnitNanoCores', 'UnitBitsPerSecond'
	Unit Unit `json:"unit,omitempty"`
	// Timeseries - the time series returned when a data query is performed.
	Timeseries *[]TimeSeriesElement `json:"timeseries,omitempty"`
}

// BasicMultiMetricCriteria the types of conditions for a multi resource alert.
type BasicMultiMetricCriteria interface {
	AsCriteria() (*Criteria, bool)
	AsDynamicMetricCriteria() (*DynamicMetricCriteria, bool)
	AsMultiMetricCriteria() (*MultiMetricCriteria, bool)
}

// MultiMetricCriteria the types of conditions for a multi resource alert.
type MultiMetricCriteria struct {
	// AdditionalProperties - Unmatched properties from the message are deserialized this collection
	AdditionalProperties map[string]interface{} `json:""`
	// Name - Name of the criteria.
	Name *string `json:"name,omitempty"`
	// MetricName - Name of the metric.
	MetricName *string `json:"metricName,omitempty"`
	// MetricNamespace - Namespace of the metric.
	MetricNamespace *string `json:"metricNamespace,omitempty"`
	// TimeAggregation - the criteria time aggregation types. Possible values include: 'AggregationTypeEnumAverage', 'AggregationTypeEnumCount', 'AggregationTypeEnumMinimum', 'AggregationTypeEnumMaximum', 'AggregationTypeEnumTotal'
	TimeAggregation AggregationTypeEnum `json:"timeAggregation,omitempty"`
	// Dimensions - List of dimension conditions.
	Dimensions *[]Dimension `json:"dimensions,omitempty"`
	// SkipMetricValidation - Allows creating an alert rule on a custom metric that isn't yet emitted, by causing the metric validation to be skipped.
	SkipMetricValidation *bool `json:"skipMetricValidation,omitempty"`
	// CriterionType - Possible values include: 'CriterionTypeMultiMetricCriteria', 'CriterionTypeStaticThresholdCriterion', 'CriterionTypeDynamicThresholdCriterion'
	CriterionType CriterionType `json:"criterionType,omitempty"`
}

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

	switch m["criterionType"] {
	case string(CriterionTypeStaticThresholdCriterion):
		var c Criteria
		err := json.Unmarshal(body, &c)
		return c, err
	case string(CriterionTypeDynamicThresholdCriterion):
		var dmc DynamicMetricCriteria
		err := json.Unmarshal(body, &dmc)
		return dmc, err
	default:
		var mmc MultiMetricCriteria
		err := json.Unmarshal(body, &mmc)
		return mmc, err
	}
}
func unmarshalBasicMultiMetricCriteriaArray(body []byte) ([]BasicMultiMetricCriteria, error) {
	var rawMessages []*json.RawMessage
	err := json.Unmarshal(body, &rawMessages)
	if err != nil {
		return nil, err
	}

	mmcArray := make([]BasicMultiMetricCriteria, len(rawMessages))

	for index, rawMessage := range rawMessages {
		mmc, err := unmarshalBasicMultiMetricCriteria(*rawMessage)
		if err != nil {
			return nil, err
		}
		mmcArray[index] = mmc
	}
	return mmcArray, nil
}

// MarshalJSON is the custom marshaler for MultiMetricCriteria.
func (mmc MultiMetricCriteria) MarshalJSON() ([]byte, error) {
	mmc.CriterionType = CriterionTypeMultiMetricCriteria
	objectMap := make(map[string]interface{})
	if mmc.Name != nil {
		objectMap["name"] = mmc.Name
	}
	if mmc.MetricName != nil {
		objectMap["metricName"] = mmc.MetricName
	}
	if mmc.MetricNamespace != nil {
		objectMap["metricNamespace"] = mmc.MetricNamespace
	}
	if mmc.TimeAggregation != "" {
		objectMap["timeAggregation"] = mmc.TimeAggregation
	}
	if mmc.Dimensions != nil {
		objectMap["dimensions"] = mmc.Dimensions
	}
	if mmc.SkipMetricValidation != nil {
		objectMap["skipMetricValidation"] = mmc.SkipMetricValidation
	}
	if mmc.CriterionType != "" {
		objectMap["criterionType"] = mmc.CriterionType
	}
	for k, v := range mmc.AdditionalProperties {
		objectMap[k] = v
	}
	return json.Marshal(objectMap)
}

// AsCriteria is the BasicMultiMetricCriteria implementation for MultiMetricCriteria.
func (mmc MultiMetricCriteria) AsCriteria() (*Criteria, bool) {
	return nil, false
}

// AsDynamicMetricCriteria is the BasicMultiMetricCriteria implementation for MultiMetricCriteria.
func (mmc MultiMetricCriteria) AsDynamicMetricCriteria() (*DynamicMetricCriteria, bool) {
	return nil, false
}

// AsMultiMetricCriteria is the BasicMultiMetricCriteria implementation for MultiMetricCriteria.
func (mmc MultiMetricCriteria) AsMultiMetricCriteria() (*MultiMetricCriteria, bool) {
	return &mmc, true
}

// AsBasicMultiMetricCriteria is the BasicMultiMetricCriteria implementation for MultiMetricCriteria.
func (mmc MultiMetricCriteria) AsBasicMultiMetricCriteria() (BasicMultiMetricCriteria, bool) {
	return &mmc, true
}

// UnmarshalJSON is the custom unmarshaler for MultiMetricCriteria struct.
func (mmc *MultiMetricCriteria) 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 {
		default:
			if v != nil {
				var additionalProperties interface{}
				err = json.Unmarshal(*v, &additionalProperties)
				if err != nil {
					return err
				}
				if mmc.AdditionalProperties == nil {
					mmc.AdditionalProperties = make(map[string]interface{})
				}
				mmc.AdditionalProperties[k] = additionalProperties
			}
		case "name":
			if v != nil {
				var name string
				err = json.Unmarshal(*v, &name)
				if err != nil {
					return err
				}
				mmc.Name = &name
			}
		case "metricName":
			if v != nil {
				var metricName string
				err = json.Unmarshal(*v, &metricName)
				if err != nil {
					return err
				}
				mmc.MetricName = &metricName
			}
		case "metricNamespace":
			if v != nil {
				var metricNamespace string
				err = json.Unmarshal(*v, &metricNamespace)
				if err != nil {
					return err
				}
				mmc.MetricNamespace = &metricNamespace
			}
		case "timeAggregation":
			if v != nil {
				var timeAggregation AggregationTypeEnum
				err = json.Unmarshal(*v, &timeAggregation)
				if err != nil {
					return err
				}
				mmc.TimeAggregation = timeAggregation
			}
		case "dimensions":
			if v != nil {
				var dimensions []Dimension
				err = json.Unmarshal(*v, &dimensions)
				if err != nil {
					return err
				}
				mmc.Dimensions = &dimensions
			}
		case "skipMetricValidation":
			if v != nil {
				var skipMetricValidation bool
				err = json.Unmarshal(*v, &skipMetricValidation)
				if err != nil {
					return err
				}
				mmc.SkipMetricValidation = &skipMetricValidation
			}
		case "criterionType":
			if v != nil {
				var criterionType CriterionType
				err = json.Unmarshal(*v, &criterionType)
				if err != nil {
					return err
				}
				mmc.CriterionType = criterionType
			}
		}
	}

	return nil
}

// Namespace metric namespace class specifies the metadata for a metric namespace.
type Namespace struct {
	// ID - The ID of the metric namespace.
	ID *string `json:"id,omitempty"`
	// Type - The type of the namespace.
	Type *string `json:"type,omitempty"`
	// Name - The escaped name of the namespace.
	Name *string `json:"name,omitempty"`
	// Classification - Kind of namespace. Possible values include: 'Platform', 'Custom', 'Qos'
	Classification NamespaceClassification `json:"classification,omitempty"`
	// Properties - Properties which include the fully qualified namespace name.
	Properties *NamespaceName `json:"properties,omitempty"`
}

// NamespaceCollection represents collection of metric namespaces.
type NamespaceCollection struct {
	autorest.Response `json:"-"`
	// Value - The values for the metric namespaces.
	Value *[]Namespace `json:"value,omitempty"`
}

// NamespaceName the fully qualified metric namespace name.
type NamespaceName struct {
	// MetricNamespaceName - The metric namespace name.
	MetricNamespaceName *string `json:"metricNamespaceName,omitempty"`
}

// Operation microsoft Insights API operation definition.
type Operation struct {
	// Name - Operation name: {provider}/{resource}/{operation}
	Name *string `json:"name,omitempty"`
	// IsDataAction - Property to specify whether the action is a data action.
	IsDataAction *bool `json:"isDataAction,omitempty"`
	// Display - Display metadata associated with the operation.
	Display *OperationDisplay `json:"display,omitempty"`
	// OperationProperties - Properties of operation, include metric specifications.
	*OperationProperties `json:"properties,omitempty"`
}

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

// UnmarshalJSON is the custom unmarshaler for Operation struct.
func (o *Operation) 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 "name":
			if v != nil {
				var name string
				err = json.Unmarshal(*v, &name)
				if err != nil {
					return err
				}
				o.Name = &name
			}
		case "isDataAction":
			if v != nil {
				var isDataAction bool
				err = json.Unmarshal(*v, &isDataAction)
				if err != nil {
					return err
				}
				o.IsDataAction = &isDataAction
			}
		case "display":
			if v != nil {
				var display OperationDisplay
				err = json.Unmarshal(*v, &display)
				if err != nil {
					return err
				}
				o.Display = &display
			}
		case "properties":
			if v != nil {
				var operationProperties OperationProperties
				err = json.Unmarshal(*v, &operationProperties)
				if err != nil {
					return err
				}
				o.OperationProperties = &operationProperties
			}
		}
	}

	return nil
}

// OperationDisplay display metadata associated with the operation.
type OperationDisplay struct {
	// Publisher - The publisher of this operation.
	Publisher *string `json:"publisher,omitempty"`
	// Provider - Service provider: Microsoft.Insights
	Provider *string `json:"provider,omitempty"`
	// Resource - Resource on which the operation is performed: AlertRules, Autoscale, etc.
	Resource *string `json:"resource,omitempty"`
	// Operation - Operation type: Read, write, delete, etc.
	Operation *string `json:"operation,omitempty"`
	// Description - The description of the operation.
	Description *string `json:"description,omitempty"`
}

// OperationListResult result of the request to list Microsoft.Insights 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 - List of operations supported by the Microsoft.Insights provider.
	Value *[]Operation `json:"value,omitempty"`
	// NextLink - URL to get the next set of operation list results if there are any.
	NextLink *string `json:"nextLink,omitempty"`
}

// OperationProperties properties of operation, include metric specifications.
type OperationProperties struct {
	// ServiceSpecification - One property of operation, include metric specifications.
	ServiceSpecification *ServiceSpecification `json:"serviceSpecification,omitempty"`
}

// Resource an azure resource object
type Resource struct {
	// ID - READ-ONLY; Azure resource Id
	ID *string `json:"id,omitempty"`
	// Name - READ-ONLY; Azure resource name
	Name *string `json:"name,omitempty"`
	// Type - READ-ONLY; Azure resource type
	Type *string `json:"type,omitempty"`
	// Location - Resource location
	Location *string `json:"location,omitempty"`
	// Tags - 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{})
	if r.Location != nil {
		objectMap["location"] = r.Location
	}
	if r.Tags != nil {
		objectMap["tags"] = r.Tags
	}
	return json.Marshal(objectMap)
}

// Response the response to a metrics query.
type Response struct {
	autorest.Response `json:"-"`
	// Cost - The integer value representing the relative cost of the query.
	Cost *float64 `json:"cost,omitempty"`
	// Timespan - The timespan for which the data was retrieved. Its value consists of two datetimes concatenated, separated by '/'.  This may be adjusted in the future and returned back from what was originally requested.
	Timespan *string `json:"timespan,omitempty"`
	// Interval - The interval (window size) for which the metric data was returned in.  This may be adjusted in the future and returned back from what was originally requested.  This is not present if a metadata request was made.
	Interval *string `json:"interval,omitempty"`
	// Namespace - The namespace of the metrics being queried
	Namespace *string `json:"namespace,omitempty"`
	// Resourceregion - The region of the resource being queried for metrics.
	Resourceregion *string `json:"resourceregion,omitempty"`
	// Value - the value of the collection.
	Value *[]Metric `json:"value,omitempty"`
}

// ServiceSpecification one property of operation, include log specifications.
type ServiceSpecification struct {
	// LogSpecifications - Log specifications of operation.
	LogSpecifications *[]LogSpecification `json:"logSpecifications,omitempty"`
	// MetricSpecifications - Metric specifications of operation.
	MetricSpecifications *[]Specification `json:"metricSpecifications,omitempty"`
	// LegacyMetricSpecifications - Legacy Metric specifications for operation. Deprecated, do not use.
	LegacyMetricSpecifications interface{} `json:"legacyMetricSpecifications,omitempty"`
}

// SingleBaseline the baseline values for a single sensitivity value.
type SingleBaseline struct {
	// Sensitivity - the sensitivity of the baseline. Possible values include: 'Low', 'Medium', 'High'
	Sensitivity BaselineSensitivity `json:"sensitivity,omitempty"`
	// LowThresholds - The low thresholds of the baseline.
	LowThresholds *[]float64 `json:"lowThresholds,omitempty"`
	// HighThresholds - The high thresholds of the baseline.
	HighThresholds *[]float64 `json:"highThresholds,omitempty"`
}

// SingleDimension the metric dimension name and value.
type SingleDimension struct {
	// Name - Name of the dimension.
	Name *string `json:"name,omitempty"`
	// Value - Value of the dimension.
	Value *string `json:"value,omitempty"`
}

// SingleMetricBaseline the baseline results of a single metric.
type SingleMetricBaseline struct {
	// ID - The metric baseline Id.
	ID *string `json:"id,omitempty"`
	// Type - The resource type of the metric baseline resource.
	Type *string `json:"type,omitempty"`
	// Name - The name of the metric for which the baselines were retrieved.
	Name *string `json:"name,omitempty"`
	// BaselinesProperties - The metric baseline properties of the metric.
	*BaselinesProperties `json:"properties,omitempty"`
}

// MarshalJSON is the custom marshaler for SingleMetricBaseline.
func (smb SingleMetricBaseline) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]interface{})
	if smb.ID != nil {
		objectMap["id"] = smb.ID
	}
	if smb.Type != nil {
		objectMap["type"] = smb.Type
	}
	if smb.Name != nil {
		objectMap["name"] = smb.Name
	}
	if smb.BaselinesProperties != nil {
		objectMap["properties"] = smb.BaselinesProperties
	}
	return json.Marshal(objectMap)
}

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

	return nil
}

// Specification metric specification of operation.
type Specification struct {
	// Name - The name of the metric.
	Name *string `json:"name,omitempty"`
	// DisplayName - Display name of the metric.
	DisplayName *string `json:"displayName,omitempty"`
	// DisplayDescription - Display description of the metric.
	DisplayDescription *string `json:"displayDescription,omitempty"`
	// Unit - The metric unit. Possible values include: Count,Bytes,Seconds,Percent,CountPerSecond,BytesPerSecond,MilliSeconds,ByteSeconds,Unspecified,BitsPerSecond,Cores,MilliCores,NanoCores
	Unit *string `json:"unit,omitempty"`
	// AggregationType - The default metric aggregation type. Possible values include: Total,Average,Maximum,Minimum,Count
	AggregationType *string `json:"aggregationType,omitempty"`
	// SupportedAggregationTypes - The supported aggregation types for the metrics.
	SupportedAggregationTypes *[]string `json:"supportedAggregationTypes,omitempty"`
	// SupportedTimeGrainTypes - The supported time grain types for the metrics.
	SupportedTimeGrainTypes *[]string `json:"supportedTimeGrainTypes,omitempty"`
	// Availabilities - The supported time grain types for the metrics.
	Availabilities *[]string `json:"availabilities,omitempty"`
	// LockAggregationType - The metric lock aggregation type.
	LockAggregationType *string `json:"lockAggregationType,omitempty"`
	// Category - Category or type of metric.
	Category *string `json:"category,omitempty"`
	// Dimensions - The dimensions of metric.
	Dimensions *[]DimensionProperties `json:"dimensions,omitempty"`
	// FillGapWithZero - Property to specify whether to fill empty gaps with zero.
	FillGapWithZero *bool `json:"fillGapWithZero,omitempty"`
	// InternalMetricName - The internal metric name.
	InternalMetricName *string `json:"internalMetricName,omitempty"`
}

// SubscriptionScopeMetric the result data of a query.
type SubscriptionScopeMetric struct {
	// ID - the metric Id.
	ID *string `json:"id,omitempty"`
	// Type - the resource type of the metric resource.
	Type *string `json:"type,omitempty"`
	// Name - the name and the display name of the metric, i.e. it is localizable string.
	Name *LocalizableString `json:"name,omitempty"`
	// DisplayDescription - Detailed description of this metric.
	DisplayDescription *string `json:"displayDescription,omitempty"`
	// ErrorCode - 'Success' or the error details on query failures for this metric.
	ErrorCode *string `json:"errorCode,omitempty"`
	// ErrorMessage - Error message encountered querying this specific metric.
	ErrorMessage *string `json:"errorMessage,omitempty"`
	// Unit - The unit of the metric. Possible values include: 'MetricUnitCount', 'MetricUnitBytes', 'MetricUnitSeconds', 'MetricUnitCountPerSecond', 'MetricUnitBytesPerSecond', 'MetricUnitPercent', 'MetricUnitMilliSeconds', 'MetricUnitByteSeconds', 'MetricUnitUnspecified', 'MetricUnitCores', 'MetricUnitMilliCores', 'MetricUnitNanoCores', 'MetricUnitBitsPerSecond'
	Unit MetricUnit `json:"unit,omitempty"`
	// Timeseries - the time series returned when a data query is performed.
	Timeseries *[]TimeSeriesElement `json:"timeseries,omitempty"`
}

// SubscriptionScopeMetricDefinition metric definition class specifies the metadata for a metric.
type SubscriptionScopeMetricDefinition struct {
	// IsDimensionRequired - Flag to indicate whether the dimension is required.
	IsDimensionRequired *bool `json:"isDimensionRequired,omitempty"`
	// ResourceID - the resource identifier of the resource that emitted the metric.
	ResourceID *string `json:"resourceId,omitempty"`
	// Namespace - the namespace the metric belongs to.
	Namespace *string `json:"namespace,omitempty"`
	// Name - the name and the display name of the metric, i.e. it is a localizable string.
	Name *LocalizableString `json:"name,omitempty"`
	// DisplayDescription - Detailed description of this metric.
	DisplayDescription *string `json:"displayDescription,omitempty"`
	// Category - Custom category name for this metric.
	Category *string `json:"category,omitempty"`
	// MetricClass - The class of the metric. Possible values include: 'MetricClassAvailability', 'MetricClassTransactions', 'MetricClassErrors', 'MetricClassLatency', 'MetricClassSaturation'
	MetricClass MetricClass `json:"metricClass,omitempty"`
	// Unit - the unit of the metric. Possible values include: 'MetricUnitCount', 'MetricUnitBytes', 'MetricUnitSeconds', 'MetricUnitCountPerSecond', 'MetricUnitBytesPerSecond', 'MetricUnitPercent', 'MetricUnitMilliSeconds', 'MetricUnitByteSeconds', 'MetricUnitUnspecified', 'MetricUnitCores', 'MetricUnitMilliCores', 'MetricUnitNanoCores', 'MetricUnitBitsPerSecond'
	Unit MetricUnit `json:"unit,omitempty"`
	// PrimaryAggregationType - the primary aggregation type value defining how to use the values for display. Possible values include: 'MetricAggregationTypeNone', 'MetricAggregationTypeAverage', 'MetricAggregationTypeCount', 'MetricAggregationTypeMinimum', 'MetricAggregationTypeMaximum', 'MetricAggregationTypeTotal'
	PrimaryAggregationType MetricAggregationType `json:"primaryAggregationType,omitempty"`
	// SupportedAggregationTypes - the collection of what aggregation types are supported.
	SupportedAggregationTypes *[]MetricAggregationType `json:"supportedAggregationTypes,omitempty"`
	// MetricAvailabilities - the collection of what aggregation intervals are available to be queried.
	MetricAvailabilities *[]Availability `json:"metricAvailabilities,omitempty"`
	// ID - the resource identifier of the metric definition.
	ID *string `json:"id,omitempty"`
	// Dimensions - the name and the display name of the dimension, i.e. it is a localizable string.
	Dimensions *[]LocalizableString `json:"dimensions,omitempty"`
}

// SubscriptionScopeMetricDefinitionCollection represents collection of metric definitions.
type SubscriptionScopeMetricDefinitionCollection struct {
	autorest.Response `json:"-"`
	// Value - The values for the metric definitions.
	Value *[]SubscriptionScopeMetricDefinition `json:"value,omitempty"`
}

// SubscriptionScopeMetricResponse the response to a subscription scope metrics query.
type SubscriptionScopeMetricResponse struct {
	autorest.Response `json:"-"`
	// Cost - The integer value representing the relative cost of the query.
	Cost *float64 `json:"cost,omitempty"`
	// Timespan - The timespan for which the data was retrieved. Its value consists of two datetimes concatenated, separated by '/'.  This may be adjusted in the future and returned back from what was originally requested.
	Timespan *string `json:"timespan,omitempty"`
	// Interval - The interval (window size) for which the metric data was returned in.  This may be adjusted in the future and returned back from what was originally requested.  This is not present if a metadata request was made.
	Interval *string `json:"interval,omitempty"`
	// Namespace - The namespace of the metrics being queried
	Namespace *string `json:"namespace,omitempty"`
	// Resourceregion - The region of the resource being queried for metrics.
	Resourceregion *string `json:"resourceregion,omitempty"`
	// Value - the value of the collection.
	Value *[]SubscriptionScopeMetric `json:"value,omitempty"`
}

// SubscriptionScopeMetricsRequestBodyParameters query parameters can also be specified in the body,
// specifying the same parameter in both the body and query parameters will result in an error.
type SubscriptionScopeMetricsRequestBodyParameters struct {
	// Timespan - The timespan of the query. It is a string with the following format 'startDateTime_ISO/endDateTime_ISO'.
	Timespan *string `json:"timespan,omitempty"`
	// Interval - The interval (i.e. timegrain) of the query.
	Interval *string `json:"interval,omitempty"`
	// MetricNames - The names of the metrics (comma separated) to retrieve.
	MetricNames *string `json:"metricNames,omitempty"`
	// Aggregation - The list of aggregation types (comma separated) to retrieve.
	Aggregation *string `json:"aggregation,omitempty"`
	// Filter - The **$filter** is used to reduce the set of metric data returned.<br>Example:<br>Metric contains metadata A, B and C.<br>- Return all time series of C where A = a1 and B = b1 or b2<br>**$filter=A eq ‘a1’ and B eq ‘b1’ or B eq ‘b2’ and C eq ‘*’**<br>- Invalid variant:<br>**$filter=A eq ‘a1’ and B eq ‘b1’ and C eq ‘*’ or B = ‘b2’**<br>This is invalid because the logical or operator cannot separate two different metadata names.<br>- Return all time series where A = a1, B = b1 and C = c1:<br>**$filter=A eq ‘a1’ and B eq ‘b1’ and C eq ‘c1’**<br>- Return all time series where A = a1<br>**$filter=A eq ‘a1’ and B eq ‘*’ and C eq ‘*’**.
	Filter *string `json:"filter,omitempty"`
	// Top - The maximum number of records to retrieve.
	// Valid only if $filter is specified.
	// Defaults to 10.
	Top *int32 `json:"top,omitempty"`
	// OrderBy - The aggregation to use for sorting results and the direction of the sort.
	// Only one order can be specified.
	// Examples: sum asc.
	OrderBy *string `json:"orderBy,omitempty"`
	// RollUpBy - Dimension name(s) to rollup results by. For example if you only want to see metric values with a filter like 'City eq Seattle or City eq Tacoma' but don't want to see separate values for each city, you can specify 'RollUpBy=City' to see the results for Seattle and Tacoma rolled up into one timeseries.
	RollUpBy *string `json:"rollUpBy,omitempty"`
	// ResultType - Reduces the set of data collected. The syntax allowed depends on the operation. See the operation's description for details. Possible values include: 'Data', 'Metadata'
	ResultType MetricResultType `json:"resultType,omitempty"`
	// MetricNamespace - Metric namespace where the metrics you want reside.
	MetricNamespace *string `json:"metricNamespace,omitempty"`
	// AutoAdjustTimegrain - When set to true, if the timespan passed in is not supported by this metric, the API will return the result using the closest supported timespan. When set to false, an error is returned for invalid timespan parameters. Defaults to false.
	AutoAdjustTimegrain *bool `json:"autoAdjustTimegrain,omitempty"`
	// ValidateDimensions - When set to false, invalid filter parameter values will be ignored. When set to true, an error is returned for invalid filter parameters. Defaults to true.
	ValidateDimensions *bool `json:"validateDimensions,omitempty"`
}

// TimeSeriesBaseline the baseline values for a single time series.
type TimeSeriesBaseline struct {
	// Aggregation - The aggregation type of the metric.
	Aggregation *string `json:"aggregation,omitempty"`
	// Dimensions - The dimensions of this time series.
	Dimensions *[]SingleDimension `json:"dimensions,omitempty"`
	// Timestamps - The list of timestamps of the baselines.
	Timestamps *[]date.Time `json:"timestamps,omitempty"`
	// Data - The baseline values for each sensitivity.
	Data *[]SingleBaseline `json:"data,omitempty"`
	// MetadataValues - The baseline metadata values.
	MetadataValues *[]BaselineMetadata `json:"metadataValues,omitempty"`
}

// TimeSeriesElement a time series result type. The discriminator value is always TimeSeries in this case.
type TimeSeriesElement struct {
	// Metadatavalues - the metadata values returned if $filter was specified in the call.
	Metadatavalues *[]MetadataValue `json:"metadatavalues,omitempty"`
	// Data - An array of data points representing the metric values.  This is only returned if a result type of data is specified.
	Data *[]Value `json:"data,omitempty"`
}

// Value represents a metric value.
type Value struct {
	// TimeStamp - the timestamp for the metric value in ISO 8601 format.
	TimeStamp *date.Time `json:"timeStamp,omitempty"`
	// Average - the average value in the time range.
	Average *float64 `json:"average,omitempty"`
	// Minimum - the least value in the time range.
	Minimum *float64 `json:"minimum,omitempty"`
	// Maximum - the greatest value in the time range.
	Maximum *float64 `json:"maximum,omitempty"`
	// Total - the sum of all of the values in the time range.
	Total *float64 `json:"total,omitempty"`
	// Count - the number of samples in the time range. Can be used to determine the number of values that contributed to the average value.
	Count *float64 `json:"count,omitempty"`
}

// WebtestLocationAvailabilityCriteria specifies the metric alert rule criteria for a web test resource.
type WebtestLocationAvailabilityCriteria struct {
	// WebTestID - The Application Insights web test Id.
	WebTestID *string `json:"webTestId,omitempty"`
	// ComponentID - The Application Insights resource Id.
	ComponentID *string `json:"componentId,omitempty"`
	// FailedLocationCount - The number of failed locations.
	FailedLocationCount *float64 `json:"failedLocationCount,omitempty"`
	// AdditionalProperties - Unmatched properties from the message are deserialized this collection
	AdditionalProperties map[string]interface{} `json:""`
	// OdataType - Possible values include: 'OdataTypeMetricAlertCriteria', 'OdataTypeMicrosoftAzureMonitorSingleResourceMultipleMetricCriteria', 'OdataTypeMicrosoftAzureMonitorWebtestLocationAvailabilityCriteria', 'OdataTypeMicrosoftAzureMonitorMultipleResourceMultipleMetricCriteria'
	OdataType OdataType `json:"odata.type,omitempty"`
}

// MarshalJSON is the custom marshaler for WebtestLocationAvailabilityCriteria.
func (wlac WebtestLocationAvailabilityCriteria) MarshalJSON() ([]byte, error) {
	wlac.OdataType = OdataTypeMicrosoftAzureMonitorWebtestLocationAvailabilityCriteria
	objectMap := make(map[string]interface{})
	if wlac.WebTestID != nil {
		objectMap["webTestId"] = wlac.WebTestID
	}
	if wlac.ComponentID != nil {
		objectMap["componentId"] = wlac.ComponentID
	}
	if wlac.FailedLocationCount != nil {
		objectMap["failedLocationCount"] = wlac.FailedLocationCount
	}
	if wlac.OdataType != "" {
		objectMap["odata.type"] = wlac.OdataType
	}
	for k, v := range wlac.AdditionalProperties {
		objectMap[k] = v
	}
	return json.Marshal(objectMap)
}

// AsAlertSingleResourceMultipleMetricCriteria is the BasicAlertCriteria implementation for WebtestLocationAvailabilityCriteria.
func (wlac WebtestLocationAvailabilityCriteria) AsAlertSingleResourceMultipleMetricCriteria() (*AlertSingleResourceMultipleMetricCriteria, bool) {
	return nil, false
}

// AsWebtestLocationAvailabilityCriteria is the BasicAlertCriteria implementation for WebtestLocationAvailabilityCriteria.
func (wlac WebtestLocationAvailabilityCriteria) AsWebtestLocationAvailabilityCriteria() (*WebtestLocationAvailabilityCriteria, bool) {
	return &wlac, true
}

// AsAlertMultipleResourceMultipleMetricCriteria is the BasicAlertCriteria implementation for WebtestLocationAvailabilityCriteria.
func (wlac WebtestLocationAvailabilityCriteria) AsAlertMultipleResourceMultipleMetricCriteria() (*AlertMultipleResourceMultipleMetricCriteria, bool) {
	return nil, false
}

// AsAlertCriteria is the BasicAlertCriteria implementation for WebtestLocationAvailabilityCriteria.
func (wlac WebtestLocationAvailabilityCriteria) AsAlertCriteria() (*AlertCriteria, bool) {
	return nil, false
}

// AsBasicAlertCriteria is the BasicAlertCriteria implementation for WebtestLocationAvailabilityCriteria.
func (wlac WebtestLocationAvailabilityCriteria) AsBasicAlertCriteria() (BasicAlertCriteria, bool) {
	return &wlac, true
}

// UnmarshalJSON is the custom unmarshaler for WebtestLocationAvailabilityCriteria struct.
func (wlac *WebtestLocationAvailabilityCriteria) 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 "webTestId":
			if v != nil {
				var webTestID string
				err = json.Unmarshal(*v, &webTestID)
				if err != nil {
					return err
				}
				wlac.WebTestID = &webTestID
			}
		case "componentId":
			if v != nil {
				var componentID string
				err = json.Unmarshal(*v, &componentID)
				if err != nil {
					return err
				}
				wlac.ComponentID = &componentID
			}
		case "failedLocationCount":
			if v != nil {
				var failedLocationCount float64
				err = json.Unmarshal(*v, &failedLocationCount)
				if err != nil {
					return err
				}
				wlac.FailedLocationCount = &failedLocationCount
			}
		default:
			if v != nil {
				var additionalProperties interface{}
				err = json.Unmarshal(*v, &additionalProperties)
				if err != nil {
					return err
				}
				if wlac.AdditionalProperties == nil {
					wlac.AdditionalProperties = make(map[string]interface{})
				}
				wlac.AdditionalProperties[k] = additionalProperties
			}
		case "odata.type":
			if v != nil {
				var odataType OdataType
				err = json.Unmarshal(*v, &odataType)
				if err != nil {
					return err
				}
				wlac.OdataType = odataType
			}
		}
	}

	return nil
}
