package frontdoor

// Copyright (c) Microsoft and contributors.  All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//
// See the License for the specific language governing permissions and
// limitations under the License.
//
// 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/azure"
	"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/frontdoor/mgmt/2019-05-01/frontdoor"

// AzureAsyncOperationResult the response body contains the status of the specified asynchronous operation,
// indicating whether it has succeeded, is in progress, or has failed. Note that this status is distinct
// from the HTTP status code returned for the Get Operation Status operation itself. If the asynchronous
// operation succeeded, the response body includes the HTTP status code for the successful request. If the
// asynchronous operation failed, the response body includes the HTTP status code for the failed request
// and error information regarding the failure.
type AzureAsyncOperationResult struct {
	// Status - Status of the Azure async operation. Possible values are: 'InProgress', 'Succeeded', and 'Failed'. Possible values include: 'InProgress', 'Succeeded', 'Failed'
	Status NetworkOperationStatus `json:"status,omitempty"`
	Error  *Error                 `json:"error,omitempty"`
}

// Backend backend address of a frontDoor load balancer.
type Backend struct {
	// Address - Location of the backend (IP address or FQDN)
	Address *string `json:"address,omitempty"`
	// HTTPPort - The HTTP TCP port number. Must be between 1 and 65535.
	HTTPPort *int32 `json:"httpPort,omitempty"`
	// HTTPSPort - The HTTPS TCP port number. Must be between 1 and 65535.
	HTTPSPort *int32 `json:"httpsPort,omitempty"`
	// EnabledState - Whether to enable use of this backend. Permitted values are 'Enabled' or 'Disabled'. Possible values include: 'Enabled', 'Disabled'
	EnabledState BackendEnabledState `json:"enabledState,omitempty"`
	// Priority - Priority to use for load balancing. Higher priorities will not be used for load balancing if any lower priority backend is healthy.
	Priority *int32 `json:"priority,omitempty"`
	// Weight - Weight of this endpoint for load balancing purposes.
	Weight *int32 `json:"weight,omitempty"`
	// BackendHostHeader - The value to use as the host header sent to the backend. If blank or unspecified, this defaults to the incoming host.
	BackendHostHeader *string `json:"backendHostHeader,omitempty"`
}

// BackendPool a backend pool is a collection of backends that can be routed to.
type BackendPool struct {
	// BackendPoolProperties - Properties of the Front Door Backend Pool
	*BackendPoolProperties `json:"properties,omitempty"`
	// Name - Resource name.
	Name *string `json:"name,omitempty"`
	// Type - READ-ONLY; Resource type.
	Type *string `json:"type,omitempty"`
	// ID - Resource ID.
	ID *string `json:"id,omitempty"`
}

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

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

	return nil
}

// BackendPoolListResult result of the request to list Backend Pools. It contains a list of Backend Pools
// objects and a URL link to get the next set of results.
type BackendPoolListResult struct {
	// Value - READ-ONLY; List of Backend Pools within a Front Door.
	Value *[]BackendPool `json:"value,omitempty"`
	// NextLink - URL to get the next set of BackendPool objects if there are any.
	NextLink *string `json:"nextLink,omitempty"`
}

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

// BackendPoolProperties the JSON object that contains the properties required to create a routing rule.
type BackendPoolProperties struct {
	// ResourceState - Resource status. Possible values include: 'ResourceStateCreating', 'ResourceStateEnabling', 'ResourceStateEnabled', 'ResourceStateDisabling', 'ResourceStateDisabled', 'ResourceStateDeleting'
	ResourceState ResourceState `json:"resourceState,omitempty"`
	// Backends - The set of backends for this pool
	Backends *[]Backend `json:"backends,omitempty"`
	// LoadBalancingSettings - Load balancing settings for a backend pool
	LoadBalancingSettings *SubResource `json:"loadBalancingSettings,omitempty"`
	// HealthProbeSettings - L7 health probe settings for a backend pool
	HealthProbeSettings *SubResource `json:"healthProbeSettings,omitempty"`
}

// BackendPoolsSettings settings that apply to all backend pools.
type BackendPoolsSettings struct {
	// EnforceCertificateNameCheck - Whether to enforce certificate name check on HTTPS requests to all backend pools. No effect on non-HTTPS requests. Possible values include: 'EnforceCertificateNameCheckEnabledStateEnabled', 'EnforceCertificateNameCheckEnabledStateDisabled'
	EnforceCertificateNameCheck EnforceCertificateNameCheckEnabledState `json:"enforceCertificateNameCheck,omitempty"`
	// SendRecvTimeoutSeconds - Send and receive timeout on forwarding request to the backend. When timeout is reached, the request fails and returns.
	SendRecvTimeoutSeconds *int32 `json:"sendRecvTimeoutSeconds,omitempty"`
}

// BackendPoolUpdateParameters a collection of backends that can be routed to.
type BackendPoolUpdateParameters struct {
	// Backends - The set of backends for this pool
	Backends *[]Backend `json:"backends,omitempty"`
	// LoadBalancingSettings - Load balancing settings for a backend pool
	LoadBalancingSettings *SubResource `json:"loadBalancingSettings,omitempty"`
	// HealthProbeSettings - L7 health probe settings for a backend pool
	HealthProbeSettings *SubResource `json:"healthProbeSettings,omitempty"`
}

// CacheConfiguration caching settings for a caching-type route. To disable caching, do not provide a
// cacheConfiguration object.
type CacheConfiguration struct {
	// QueryParameterStripDirective - Treatment of URL query terms when forming the cache key. Possible values include: 'StripNone', 'StripAll'
	QueryParameterStripDirective Query `json:"queryParameterStripDirective,omitempty"`
	// DynamicCompression - Whether to use dynamic compression for cached content. Possible values include: 'DynamicCompressionEnabledEnabled', 'DynamicCompressionEnabledDisabled'
	DynamicCompression DynamicCompressionEnabled `json:"dynamicCompression,omitempty"`
}

// CertificateSourceParameters parameters required for enabling SSL with Front Door-managed certificates
type CertificateSourceParameters struct {
	// CertificateType - Defines the type of the certificate used for secure connections to a frontendEndpoint. Possible values include: 'Dedicated'
	CertificateType CertificateType `json:"certificateType,omitempty"`
}

// CheckNameAvailabilityInput input of CheckNameAvailability API.
type CheckNameAvailabilityInput struct {
	// Name - The resource name to validate.
	Name *string `json:"name,omitempty"`
	// Type - The type of the resource whose name is to be validated. Possible values include: 'MicrosoftNetworkfrontDoors', 'MicrosoftNetworkfrontDoorsfrontendEndpoints'
	Type ResourceType `json:"type,omitempty"`
}

// CheckNameAvailabilityOutput output of check name availability API.
type CheckNameAvailabilityOutput struct {
	autorest.Response `json:"-"`
	// NameAvailability - READ-ONLY; Indicates whether the name is available. Possible values include: 'Available', 'Unavailable'
	NameAvailability Availability `json:"nameAvailability,omitempty"`
	// Reason - READ-ONLY; The reason why the name is not available.
	Reason *string `json:"reason,omitempty"`
	// Message - READ-ONLY; The detailed error message describing why the name is not available.
	Message *string `json:"message,omitempty"`
}

// CustomHTTPSConfiguration https settings for a domain
type CustomHTTPSConfiguration struct {
	// CertificateSource - Defines the source of the SSL certificate. Possible values include: 'CertificateSourceAzureKeyVault', 'CertificateSourceFrontDoor'
	CertificateSource CertificateSource `json:"certificateSource,omitempty"`
	// ProtocolType - Defines the TLS extension protocol that is used for secure delivery
	ProtocolType *string `json:"protocolType,omitempty"`
	// MinimumTLSVersion - The minimum TLS version required from the clients to establish an SSL handshake with Front Door. Possible values include: 'OneFullStopZero', 'OneFullStopTwo'
	MinimumTLSVersion MinimumTLSVersion `json:"minimumTlsVersion,omitempty"`
	// KeyVaultCertificateSourceParameters - KeyVault certificate source parameters (if certificateSource=AzureKeyVault)
	*KeyVaultCertificateSourceParameters `json:"keyVaultCertificateSourceParameters,omitempty"`
	// CertificateSourceParameters - Parameters required for enabling SSL with Front Door-managed certificates (if certificateSource=FrontDoor)
	*CertificateSourceParameters `json:"frontDoorCertificateSourceParameters,omitempty"`
}

// MarshalJSON is the custom marshaler for CustomHTTPSConfiguration.
func (chc CustomHTTPSConfiguration) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]interface{})
	if chc.CertificateSource != "" {
		objectMap["certificateSource"] = chc.CertificateSource
	}
	if chc.ProtocolType != nil {
		objectMap["protocolType"] = chc.ProtocolType
	}
	if chc.MinimumTLSVersion != "" {
		objectMap["minimumTlsVersion"] = chc.MinimumTLSVersion
	}
	if chc.KeyVaultCertificateSourceParameters != nil {
		objectMap["keyVaultCertificateSourceParameters"] = chc.KeyVaultCertificateSourceParameters
	}
	if chc.CertificateSourceParameters != nil {
		objectMap["frontDoorCertificateSourceParameters"] = chc.CertificateSourceParameters
	}
	return json.Marshal(objectMap)
}

// UnmarshalJSON is the custom unmarshaler for CustomHTTPSConfiguration struct.
func (chc *CustomHTTPSConfiguration) 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 "certificateSource":
			if v != nil {
				var certificateSource CertificateSource
				err = json.Unmarshal(*v, &certificateSource)
				if err != nil {
					return err
				}
				chc.CertificateSource = certificateSource
			}
		case "protocolType":
			if v != nil {
				var protocolType string
				err = json.Unmarshal(*v, &protocolType)
				if err != nil {
					return err
				}
				chc.ProtocolType = &protocolType
			}
		case "minimumTlsVersion":
			if v != nil {
				var minimumTLSVersion MinimumTLSVersion
				err = json.Unmarshal(*v, &minimumTLSVersion)
				if err != nil {
					return err
				}
				chc.MinimumTLSVersion = minimumTLSVersion
			}
		case "keyVaultCertificateSourceParameters":
			if v != nil {
				var keyVaultCertificateSourceParameters KeyVaultCertificateSourceParameters
				err = json.Unmarshal(*v, &keyVaultCertificateSourceParameters)
				if err != nil {
					return err
				}
				chc.KeyVaultCertificateSourceParameters = &keyVaultCertificateSourceParameters
			}
		case "frontDoorCertificateSourceParameters":
			if v != nil {
				var certificateSourceParameters CertificateSourceParameters
				err = json.Unmarshal(*v, &certificateSourceParameters)
				if err != nil {
					return err
				}
				chc.CertificateSourceParameters = &certificateSourceParameters
			}
		}
	}

	return nil
}

// CustomRule defines contents of a web application rule
type CustomRule struct {
	// Name - Describes the name of the rule.
	Name *string `json:"name,omitempty"`
	// Priority - Describes priority of the rule. Rules with a lower value will be evaluated before rules with a higher value.
	Priority *int32 `json:"priority,omitempty"`
	// EnabledState - Describes if the custom rule is in enabled or disabled state. Defaults to Enabled if not specified. Possible values include: 'CustomRuleEnabledStateDisabled', 'CustomRuleEnabledStateEnabled'
	EnabledState CustomRuleEnabledState `json:"enabledState,omitempty"`
	// RuleType - Describes type of rule. Possible values include: 'MatchRule', 'RateLimitRule'
	RuleType RuleType `json:"ruleType,omitempty"`
	// RateLimitDurationInMinutes - Time window for resetting the rate limit count. Default is 1 minute.
	RateLimitDurationInMinutes *int32 `json:"rateLimitDurationInMinutes,omitempty"`
	// RateLimitThreshold - Number of allowed requests per client within the time window.
	RateLimitThreshold *int32 `json:"rateLimitThreshold,omitempty"`
	// MatchConditions - List of match conditions.
	MatchConditions *[]MatchCondition `json:"matchConditions,omitempty"`
	// Action - Describes what action to be applied when rule matches. Possible values include: 'Allow', 'Block', 'Log', 'Redirect'
	Action ActionType `json:"action,omitempty"`
}

// CustomRuleList defines contents of custom rules
type CustomRuleList struct {
	// Rules - List of rules
	Rules *[]CustomRule `json:"rules,omitempty"`
}

// EndpointsPurgeContentFuture an abstraction for monitoring and retrieving the results of a long-running
// operation.
type EndpointsPurgeContentFuture struct {
	azure.FutureAPI
	// Result returns the result of the asynchronous operation.
	// If the operation has not completed it will return an error.
	Result func(EndpointsClient) (autorest.Response, error)
}

// Error ...
type Error struct {
	Code       *string         `json:"code,omitempty"`
	Message    *string         `json:"message,omitempty"`
	Target     *string         `json:"target,omitempty"`
	Details    *[]ErrorDetails `json:"details,omitempty"`
	InnerError *string         `json:"innerError,omitempty"`
}

// ErrorDetails ...
type ErrorDetails struct {
	Code    *string `json:"code,omitempty"`
	Target  *string `json:"target,omitempty"`
	Message *string `json:"message,omitempty"`
}

// ErrorResponse error response indicates Front Door service is not able to process the incoming request.
// The reason is provided in the error message.
type ErrorResponse struct {
	// Code - READ-ONLY; Error code.
	Code *string `json:"code,omitempty"`
	// Message - READ-ONLY; Error message indicating why the operation failed.
	Message *string `json:"message,omitempty"`
}

// ForwardingConfiguration describes Forwarding Route.
type ForwardingConfiguration struct {
	// CustomForwardingPath - A custom path used to rewrite resource paths matched by this rule. Leave empty to use incoming path.
	CustomForwardingPath *string `json:"customForwardingPath,omitempty"`
	// ForwardingProtocol - Protocol this rule will use when forwarding traffic to backends. Possible values include: 'HTTPOnly', 'HTTPSOnly', 'MatchRequest'
	ForwardingProtocol ForwardingProtocol `json:"forwardingProtocol,omitempty"`
	// CacheConfiguration - The caching configuration associated with this rule.
	CacheConfiguration *CacheConfiguration `json:"cacheConfiguration,omitempty"`
	// BackendPool - A reference to the BackendPool which this rule routes to.
	BackendPool *SubResource `json:"backendPool,omitempty"`
	// OdataType - Possible values include: 'OdataTypeRouteConfiguration', 'OdataTypeMicrosoftAzureFrontDoorModelsFrontdoorForwardingConfiguration', 'OdataTypeMicrosoftAzureFrontDoorModelsFrontdoorRedirectConfiguration'
	OdataType OdataType `json:"@odata.type,omitempty"`
}

// MarshalJSON is the custom marshaler for ForwardingConfiguration.
func (fc ForwardingConfiguration) MarshalJSON() ([]byte, error) {
	fc.OdataType = OdataTypeMicrosoftAzureFrontDoorModelsFrontdoorForwardingConfiguration
	objectMap := make(map[string]interface{})
	if fc.CustomForwardingPath != nil {
		objectMap["customForwardingPath"] = fc.CustomForwardingPath
	}
	if fc.ForwardingProtocol != "" {
		objectMap["forwardingProtocol"] = fc.ForwardingProtocol
	}
	if fc.CacheConfiguration != nil {
		objectMap["cacheConfiguration"] = fc.CacheConfiguration
	}
	if fc.BackendPool != nil {
		objectMap["backendPool"] = fc.BackendPool
	}
	if fc.OdataType != "" {
		objectMap["@odata.type"] = fc.OdataType
	}
	return json.Marshal(objectMap)
}

// AsForwardingConfiguration is the BasicRouteConfiguration implementation for ForwardingConfiguration.
func (fc ForwardingConfiguration) AsForwardingConfiguration() (*ForwardingConfiguration, bool) {
	return &fc, true
}

// AsRedirectConfiguration is the BasicRouteConfiguration implementation for ForwardingConfiguration.
func (fc ForwardingConfiguration) AsRedirectConfiguration() (*RedirectConfiguration, bool) {
	return nil, false
}

// AsRouteConfiguration is the BasicRouteConfiguration implementation for ForwardingConfiguration.
func (fc ForwardingConfiguration) AsRouteConfiguration() (*RouteConfiguration, bool) {
	return nil, false
}

// AsBasicRouteConfiguration is the BasicRouteConfiguration implementation for ForwardingConfiguration.
func (fc ForwardingConfiguration) AsBasicRouteConfiguration() (BasicRouteConfiguration, bool) {
	return &fc, true
}

// FrontDoor front Door represents a collection of backend endpoints to route traffic to along with rules
// that specify how traffic is sent there.
type FrontDoor struct {
	autorest.Response `json:"-"`
	// Properties - Properties of the Front Door Load Balancer
	*Properties `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"`
	// Location - Resource location.
	Location *string `json:"location,omitempty"`
	// Tags - Resource tags.
	Tags map[string]*string `json:"tags"`
}

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

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

	return nil
}

// FrontDoorsCreateOrUpdateFutureType an abstraction for monitoring and retrieving the results of a
// long-running operation.
type FrontDoorsCreateOrUpdateFutureType struct {
	azure.FutureAPI
	// Result returns the result of the asynchronous operation.
	// If the operation has not completed it will return an error.
	Result func(FrontDoorsClient) (FrontDoor, error)
}

// FrontDoorsDeleteFutureType an abstraction for monitoring and retrieving the results of a long-running
// operation.
type FrontDoorsDeleteFutureType struct {
	azure.FutureAPI
	// Result returns the result of the asynchronous operation.
	// If the operation has not completed it will return an error.
	Result func(FrontDoorsClient) (autorest.Response, error)
}

// FrontendEndpoint a frontend endpoint used for routing.
type FrontendEndpoint struct {
	autorest.Response `json:"-"`
	// FrontendEndpointProperties - Properties of the Frontend endpoint
	*FrontendEndpointProperties `json:"properties,omitempty"`
	// Name - Resource name.
	Name *string `json:"name,omitempty"`
	// Type - READ-ONLY; Resource type.
	Type *string `json:"type,omitempty"`
	// ID - Resource ID.
	ID *string `json:"id,omitempty"`
}

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

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

	return nil
}

// FrontendEndpointLink defines the Resource ID for a Frontend Endpoint.
type FrontendEndpointLink struct {
	// ID - Resource ID.
	ID *string `json:"id,omitempty"`
}

// FrontendEndpointProperties the JSON object that contains the properties required to create a frontend
// endpoint.
type FrontendEndpointProperties struct {
	// ResourceState - Resource status. Possible values include: 'ResourceStateCreating', 'ResourceStateEnabling', 'ResourceStateEnabled', 'ResourceStateDisabling', 'ResourceStateDisabled', 'ResourceStateDeleting'
	ResourceState ResourceState `json:"resourceState,omitempty"`
	// CustomHTTPSProvisioningState - READ-ONLY; Provisioning status of Custom Https of the frontendEndpoint. Possible values include: 'CustomHTTPSProvisioningStateEnabling', 'CustomHTTPSProvisioningStateEnabled', 'CustomHTTPSProvisioningStateDisabling', 'CustomHTTPSProvisioningStateDisabled', 'CustomHTTPSProvisioningStateFailed'
	CustomHTTPSProvisioningState CustomHTTPSProvisioningState `json:"customHttpsProvisioningState,omitempty"`
	// CustomHTTPSProvisioningSubstate - READ-ONLY; Provisioning substate shows the progress of custom HTTPS enabling/disabling process step by step. Possible values include: 'SubmittingDomainControlValidationRequest', 'PendingDomainControlValidationREquestApproval', 'DomainControlValidationRequestApproved', 'DomainControlValidationRequestRejected', 'DomainControlValidationRequestTimedOut', 'IssuingCertificate', 'DeployingCertificate', 'CertificateDeployed', 'DeletingCertificate', 'CertificateDeleted'
	CustomHTTPSProvisioningSubstate CustomHTTPSProvisioningSubstate `json:"customHttpsProvisioningSubstate,omitempty"`
	// CustomHTTPSConfiguration - READ-ONLY; The configuration specifying how to enable HTTPS
	CustomHTTPSConfiguration *CustomHTTPSConfiguration `json:"customHttpsConfiguration,omitempty"`
	// HostName - The host name of the frontendEndpoint. Must be a domain name.
	HostName *string `json:"hostName,omitempty"`
	// SessionAffinityEnabledState - Whether to allow session affinity on this host. Valid options are 'Enabled' or 'Disabled'. Possible values include: 'SessionAffinityEnabledStateEnabled', 'SessionAffinityEnabledStateDisabled'
	SessionAffinityEnabledState SessionAffinityEnabledState `json:"sessionAffinityEnabledState,omitempty"`
	// SessionAffinityTTLSeconds - UNUSED. This field will be ignored. The TTL to use in seconds for session affinity, if applicable.
	SessionAffinityTTLSeconds *int32 `json:"sessionAffinityTtlSeconds,omitempty"`
	// WebApplicationFirewallPolicyLink - Defines the Web Application Firewall policy for each host (if applicable)
	WebApplicationFirewallPolicyLink *FrontendEndpointUpdateParametersWebApplicationFirewallPolicyLink `json:"webApplicationFirewallPolicyLink,omitempty"`
}

// MarshalJSON is the custom marshaler for FrontendEndpointProperties.
func (fep FrontendEndpointProperties) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]interface{})
	if fep.ResourceState != "" {
		objectMap["resourceState"] = fep.ResourceState
	}
	if fep.HostName != nil {
		objectMap["hostName"] = fep.HostName
	}
	if fep.SessionAffinityEnabledState != "" {
		objectMap["sessionAffinityEnabledState"] = fep.SessionAffinityEnabledState
	}
	if fep.SessionAffinityTTLSeconds != nil {
		objectMap["sessionAffinityTtlSeconds"] = fep.SessionAffinityTTLSeconds
	}
	if fep.WebApplicationFirewallPolicyLink != nil {
		objectMap["webApplicationFirewallPolicyLink"] = fep.WebApplicationFirewallPolicyLink
	}
	return json.Marshal(objectMap)
}

// FrontendEndpointsDisableHTTPSFuture an abstraction for monitoring and retrieving the results of a
// long-running operation.
type FrontendEndpointsDisableHTTPSFuture struct {
	azure.FutureAPI
	// Result returns the result of the asynchronous operation.
	// If the operation has not completed it will return an error.
	Result func(FrontendEndpointsClient) (autorest.Response, error)
}

// FrontendEndpointsEnableHTTPSFuture an abstraction for monitoring and retrieving the results of a
// long-running operation.
type FrontendEndpointsEnableHTTPSFuture struct {
	azure.FutureAPI
	// Result returns the result of the asynchronous operation.
	// If the operation has not completed it will return an error.
	Result func(FrontendEndpointsClient) (autorest.Response, error)
}

// FrontendEndpointsListResult result of the request to list frontend endpoints. It contains a list of
// Frontend endpoint objects and a URL link to get the next set of results.
type FrontendEndpointsListResult struct {
	autorest.Response `json:"-"`
	// Value - READ-ONLY; List of Frontend endpoints within a Front Door.
	Value *[]FrontendEndpoint `json:"value,omitempty"`
	// NextLink - URL to get the next set of frontend endpoints if there are any.
	NextLink *string `json:"nextLink,omitempty"`
}

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

// FrontendEndpointsListResultIterator provides access to a complete listing of FrontendEndpoint values.
type FrontendEndpointsListResultIterator struct {
	i    int
	page FrontendEndpointsListResultPage
}

// 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 *FrontendEndpointsListResultIterator) NextWithContext(ctx context.Context) (err error) {
	if tracing.IsEnabled() {
		ctx = tracing.StartSpan(ctx, fqdn+"/FrontendEndpointsListResultIterator.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 *FrontendEndpointsListResultIterator) Next() error {
	return iter.NextWithContext(context.Background())
}

// NotDone returns true if the enumeration should be started or is not yet complete.
func (iter FrontendEndpointsListResultIterator) 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 FrontendEndpointsListResultIterator) Response() FrontendEndpointsListResult {
	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 FrontendEndpointsListResultIterator) Value() FrontendEndpoint {
	if !iter.page.NotDone() {
		return FrontendEndpoint{}
	}
	return iter.page.Values()[iter.i]
}

// Creates a new instance of the FrontendEndpointsListResultIterator type.
func NewFrontendEndpointsListResultIterator(page FrontendEndpointsListResultPage) FrontendEndpointsListResultIterator {
	return FrontendEndpointsListResultIterator{page: page}
}

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

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

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

// FrontendEndpointsListResultPage contains a page of FrontendEndpoint values.
type FrontendEndpointsListResultPage struct {
	fn   func(context.Context, FrontendEndpointsListResult) (FrontendEndpointsListResult, error)
	felr FrontendEndpointsListResult
}

// 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 *FrontendEndpointsListResultPage) NextWithContext(ctx context.Context) (err error) {
	if tracing.IsEnabled() {
		ctx = tracing.StartSpan(ctx, fqdn+"/FrontendEndpointsListResultPage.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.felr)
		if err != nil {
			return err
		}
		page.felr = 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 *FrontendEndpointsListResultPage) Next() error {
	return page.NextWithContext(context.Background())
}

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

// Response returns the raw server response from the last page request.
func (page FrontendEndpointsListResultPage) Response() FrontendEndpointsListResult {
	return page.felr
}

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

// Creates a new instance of the FrontendEndpointsListResultPage type.
func NewFrontendEndpointsListResultPage(cur FrontendEndpointsListResult, getNextPage func(context.Context, FrontendEndpointsListResult) (FrontendEndpointsListResult, error)) FrontendEndpointsListResultPage {
	return FrontendEndpointsListResultPage{
		fn:   getNextPage,
		felr: cur,
	}
}

// FrontendEndpointUpdateParameters frontend endpoint used in routing rule
type FrontendEndpointUpdateParameters struct {
	// HostName - The host name of the frontendEndpoint. Must be a domain name.
	HostName *string `json:"hostName,omitempty"`
	// SessionAffinityEnabledState - Whether to allow session affinity on this host. Valid options are 'Enabled' or 'Disabled'. Possible values include: 'SessionAffinityEnabledStateEnabled', 'SessionAffinityEnabledStateDisabled'
	SessionAffinityEnabledState SessionAffinityEnabledState `json:"sessionAffinityEnabledState,omitempty"`
	// SessionAffinityTTLSeconds - UNUSED. This field will be ignored. The TTL to use in seconds for session affinity, if applicable.
	SessionAffinityTTLSeconds *int32 `json:"sessionAffinityTtlSeconds,omitempty"`
	// WebApplicationFirewallPolicyLink - Defines the Web Application Firewall policy for each host (if applicable)
	WebApplicationFirewallPolicyLink *FrontendEndpointUpdateParametersWebApplicationFirewallPolicyLink `json:"webApplicationFirewallPolicyLink,omitempty"`
}

// FrontendEndpointUpdateParametersWebApplicationFirewallPolicyLink defines the Web Application Firewall
// policy for each host (if applicable)
type FrontendEndpointUpdateParametersWebApplicationFirewallPolicyLink struct {
	// ID - Resource ID.
	ID *string `json:"id,omitempty"`
}

// HealthProbeSettingsListResult result of the request to list HealthProbeSettings. It contains a list of
// HealthProbeSettings objects and a URL link to get the next set of results.
type HealthProbeSettingsListResult struct {
	// Value - READ-ONLY; List of HealthProbeSettings within a Front Door.
	Value *[]HealthProbeSettingsModel `json:"value,omitempty"`
	// NextLink - URL to get the next set of HealthProbeSettings objects if there are any.
	NextLink *string `json:"nextLink,omitempty"`
}

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

// HealthProbeSettingsModel load balancing settings for a backend pool
type HealthProbeSettingsModel struct {
	// HealthProbeSettingsProperties - Properties of the health probe settings
	*HealthProbeSettingsProperties `json:"properties,omitempty"`
	// Name - Resource name.
	Name *string `json:"name,omitempty"`
	// Type - READ-ONLY; Resource type.
	Type *string `json:"type,omitempty"`
	// ID - Resource ID.
	ID *string `json:"id,omitempty"`
}

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

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

	return nil
}

// HealthProbeSettingsProperties the JSON object that contains the properties required to create a health
// probe settings.
type HealthProbeSettingsProperties struct {
	// ResourceState - Resource status. Possible values include: 'ResourceStateCreating', 'ResourceStateEnabling', 'ResourceStateEnabled', 'ResourceStateDisabling', 'ResourceStateDisabled', 'ResourceStateDeleting'
	ResourceState ResourceState `json:"resourceState,omitempty"`
	// Path - The path to use for the health probe. Default is /
	Path *string `json:"path,omitempty"`
	// Protocol - Protocol scheme to use for this probe. Possible values include: 'HTTP', 'HTTPS'
	Protocol Protocol `json:"protocol,omitempty"`
	// IntervalInSeconds - The number of seconds between health probes.
	IntervalInSeconds *int32 `json:"intervalInSeconds,omitempty"`
	// HealthProbeMethod - Configures which HTTP method to use to probe the backends defined under backendPools. Possible values include: 'GET', 'HEAD'
	HealthProbeMethod HealthProbeMethod `json:"healthProbeMethod,omitempty"`
	// EnabledState - Whether to enable health probes to be made against backends defined under backendPools. Health probes can only be disabled if there is a single enabled backend in single enabled backend pool. Possible values include: 'HealthProbeEnabledEnabled', 'HealthProbeEnabledDisabled'
	EnabledState HealthProbeEnabled `json:"enabledState,omitempty"`
}

// HealthProbeSettingsUpdateParameters l7 health probe settings for a backend pool
type HealthProbeSettingsUpdateParameters struct {
	// Path - The path to use for the health probe. Default is /
	Path *string `json:"path,omitempty"`
	// Protocol - Protocol scheme to use for this probe. Possible values include: 'HTTP', 'HTTPS'
	Protocol Protocol `json:"protocol,omitempty"`
	// IntervalInSeconds - The number of seconds between health probes.
	IntervalInSeconds *int32 `json:"intervalInSeconds,omitempty"`
	// HealthProbeMethod - Configures which HTTP method to use to probe the backends defined under backendPools. Possible values include: 'GET', 'HEAD'
	HealthProbeMethod HealthProbeMethod `json:"healthProbeMethod,omitempty"`
	// EnabledState - Whether to enable health probes to be made against backends defined under backendPools. Health probes can only be disabled if there is a single enabled backend in single enabled backend pool. Possible values include: 'HealthProbeEnabledEnabled', 'HealthProbeEnabledDisabled'
	EnabledState HealthProbeEnabled `json:"enabledState,omitempty"`
}

// KeyVaultCertificateSourceParameters parameters required for bring-your-own-certification via Key Vault
type KeyVaultCertificateSourceParameters struct {
	// Vault - The Key Vault containing the SSL certificate
	Vault *KeyVaultCertificateSourceParametersVault `json:"vault,omitempty"`
	// SecretName - The name of the Key Vault secret representing the full certificate PFX
	SecretName *string `json:"secretName,omitempty"`
	// SecretVersion - The version of the Key Vault secret representing the full certificate PFX
	SecretVersion *string `json:"secretVersion,omitempty"`
}

// KeyVaultCertificateSourceParametersVault the Key Vault containing the SSL certificate
type KeyVaultCertificateSourceParametersVault struct {
	// ID - Resource ID.
	ID *string `json:"id,omitempty"`
}

// ListResult result of the request to list Front Doors. It contains a list of Front Door objects and a URL
// link to get the next set of results.
type ListResult struct {
	autorest.Response `json:"-"`
	// Value - READ-ONLY; List of Front Doors within a resource group.
	Value *[]FrontDoor `json:"value,omitempty"`
	// NextLink - URL to get the next set of Front Door objects if there are any.
	NextLink *string `json:"nextLink,omitempty"`
}

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

// ListResultIterator provides access to a complete listing of FrontDoor values.
type ListResultIterator struct {
	i    int
	page ListResultPage
}

// 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 *ListResultIterator) NextWithContext(ctx context.Context) (err error) {
	if tracing.IsEnabled() {
		ctx = tracing.StartSpan(ctx, fqdn+"/ListResultIterator.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 *ListResultIterator) Next() error {
	return iter.NextWithContext(context.Background())
}

// NotDone returns true if the enumeration should be started or is not yet complete.
func (iter ListResultIterator) 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 ListResultIterator) Response() ListResult {
	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 ListResultIterator) Value() FrontDoor {
	if !iter.page.NotDone() {
		return FrontDoor{}
	}
	return iter.page.Values()[iter.i]
}

// Creates a new instance of the ListResultIterator type.
func NewListResultIterator(page ListResultPage) ListResultIterator {
	return ListResultIterator{page: page}
}

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

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

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

// ListResultPage contains a page of FrontDoor values.
type ListResultPage struct {
	fn func(context.Context, ListResult) (ListResult, error)
	lr ListResult
}

// 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 *ListResultPage) NextWithContext(ctx context.Context) (err error) {
	if tracing.IsEnabled() {
		ctx = tracing.StartSpan(ctx, fqdn+"/ListResultPage.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.lr)
		if err != nil {
			return err
		}
		page.lr = 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 *ListResultPage) Next() error {
	return page.NextWithContext(context.Background())
}

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

// Response returns the raw server response from the last page request.
func (page ListResultPage) Response() ListResult {
	return page.lr
}

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

// Creates a new instance of the ListResultPage type.
func NewListResultPage(cur ListResult, getNextPage func(context.Context, ListResult) (ListResult, error)) ListResultPage {
	return ListResultPage{
		fn: getNextPage,
		lr: cur,
	}
}

// LoadBalancingSettingsListResult result of the request to list load balancing settings. It contains a
// list of load balancing settings objects and a URL link to get the next set of results.
type LoadBalancingSettingsListResult struct {
	// Value - READ-ONLY; List of Backend Pools within a Front Door.
	Value *[]LoadBalancingSettingsModel `json:"value,omitempty"`
	// NextLink - URL to get the next set of LoadBalancingSettings objects if there are any.
	NextLink *string `json:"nextLink,omitempty"`
}

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

// LoadBalancingSettingsModel load balancing settings for a backend pool
type LoadBalancingSettingsModel struct {
	// LoadBalancingSettingsProperties - Properties of the load balancing settings
	*LoadBalancingSettingsProperties `json:"properties,omitempty"`
	// Name - Resource name.
	Name *string `json:"name,omitempty"`
	// Type - READ-ONLY; Resource type.
	Type *string `json:"type,omitempty"`
	// ID - Resource ID.
	ID *string `json:"id,omitempty"`
}

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

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

	return nil
}

// LoadBalancingSettingsProperties the JSON object that contains the properties required to create load
// balancing settings
type LoadBalancingSettingsProperties struct {
	// ResourceState - Resource status. Possible values include: 'ResourceStateCreating', 'ResourceStateEnabling', 'ResourceStateEnabled', 'ResourceStateDisabling', 'ResourceStateDisabled', 'ResourceStateDeleting'
	ResourceState ResourceState `json:"resourceState,omitempty"`
	// SampleSize - The number of samples to consider for load balancing decisions
	SampleSize *int32 `json:"sampleSize,omitempty"`
	// SuccessfulSamplesRequired - The number of samples within the sample period that must succeed
	SuccessfulSamplesRequired *int32 `json:"successfulSamplesRequired,omitempty"`
	// AdditionalLatencyMilliseconds - The additional latency in milliseconds for probes to fall into the lowest latency bucket
	AdditionalLatencyMilliseconds *int32 `json:"additionalLatencyMilliseconds,omitempty"`
}

// LoadBalancingSettingsUpdateParameters round-Robin load balancing settings for a backend pool
type LoadBalancingSettingsUpdateParameters struct {
	// SampleSize - The number of samples to consider for load balancing decisions
	SampleSize *int32 `json:"sampleSize,omitempty"`
	// SuccessfulSamplesRequired - The number of samples within the sample period that must succeed
	SuccessfulSamplesRequired *int32 `json:"successfulSamplesRequired,omitempty"`
	// AdditionalLatencyMilliseconds - The additional latency in milliseconds for probes to fall into the lowest latency bucket
	AdditionalLatencyMilliseconds *int32 `json:"additionalLatencyMilliseconds,omitempty"`
}

// ManagedRuleDefinition describes a managed rule definition.
type ManagedRuleDefinition struct {
	// RuleID - READ-ONLY; Identifier for the managed rule.
	RuleID *string `json:"ruleId,omitempty"`
	// DefaultState - READ-ONLY; Describes the default state for the managed rule. Possible values include: 'ManagedRuleEnabledStateDisabled', 'ManagedRuleEnabledStateEnabled'
	DefaultState ManagedRuleEnabledState `json:"defaultState,omitempty"`
	// DefaultAction - READ-ONLY; Describes the default action to be applied when the managed rule matches. Possible values include: 'Allow', 'Block', 'Log', 'Redirect'
	DefaultAction ActionType `json:"defaultAction,omitempty"`
	// Description - READ-ONLY; Describes the functionality of the managed rule.
	Description *string `json:"description,omitempty"`
}

// ManagedRuleGroupDefinition describes a managed rule group.
type ManagedRuleGroupDefinition struct {
	// RuleGroupName - READ-ONLY; Name of the managed rule group.
	RuleGroupName *string `json:"ruleGroupName,omitempty"`
	// Description - READ-ONLY; Description of the managed rule group.
	Description *string `json:"description,omitempty"`
	// Rules - READ-ONLY; List of rules within the managed rule group.
	Rules *[]ManagedRuleDefinition `json:"rules,omitempty"`
}

// ManagedRuleGroupOverride defines a managed rule group override setting.
type ManagedRuleGroupOverride struct {
	// RuleGroupName - Describes the managed rule group to override.
	RuleGroupName *string `json:"ruleGroupName,omitempty"`
	// Rules - List of rules that will be disabled. If none specified, all rules in the group will be disabled.
	Rules *[]ManagedRuleOverride `json:"rules,omitempty"`
}

// ManagedRuleOverride defines a managed rule group override setting.
type ManagedRuleOverride struct {
	// RuleID - Identifier for the managed rule.
	RuleID *string `json:"ruleId,omitempty"`
	// EnabledState - Describes if the managed rule is in enabled or disabled state. Defaults to Disabled if not specified. Possible values include: 'ManagedRuleEnabledStateDisabled', 'ManagedRuleEnabledStateEnabled'
	EnabledState ManagedRuleEnabledState `json:"enabledState,omitempty"`
	// Action - Describes the override action to be applied when rule matches. Possible values include: 'Allow', 'Block', 'Log', 'Redirect'
	Action ActionType `json:"action,omitempty"`
}

// ManagedRuleSet defines a managed rule set.
type ManagedRuleSet struct {
	// RuleSetType - Defines the rule set type to use.
	RuleSetType *string `json:"ruleSetType,omitempty"`
	// RuleSetVersion - Defines the version of the rule set to use.
	RuleSetVersion *string `json:"ruleSetVersion,omitempty"`
	// RuleGroupOverrides - Defines the rule group overrides to apply to the rule set.
	RuleGroupOverrides *[]ManagedRuleGroupOverride `json:"ruleGroupOverrides,omitempty"`
}

// ManagedRuleSetDefinition describes the a managed rule set definition.
type ManagedRuleSetDefinition struct {
	// ManagedRuleSetDefinitionProperties - Properties for a managed rule set definition.
	*ManagedRuleSetDefinitionProperties `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"`
	// Location - Resource location.
	Location *string `json:"location,omitempty"`
	// Tags - Resource tags.
	Tags map[string]*string `json:"tags"`
}

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

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

	return nil
}

// ManagedRuleSetDefinitionList list of managed rule set definitions available for use in a policy.
type ManagedRuleSetDefinitionList struct {
	autorest.Response `json:"-"`
	// Value - READ-ONLY; List of managed rule set definitions.
	Value *[]ManagedRuleSetDefinition `json:"value,omitempty"`
	// NextLink - URL to retrieve next set of managed rule set definitions.
	NextLink *string `json:"nextLink,omitempty"`
}

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

// ManagedRuleSetDefinitionListIterator provides access to a complete listing of ManagedRuleSetDefinition
// values.
type ManagedRuleSetDefinitionListIterator struct {
	i    int
	page ManagedRuleSetDefinitionListPage
}

// 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 *ManagedRuleSetDefinitionListIterator) NextWithContext(ctx context.Context) (err error) {
	if tracing.IsEnabled() {
		ctx = tracing.StartSpan(ctx, fqdn+"/ManagedRuleSetDefinitionListIterator.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 *ManagedRuleSetDefinitionListIterator) Next() error {
	return iter.NextWithContext(context.Background())
}

// NotDone returns true if the enumeration should be started or is not yet complete.
func (iter ManagedRuleSetDefinitionListIterator) 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 ManagedRuleSetDefinitionListIterator) Response() ManagedRuleSetDefinitionList {
	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 ManagedRuleSetDefinitionListIterator) Value() ManagedRuleSetDefinition {
	if !iter.page.NotDone() {
		return ManagedRuleSetDefinition{}
	}
	return iter.page.Values()[iter.i]
}

// Creates a new instance of the ManagedRuleSetDefinitionListIterator type.
func NewManagedRuleSetDefinitionListIterator(page ManagedRuleSetDefinitionListPage) ManagedRuleSetDefinitionListIterator {
	return ManagedRuleSetDefinitionListIterator{page: page}
}

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

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

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

// ManagedRuleSetDefinitionListPage contains a page of ManagedRuleSetDefinition values.
type ManagedRuleSetDefinitionListPage struct {
	fn    func(context.Context, ManagedRuleSetDefinitionList) (ManagedRuleSetDefinitionList, error)
	mrsdl ManagedRuleSetDefinitionList
}

// 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 *ManagedRuleSetDefinitionListPage) NextWithContext(ctx context.Context) (err error) {
	if tracing.IsEnabled() {
		ctx = tracing.StartSpan(ctx, fqdn+"/ManagedRuleSetDefinitionListPage.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.mrsdl)
		if err != nil {
			return err
		}
		page.mrsdl = 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 *ManagedRuleSetDefinitionListPage) Next() error {
	return page.NextWithContext(context.Background())
}

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

// Response returns the raw server response from the last page request.
func (page ManagedRuleSetDefinitionListPage) Response() ManagedRuleSetDefinitionList {
	return page.mrsdl
}

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

// Creates a new instance of the ManagedRuleSetDefinitionListPage type.
func NewManagedRuleSetDefinitionListPage(cur ManagedRuleSetDefinitionList, getNextPage func(context.Context, ManagedRuleSetDefinitionList) (ManagedRuleSetDefinitionList, error)) ManagedRuleSetDefinitionListPage {
	return ManagedRuleSetDefinitionListPage{
		fn:    getNextPage,
		mrsdl: cur,
	}
}

// ManagedRuleSetDefinitionProperties properties for a managed rule set definition.
type ManagedRuleSetDefinitionProperties struct {
	// ProvisioningState - READ-ONLY; Provisioning state of the managed rule set.
	ProvisioningState *string `json:"provisioningState,omitempty"`
	// RuleSetID - READ-ONLY; Id of the managed rule set.
	RuleSetID *string `json:"ruleSetId,omitempty"`
	// RuleSetType - READ-ONLY; Type of the managed rule set.
	RuleSetType *string `json:"ruleSetType,omitempty"`
	// RuleSetVersion - READ-ONLY; Version of the managed rule set type.
	RuleSetVersion *string `json:"ruleSetVersion,omitempty"`
	// RuleGroups - READ-ONLY; Rule groups of the managed rule set.
	RuleGroups *[]ManagedRuleGroupDefinition `json:"ruleGroups,omitempty"`
}

// ManagedRuleSetList defines the list of managed rule sets for the policy.
type ManagedRuleSetList struct {
	// ManagedRuleSets - List of rule sets.
	ManagedRuleSets *[]ManagedRuleSet `json:"managedRuleSets,omitempty"`
}

// MatchCondition define a match condition.
type MatchCondition struct {
	// MatchVariable - Request variable to compare with. Possible values include: 'RemoteAddr', 'RequestMethod', 'QueryString', 'PostArgs', 'RequestURI', 'RequestHeader', 'RequestBody', 'Cookies', 'SocketAddr'
	MatchVariable MatchVariable `json:"matchVariable,omitempty"`
	// Selector - Match against a specific key from the QueryString, PostArgs, RequestHeader or Cookies variables. Default is null.
	Selector *string `json:"selector,omitempty"`
	// Operator - Comparison type to use for matching with the variable value. Possible values include: 'Any', 'IPMatch', 'GeoMatch', 'Equal', 'Contains', 'LessThan', 'GreaterThan', 'LessThanOrEqual', 'GreaterThanOrEqual', 'BeginsWith', 'EndsWith', 'RegEx'
	Operator Operator `json:"operator,omitempty"`
	// NegateCondition - Describes if the result of this condition should be negated.
	NegateCondition *bool `json:"negateCondition,omitempty"`
	// MatchValue - List of possible match values.
	MatchValue *[]string `json:"matchValue,omitempty"`
	// Transforms - List of transforms.
	Transforms *[]TransformType `json:"transforms,omitempty"`
}

// PoliciesCreateOrUpdateFuture an abstraction for monitoring and retrieving the results of a long-running
// operation.
type PoliciesCreateOrUpdateFuture struct {
	azure.FutureAPI
	// Result returns the result of the asynchronous operation.
	// If the operation has not completed it will return an error.
	Result func(PoliciesClient) (WebApplicationFirewallPolicy, error)
}

// PoliciesDeleteFuture an abstraction for monitoring and retrieving the results of a long-running
// operation.
type PoliciesDeleteFuture struct {
	azure.FutureAPI
	// Result returns the result of the asynchronous operation.
	// If the operation has not completed it will return an error.
	Result func(PoliciesClient) (autorest.Response, error)
}

// PolicySettings defines top-level WebApplicationFirewallPolicy configuration settings.
type PolicySettings struct {
	// EnabledState - Describes if the policy is in enabled or disabled state. Defaults to Enabled if not specified. Possible values include: 'PolicyEnabledStateDisabled', 'PolicyEnabledStateEnabled'
	EnabledState PolicyEnabledState `json:"enabledState,omitempty"`
	// Mode - Describes if it is in detection mode or prevention mode at policy level. Possible values include: 'Prevention', 'Detection'
	Mode PolicyMode `json:"mode,omitempty"`
	// RedirectURL - If action type is redirect, this field represents redirect URL for the client.
	RedirectURL *string `json:"redirectUrl,omitempty"`
	// CustomBlockResponseStatusCode - If the action type is block, customer can override the response status code.
	CustomBlockResponseStatusCode *int32 `json:"customBlockResponseStatusCode,omitempty"`
	// CustomBlockResponseBody - If the action type is block, customer can override the response body. The body must be specified in base64 encoding.
	CustomBlockResponseBody *string `json:"customBlockResponseBody,omitempty"`
}

// Properties the JSON object that contains the properties required to create an endpoint.
type Properties struct {
	// ResourceState - Resource status of the Front Door. Possible values include: 'ResourceStateCreating', 'ResourceStateEnabling', 'ResourceStateEnabled', 'ResourceStateDisabling', 'ResourceStateDisabled', 'ResourceStateDeleting'
	ResourceState ResourceState `json:"resourceState,omitempty"`
	// ProvisioningState - READ-ONLY; Provisioning state of the Front Door.
	ProvisioningState *string `json:"provisioningState,omitempty"`
	// Cname - READ-ONLY; The host that each frontendEndpoint must CNAME to.
	Cname *string `json:"cname,omitempty"`
	// FriendlyName - A friendly name for the frontDoor
	FriendlyName *string `json:"friendlyName,omitempty"`
	// RoutingRules - Routing rules associated with this Front Door.
	RoutingRules *[]RoutingRule `json:"routingRules,omitempty"`
	// LoadBalancingSettings - Load balancing settings associated with this Front Door instance.
	LoadBalancingSettings *[]LoadBalancingSettingsModel `json:"loadBalancingSettings,omitempty"`
	// HealthProbeSettings - Health probe settings associated with this Front Door instance.
	HealthProbeSettings *[]HealthProbeSettingsModel `json:"healthProbeSettings,omitempty"`
	// BackendPools - Backend pools available to routing rules.
	BackendPools *[]BackendPool `json:"backendPools,omitempty"`
	// FrontendEndpoints - Frontend endpoints available to routing rules.
	FrontendEndpoints *[]FrontendEndpoint `json:"frontendEndpoints,omitempty"`
	// BackendPoolsSettings - Settings for all backendPools
	BackendPoolsSettings *BackendPoolsSettings `json:"backendPoolsSettings,omitempty"`
	// EnabledState - Operational status of the Front Door load balancer. Permitted values are 'Enabled' or 'Disabled'. Possible values include: 'EnabledStateEnabled', 'EnabledStateDisabled'
	EnabledState EnabledState `json:"enabledState,omitempty"`
}

// MarshalJSON is the custom marshaler for Properties.
func (p Properties) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]interface{})
	if p.ResourceState != "" {
		objectMap["resourceState"] = p.ResourceState
	}
	if p.FriendlyName != nil {
		objectMap["friendlyName"] = p.FriendlyName
	}
	if p.RoutingRules != nil {
		objectMap["routingRules"] = p.RoutingRules
	}
	if p.LoadBalancingSettings != nil {
		objectMap["loadBalancingSettings"] = p.LoadBalancingSettings
	}
	if p.HealthProbeSettings != nil {
		objectMap["healthProbeSettings"] = p.HealthProbeSettings
	}
	if p.BackendPools != nil {
		objectMap["backendPools"] = p.BackendPools
	}
	if p.FrontendEndpoints != nil {
		objectMap["frontendEndpoints"] = p.FrontendEndpoints
	}
	if p.BackendPoolsSettings != nil {
		objectMap["backendPoolsSettings"] = p.BackendPoolsSettings
	}
	if p.EnabledState != "" {
		objectMap["enabledState"] = p.EnabledState
	}
	return json.Marshal(objectMap)
}

// PurgeParameters parameters required for content purge.
type PurgeParameters struct {
	// ContentPaths - The path to the content to be purged. Can describe a file path or a wild card directory.
	ContentPaths *[]string `json:"contentPaths,omitempty"`
}

// RedirectConfiguration describes Redirect Route.
type RedirectConfiguration struct {
	// RedirectType - The redirect type the rule will use when redirecting traffic. Possible values include: 'Moved', 'Found', 'TemporaryRedirect', 'PermanentRedirect'
	RedirectType RedirectType `json:"redirectType,omitempty"`
	// RedirectProtocol - The protocol of the destination to where the traffic is redirected. Possible values include: 'RedirectProtocolHTTPOnly', 'RedirectProtocolHTTPSOnly', 'RedirectProtocolMatchRequest'
	RedirectProtocol RedirectProtocol `json:"redirectProtocol,omitempty"`
	// CustomHost - Host to redirect. Leave empty to use the incoming host as the destination host.
	CustomHost *string `json:"customHost,omitempty"`
	// CustomPath - The full path to redirect. Path cannot be empty and must start with /. Leave empty to use the incoming path as destination path.
	CustomPath *string `json:"customPath,omitempty"`
	// CustomFragment - Fragment to add to the redirect URL. Fragment is the part of the URL that comes after #. Do not include the #.
	CustomFragment *string `json:"customFragment,omitempty"`
	// CustomQueryString - The set of query strings to be placed in the redirect URL. Setting this value would replace any existing query string; leave empty to preserve the incoming query string. Query string must be in <key>=<value> format. The first ? and & will be added automatically so do not include them in the front, but do separate multiple query strings with &.
	CustomQueryString *string `json:"customQueryString,omitempty"`
	// OdataType - Possible values include: 'OdataTypeRouteConfiguration', 'OdataTypeMicrosoftAzureFrontDoorModelsFrontdoorForwardingConfiguration', 'OdataTypeMicrosoftAzureFrontDoorModelsFrontdoorRedirectConfiguration'
	OdataType OdataType `json:"@odata.type,omitempty"`
}

// MarshalJSON is the custom marshaler for RedirectConfiguration.
func (rc RedirectConfiguration) MarshalJSON() ([]byte, error) {
	rc.OdataType = OdataTypeMicrosoftAzureFrontDoorModelsFrontdoorRedirectConfiguration
	objectMap := make(map[string]interface{})
	if rc.RedirectType != "" {
		objectMap["redirectType"] = rc.RedirectType
	}
	if rc.RedirectProtocol != "" {
		objectMap["redirectProtocol"] = rc.RedirectProtocol
	}
	if rc.CustomHost != nil {
		objectMap["customHost"] = rc.CustomHost
	}
	if rc.CustomPath != nil {
		objectMap["customPath"] = rc.CustomPath
	}
	if rc.CustomFragment != nil {
		objectMap["customFragment"] = rc.CustomFragment
	}
	if rc.CustomQueryString != nil {
		objectMap["customQueryString"] = rc.CustomQueryString
	}
	if rc.OdataType != "" {
		objectMap["@odata.type"] = rc.OdataType
	}
	return json.Marshal(objectMap)
}

// AsForwardingConfiguration is the BasicRouteConfiguration implementation for RedirectConfiguration.
func (rc RedirectConfiguration) AsForwardingConfiguration() (*ForwardingConfiguration, bool) {
	return nil, false
}

// AsRedirectConfiguration is the BasicRouteConfiguration implementation for RedirectConfiguration.
func (rc RedirectConfiguration) AsRedirectConfiguration() (*RedirectConfiguration, bool) {
	return &rc, true
}

// AsRouteConfiguration is the BasicRouteConfiguration implementation for RedirectConfiguration.
func (rc RedirectConfiguration) AsRouteConfiguration() (*RouteConfiguration, bool) {
	return nil, false
}

// AsBasicRouteConfiguration is the BasicRouteConfiguration implementation for RedirectConfiguration.
func (rc RedirectConfiguration) AsBasicRouteConfiguration() (BasicRouteConfiguration, bool) {
	return &rc, true
}

// Resource common resource representation.
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"`
	// 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)
}

// BasicRouteConfiguration base class for all types of Route.
type BasicRouteConfiguration interface {
	AsForwardingConfiguration() (*ForwardingConfiguration, bool)
	AsRedirectConfiguration() (*RedirectConfiguration, bool)
	AsRouteConfiguration() (*RouteConfiguration, bool)
}

// RouteConfiguration base class for all types of Route.
type RouteConfiguration struct {
	// OdataType - Possible values include: 'OdataTypeRouteConfiguration', 'OdataTypeMicrosoftAzureFrontDoorModelsFrontdoorForwardingConfiguration', 'OdataTypeMicrosoftAzureFrontDoorModelsFrontdoorRedirectConfiguration'
	OdataType OdataType `json:"@odata.type,omitempty"`
}

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

	switch m["@odata.type"] {
	case string(OdataTypeMicrosoftAzureFrontDoorModelsFrontdoorForwardingConfiguration):
		var fc ForwardingConfiguration
		err := json.Unmarshal(body, &fc)
		return fc, err
	case string(OdataTypeMicrosoftAzureFrontDoorModelsFrontdoorRedirectConfiguration):
		var rc RedirectConfiguration
		err := json.Unmarshal(body, &rc)
		return rc, err
	default:
		var rc RouteConfiguration
		err := json.Unmarshal(body, &rc)
		return rc, err
	}
}
func unmarshalBasicRouteConfigurationArray(body []byte) ([]BasicRouteConfiguration, error) {
	var rawMessages []*json.RawMessage
	err := json.Unmarshal(body, &rawMessages)
	if err != nil {
		return nil, err
	}

	rcArray := make([]BasicRouteConfiguration, len(rawMessages))

	for index, rawMessage := range rawMessages {
		rc, err := unmarshalBasicRouteConfiguration(*rawMessage)
		if err != nil {
			return nil, err
		}
		rcArray[index] = rc
	}
	return rcArray, nil
}

// MarshalJSON is the custom marshaler for RouteConfiguration.
func (rc RouteConfiguration) MarshalJSON() ([]byte, error) {
	rc.OdataType = OdataTypeRouteConfiguration
	objectMap := make(map[string]interface{})
	if rc.OdataType != "" {
		objectMap["@odata.type"] = rc.OdataType
	}
	return json.Marshal(objectMap)
}

// AsForwardingConfiguration is the BasicRouteConfiguration implementation for RouteConfiguration.
func (rc RouteConfiguration) AsForwardingConfiguration() (*ForwardingConfiguration, bool) {
	return nil, false
}

// AsRedirectConfiguration is the BasicRouteConfiguration implementation for RouteConfiguration.
func (rc RouteConfiguration) AsRedirectConfiguration() (*RedirectConfiguration, bool) {
	return nil, false
}

// AsRouteConfiguration is the BasicRouteConfiguration implementation for RouteConfiguration.
func (rc RouteConfiguration) AsRouteConfiguration() (*RouteConfiguration, bool) {
	return &rc, true
}

// AsBasicRouteConfiguration is the BasicRouteConfiguration implementation for RouteConfiguration.
func (rc RouteConfiguration) AsBasicRouteConfiguration() (BasicRouteConfiguration, bool) {
	return &rc, true
}

// RoutingRule a routing rule represents a specification for traffic to treat and where to send it, along
// with health probe information.
type RoutingRule struct {
	// RoutingRuleProperties - Properties of the Front Door Routing Rule
	*RoutingRuleProperties `json:"properties,omitempty"`
	// Name - Resource name.
	Name *string `json:"name,omitempty"`
	// Type - READ-ONLY; Resource type.
	Type *string `json:"type,omitempty"`
	// ID - Resource ID.
	ID *string `json:"id,omitempty"`
}

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

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

	return nil
}

// RoutingRuleListResult result of the request to list Routing Rules. It contains a list of Routing Rule
// objects and a URL link to get the next set of results.
type RoutingRuleListResult struct {
	// Value - READ-ONLY; List of Routing Rules within a Front Door.
	Value *[]RoutingRule `json:"value,omitempty"`
	// NextLink - URL to get the next set of RoutingRule objects if there are any.
	NextLink *string `json:"nextLink,omitempty"`
}

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

// RoutingRuleProperties the JSON object that contains the properties required to create a routing rule.
type RoutingRuleProperties struct {
	// ResourceState - Resource status. Possible values include: 'ResourceStateCreating', 'ResourceStateEnabling', 'ResourceStateEnabled', 'ResourceStateDisabling', 'ResourceStateDisabled', 'ResourceStateDeleting'
	ResourceState ResourceState `json:"resourceState,omitempty"`
	// FrontendEndpoints - Frontend endpoints associated with this rule
	FrontendEndpoints *[]SubResource `json:"frontendEndpoints,omitempty"`
	// AcceptedProtocols - Protocol schemes to match for this rule
	AcceptedProtocols *[]Protocol `json:"acceptedProtocols,omitempty"`
	// PatternsToMatch - The route patterns of the rule.
	PatternsToMatch *[]string `json:"patternsToMatch,omitempty"`
	// EnabledState - Whether to enable use of this rule. Permitted values are 'Enabled' or 'Disabled'. Possible values include: 'RoutingRuleEnabledStateEnabled', 'RoutingRuleEnabledStateDisabled'
	EnabledState RoutingRuleEnabledState `json:"enabledState,omitempty"`
	// RouteConfiguration - A reference to the routing configuration.
	RouteConfiguration BasicRouteConfiguration `json:"routeConfiguration,omitempty"`
}

// UnmarshalJSON is the custom unmarshaler for RoutingRuleProperties struct.
func (rrp *RoutingRuleProperties) 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 "resourceState":
			if v != nil {
				var resourceState ResourceState
				err = json.Unmarshal(*v, &resourceState)
				if err != nil {
					return err
				}
				rrp.ResourceState = resourceState
			}
		case "frontendEndpoints":
			if v != nil {
				var frontendEndpoints []SubResource
				err = json.Unmarshal(*v, &frontendEndpoints)
				if err != nil {
					return err
				}
				rrp.FrontendEndpoints = &frontendEndpoints
			}
		case "acceptedProtocols":
			if v != nil {
				var acceptedProtocols []Protocol
				err = json.Unmarshal(*v, &acceptedProtocols)
				if err != nil {
					return err
				}
				rrp.AcceptedProtocols = &acceptedProtocols
			}
		case "patternsToMatch":
			if v != nil {
				var patternsToMatch []string
				err = json.Unmarshal(*v, &patternsToMatch)
				if err != nil {
					return err
				}
				rrp.PatternsToMatch = &patternsToMatch
			}
		case "enabledState":
			if v != nil {
				var enabledState RoutingRuleEnabledState
				err = json.Unmarshal(*v, &enabledState)
				if err != nil {
					return err
				}
				rrp.EnabledState = enabledState
			}
		case "routeConfiguration":
			if v != nil {
				routeConfiguration, err := unmarshalBasicRouteConfiguration(*v)
				if err != nil {
					return err
				}
				rrp.RouteConfiguration = routeConfiguration
			}
		}
	}

	return nil
}

// RoutingRuleUpdateParameters routing rules to apply to an endpoint
type RoutingRuleUpdateParameters struct {
	// FrontendEndpoints - Frontend endpoints associated with this rule
	FrontendEndpoints *[]SubResource `json:"frontendEndpoints,omitempty"`
	// AcceptedProtocols - Protocol schemes to match for this rule
	AcceptedProtocols *[]Protocol `json:"acceptedProtocols,omitempty"`
	// PatternsToMatch - The route patterns of the rule.
	PatternsToMatch *[]string `json:"patternsToMatch,omitempty"`
	// EnabledState - Whether to enable use of this rule. Permitted values are 'Enabled' or 'Disabled'. Possible values include: 'RoutingRuleEnabledStateEnabled', 'RoutingRuleEnabledStateDisabled'
	EnabledState RoutingRuleEnabledState `json:"enabledState,omitempty"`
	// RouteConfiguration - A reference to the routing configuration.
	RouteConfiguration BasicRouteConfiguration `json:"routeConfiguration,omitempty"`
}

// UnmarshalJSON is the custom unmarshaler for RoutingRuleUpdateParameters struct.
func (rrup *RoutingRuleUpdateParameters) 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 "frontendEndpoints":
			if v != nil {
				var frontendEndpoints []SubResource
				err = json.Unmarshal(*v, &frontendEndpoints)
				if err != nil {
					return err
				}
				rrup.FrontendEndpoints = &frontendEndpoints
			}
		case "acceptedProtocols":
			if v != nil {
				var acceptedProtocols []Protocol
				err = json.Unmarshal(*v, &acceptedProtocols)
				if err != nil {
					return err
				}
				rrup.AcceptedProtocols = &acceptedProtocols
			}
		case "patternsToMatch":
			if v != nil {
				var patternsToMatch []string
				err = json.Unmarshal(*v, &patternsToMatch)
				if err != nil {
					return err
				}
				rrup.PatternsToMatch = &patternsToMatch
			}
		case "enabledState":
			if v != nil {
				var enabledState RoutingRuleEnabledState
				err = json.Unmarshal(*v, &enabledState)
				if err != nil {
					return err
				}
				rrup.EnabledState = enabledState
			}
		case "routeConfiguration":
			if v != nil {
				routeConfiguration, err := unmarshalBasicRouteConfiguration(*v)
				if err != nil {
					return err
				}
				rrup.RouteConfiguration = routeConfiguration
			}
		}
	}

	return nil
}

// SubResource reference to another subresource.
type SubResource struct {
	// ID - Resource ID.
	ID *string `json:"id,omitempty"`
}

// TagsObject tags object for patch operations.
type TagsObject struct {
	// Tags - Resource tags.
	Tags map[string]*string `json:"tags"`
}

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

// UpdateParameters the properties needed to update a Front Door
type UpdateParameters struct {
	// FriendlyName - A friendly name for the frontDoor
	FriendlyName *string `json:"friendlyName,omitempty"`
	// RoutingRules - Routing rules associated with this Front Door.
	RoutingRules *[]RoutingRule `json:"routingRules,omitempty"`
	// LoadBalancingSettings - Load balancing settings associated with this Front Door instance.
	LoadBalancingSettings *[]LoadBalancingSettingsModel `json:"loadBalancingSettings,omitempty"`
	// HealthProbeSettings - Health probe settings associated with this Front Door instance.
	HealthProbeSettings *[]HealthProbeSettingsModel `json:"healthProbeSettings,omitempty"`
	// BackendPools - Backend pools available to routing rules.
	BackendPools *[]BackendPool `json:"backendPools,omitempty"`
	// FrontendEndpoints - Frontend endpoints available to routing rules.
	FrontendEndpoints *[]FrontendEndpoint `json:"frontendEndpoints,omitempty"`
	// BackendPoolsSettings - Settings for all backendPools
	BackendPoolsSettings *BackendPoolsSettings `json:"backendPoolsSettings,omitempty"`
	// EnabledState - Operational status of the Front Door load balancer. Permitted values are 'Enabled' or 'Disabled'. Possible values include: 'EnabledStateEnabled', 'EnabledStateDisabled'
	EnabledState EnabledState `json:"enabledState,omitempty"`
}

// ValidateCustomDomainInput input of the custom domain to be validated for DNS mapping.
type ValidateCustomDomainInput struct {
	// HostName - The host name of the custom domain. Must be a domain name.
	HostName *string `json:"hostName,omitempty"`
}

// ValidateCustomDomainOutput output of custom domain validation.
type ValidateCustomDomainOutput struct {
	autorest.Response `json:"-"`
	// CustomDomainValidated - READ-ONLY; Indicates whether the custom domain is valid or not.
	CustomDomainValidated *bool `json:"customDomainValidated,omitempty"`
	// Reason - READ-ONLY; The reason why the custom domain is not valid.
	Reason *string `json:"reason,omitempty"`
	// Message - READ-ONLY; Error message describing why the custom domain is not valid.
	Message *string `json:"message,omitempty"`
}

// WebApplicationFirewallPolicy defines web application firewall policy.
type WebApplicationFirewallPolicy struct {
	autorest.Response `json:"-"`
	// WebApplicationFirewallPolicyProperties - Properties of the web application firewall policy.
	*WebApplicationFirewallPolicyProperties `json:"properties,omitempty"`
	// Etag - Gets a unique read-only string that changes whenever the resource is updated.
	Etag *string `json:"etag,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"`
	// Location - Resource location.
	Location *string `json:"location,omitempty"`
	// Tags - Resource tags.
	Tags map[string]*string `json:"tags"`
}

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

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

	return nil
}

// WebApplicationFirewallPolicyList defines a list of WebApplicationFirewallPolicies. It contains a list of
// WebApplicationFirewallPolicy objects and a URL link to get the next set of results.
type WebApplicationFirewallPolicyList struct {
	autorest.Response `json:"-"`
	// Value - READ-ONLY; List of WebApplicationFirewallPolicies within a resource group.
	Value *[]WebApplicationFirewallPolicy `json:"value,omitempty"`
	// NextLink - URL to get the next set of WebApplicationFirewallPolicy objects if there are any.
	NextLink *string `json:"nextLink,omitempty"`
}

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

// WebApplicationFirewallPolicyListIterator provides access to a complete listing of
// WebApplicationFirewallPolicy values.
type WebApplicationFirewallPolicyListIterator struct {
	i    int
	page WebApplicationFirewallPolicyListPage
}

// 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 *WebApplicationFirewallPolicyListIterator) NextWithContext(ctx context.Context) (err error) {
	if tracing.IsEnabled() {
		ctx = tracing.StartSpan(ctx, fqdn+"/WebApplicationFirewallPolicyListIterator.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 *WebApplicationFirewallPolicyListIterator) Next() error {
	return iter.NextWithContext(context.Background())
}

// NotDone returns true if the enumeration should be started or is not yet complete.
func (iter WebApplicationFirewallPolicyListIterator) 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 WebApplicationFirewallPolicyListIterator) Response() WebApplicationFirewallPolicyList {
	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 WebApplicationFirewallPolicyListIterator) Value() WebApplicationFirewallPolicy {
	if !iter.page.NotDone() {
		return WebApplicationFirewallPolicy{}
	}
	return iter.page.Values()[iter.i]
}

// Creates a new instance of the WebApplicationFirewallPolicyListIterator type.
func NewWebApplicationFirewallPolicyListIterator(page WebApplicationFirewallPolicyListPage) WebApplicationFirewallPolicyListIterator {
	return WebApplicationFirewallPolicyListIterator{page: page}
}

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

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

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

// WebApplicationFirewallPolicyListPage contains a page of WebApplicationFirewallPolicy values.
type WebApplicationFirewallPolicyListPage struct {
	fn    func(context.Context, WebApplicationFirewallPolicyList) (WebApplicationFirewallPolicyList, error)
	wafpl WebApplicationFirewallPolicyList
}

// 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 *WebApplicationFirewallPolicyListPage) NextWithContext(ctx context.Context) (err error) {
	if tracing.IsEnabled() {
		ctx = tracing.StartSpan(ctx, fqdn+"/WebApplicationFirewallPolicyListPage.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.wafpl)
		if err != nil {
			return err
		}
		page.wafpl = 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 *WebApplicationFirewallPolicyListPage) Next() error {
	return page.NextWithContext(context.Background())
}

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

// Response returns the raw server response from the last page request.
func (page WebApplicationFirewallPolicyListPage) Response() WebApplicationFirewallPolicyList {
	return page.wafpl
}

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

// Creates a new instance of the WebApplicationFirewallPolicyListPage type.
func NewWebApplicationFirewallPolicyListPage(cur WebApplicationFirewallPolicyList, getNextPage func(context.Context, WebApplicationFirewallPolicyList) (WebApplicationFirewallPolicyList, error)) WebApplicationFirewallPolicyListPage {
	return WebApplicationFirewallPolicyListPage{
		fn:    getNextPage,
		wafpl: cur,
	}
}

// WebApplicationFirewallPolicyProperties defines web application firewall policy properties.
type WebApplicationFirewallPolicyProperties struct {
	// PolicySettings - Describes settings for the policy.
	PolicySettings *PolicySettings `json:"policySettings,omitempty"`
	// CustomRules - Describes custom rules inside the policy.
	CustomRules *CustomRuleList `json:"customRules,omitempty"`
	// ManagedRules - Describes managed rules inside the policy.
	ManagedRules *ManagedRuleSetList `json:"managedRules,omitempty"`
	// FrontendEndpointLinks - READ-ONLY; Describes Frontend Endpoints associated with this Web Application Firewall policy.
	FrontendEndpointLinks *[]FrontendEndpointLink `json:"frontendEndpointLinks,omitempty"`
	// ProvisioningState - READ-ONLY; Provisioning state of the policy.
	ProvisioningState *string `json:"provisioningState,omitempty"`
	// ResourceState - READ-ONLY; Possible values include: 'PolicyResourceStateCreating', 'PolicyResourceStateEnabling', 'PolicyResourceStateEnabled', 'PolicyResourceStateDisabling', 'PolicyResourceStateDisabled', 'PolicyResourceStateDeleting'
	ResourceState PolicyResourceState `json:"resourceState,omitempty"`
}

// MarshalJSON is the custom marshaler for WebApplicationFirewallPolicyProperties.
func (wafpp WebApplicationFirewallPolicyProperties) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]interface{})
	if wafpp.PolicySettings != nil {
		objectMap["policySettings"] = wafpp.PolicySettings
	}
	if wafpp.CustomRules != nil {
		objectMap["customRules"] = wafpp.CustomRules
	}
	if wafpp.ManagedRules != nil {
		objectMap["managedRules"] = wafpp.ManagedRules
	}
	return json.Marshal(objectMap)
}
