package peering

// 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/to"
	"github.com/Azure/go-autorest/tracing"
	"net/http"
)

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

// ConnectionState enumerates the values for connection state.
type ConnectionState string

const (
	// Active ...
	Active ConnectionState = "Active"
	// Approved ...
	Approved ConnectionState = "Approved"
	// None ...
	None ConnectionState = "None"
	// PendingApproval ...
	PendingApproval ConnectionState = "PendingApproval"
	// ProvisioningCompleted ...
	ProvisioningCompleted ConnectionState = "ProvisioningCompleted"
	// ProvisioningFailed ...
	ProvisioningFailed ConnectionState = "ProvisioningFailed"
	// ProvisioningStarted ...
	ProvisioningStarted ConnectionState = "ProvisioningStarted"
	// Validating ...
	Validating ConnectionState = "Validating"
)

// PossibleConnectionStateValues returns an array of possible values for the ConnectionState const type.
func PossibleConnectionStateValues() []ConnectionState {
	return []ConnectionState{Active, Approved, None, PendingApproval, ProvisioningCompleted, ProvisioningFailed, ProvisioningStarted, Validating}
}

// Family enumerates the values for family.
type Family string

const (
	// Direct ...
	Direct Family = "Direct"
	// Exchange ...
	Exchange Family = "Exchange"
)

// PossibleFamilyValues returns an array of possible values for the Family const type.
func PossibleFamilyValues() []Family {
	return []Family{Direct, Exchange}
}

// Kind enumerates the values for kind.
type Kind string

const (
	// KindDirect ...
	KindDirect Kind = "Direct"
	// KindExchange ...
	KindExchange Kind = "Exchange"
)

// PossibleKindValues returns an array of possible values for the Kind const type.
func PossibleKindValues() []Kind {
	return []Kind{KindDirect, KindExchange}
}

// Name enumerates the values for name.
type Name string

const (
	// BasicDirectFree ...
	BasicDirectFree Name = "Basic_Direct_Free"
	// BasicExchangeFree ...
	BasicExchangeFree Name = "Basic_Exchange_Free"
	// PremiumDirectFree ...
	PremiumDirectFree Name = "Premium_Direct_Free"
	// PremiumExchangeMetered ...
	PremiumExchangeMetered Name = "Premium_Exchange_Metered"
)

// PossibleNameValues returns an array of possible values for the Name const type.
func PossibleNameValues() []Name {
	return []Name{BasicDirectFree, BasicExchangeFree, PremiumDirectFree, PremiumExchangeMetered}
}

// ProvisioningState enumerates the values for provisioning state.
type ProvisioningState string

const (
	// Deleting ...
	Deleting ProvisioningState = "Deleting"
	// Failed ...
	Failed ProvisioningState = "Failed"
	// Succeeded ...
	Succeeded ProvisioningState = "Succeeded"
	// Updating ...
	Updating ProvisioningState = "Updating"
)

// PossibleProvisioningStateValues returns an array of possible values for the ProvisioningState const type.
func PossibleProvisioningStateValues() []ProvisioningState {
	return []ProvisioningState{Deleting, Failed, Succeeded, Updating}
}

// SessionStateV4 enumerates the values for session state v4.
type SessionStateV4 string

const (
	// SessionStateV4Active ...
	SessionStateV4Active SessionStateV4 = "Active"
	// SessionStateV4Connect ...
	SessionStateV4Connect SessionStateV4 = "Connect"
	// SessionStateV4Established ...
	SessionStateV4Established SessionStateV4 = "Established"
	// SessionStateV4Idle ...
	SessionStateV4Idle SessionStateV4 = "Idle"
	// SessionStateV4None ...
	SessionStateV4None SessionStateV4 = "None"
	// SessionStateV4OpenConfirm ...
	SessionStateV4OpenConfirm SessionStateV4 = "OpenConfirm"
	// SessionStateV4OpenSent ...
	SessionStateV4OpenSent SessionStateV4 = "OpenSent"
	// SessionStateV4PendingAdd ...
	SessionStateV4PendingAdd SessionStateV4 = "PendingAdd"
	// SessionStateV4PendingRemove ...
	SessionStateV4PendingRemove SessionStateV4 = "PendingRemove"
	// SessionStateV4PendingUpdate ...
	SessionStateV4PendingUpdate SessionStateV4 = "PendingUpdate"
)

// PossibleSessionStateV4Values returns an array of possible values for the SessionStateV4 const type.
func PossibleSessionStateV4Values() []SessionStateV4 {
	return []SessionStateV4{SessionStateV4Active, SessionStateV4Connect, SessionStateV4Established, SessionStateV4Idle, SessionStateV4None, SessionStateV4OpenConfirm, SessionStateV4OpenSent, SessionStateV4PendingAdd, SessionStateV4PendingRemove, SessionStateV4PendingUpdate}
}

// SessionStateV6 enumerates the values for session state v6.
type SessionStateV6 string

const (
	// SessionStateV6Active ...
	SessionStateV6Active SessionStateV6 = "Active"
	// SessionStateV6Connect ...
	SessionStateV6Connect SessionStateV6 = "Connect"
	// SessionStateV6Established ...
	SessionStateV6Established SessionStateV6 = "Established"
	// SessionStateV6Idle ...
	SessionStateV6Idle SessionStateV6 = "Idle"
	// SessionStateV6None ...
	SessionStateV6None SessionStateV6 = "None"
	// SessionStateV6OpenConfirm ...
	SessionStateV6OpenConfirm SessionStateV6 = "OpenConfirm"
	// SessionStateV6OpenSent ...
	SessionStateV6OpenSent SessionStateV6 = "OpenSent"
	// SessionStateV6PendingAdd ...
	SessionStateV6PendingAdd SessionStateV6 = "PendingAdd"
	// SessionStateV6PendingRemove ...
	SessionStateV6PendingRemove SessionStateV6 = "PendingRemove"
	// SessionStateV6PendingUpdate ...
	SessionStateV6PendingUpdate SessionStateV6 = "PendingUpdate"
)

// PossibleSessionStateV6Values returns an array of possible values for the SessionStateV6 const type.
func PossibleSessionStateV6Values() []SessionStateV6 {
	return []SessionStateV6{SessionStateV6Active, SessionStateV6Connect, SessionStateV6Established, SessionStateV6Idle, SessionStateV6None, SessionStateV6OpenConfirm, SessionStateV6OpenSent, SessionStateV6PendingAdd, SessionStateV6PendingRemove, SessionStateV6PendingUpdate}
}

// Size enumerates the values for size.
type Size string

const (
	// Free ...
	Free Size = "Free"
	// Metered ...
	Metered Size = "Metered"
	// Unlimited ...
	Unlimited Size = "Unlimited"
)

// PossibleSizeValues returns an array of possible values for the Size const type.
func PossibleSizeValues() []Size {
	return []Size{Free, Metered, Unlimited}
}

// Tier enumerates the values for tier.
type Tier string

const (
	// Basic ...
	Basic Tier = "Basic"
	// Premium ...
	Premium Tier = "Premium"
)

// PossibleTierValues returns an array of possible values for the Tier const type.
func PossibleTierValues() []Tier {
	return []Tier{Basic, Premium}
}

// ValidationState enumerates the values for validation state.
type ValidationState string

const (
	// ValidationStateApproved ...
	ValidationStateApproved ValidationState = "Approved"
	// ValidationStateFailed ...
	ValidationStateFailed ValidationState = "Failed"
	// ValidationStateNone ...
	ValidationStateNone ValidationState = "None"
	// ValidationStatePending ...
	ValidationStatePending ValidationState = "Pending"
)

// PossibleValidationStateValues returns an array of possible values for the ValidationState const type.
func PossibleValidationStateValues() []ValidationState {
	return []ValidationState{ValidationStateApproved, ValidationStateFailed, ValidationStateNone, ValidationStatePending}
}

// BandwidthOffer the properties that define a peering bandwidth offer.
type BandwidthOffer struct {
	// OfferName - The name of the bandwidth offer.
	OfferName *string `json:"offerName,omitempty"`
	// ValueInMbps - The value of the bandwidth offer in Mbps.
	ValueInMbps *int32 `json:"valueInMbps,omitempty"`
}

// BgpSession the properties that define a BGP session.
type BgpSession struct {
	// SessionPrefixV4 - The IPv4 prefix that contains both ends' IPv4 addresses.
	SessionPrefixV4 *string `json:"sessionPrefixV4,omitempty"`
	// SessionPrefixV6 - The IPv6 prefix that contains both ends' IPv6 addresses.
	SessionPrefixV6 *string `json:"sessionPrefixV6,omitempty"`
	// MicrosoftSessionIPv4Address - READ-ONLY; The IPv4 session address on Microsoft's end.
	MicrosoftSessionIPv4Address *string `json:"microsoftSessionIPv4Address,omitempty"`
	// MicrosoftSessionIPv6Address - READ-ONLY; The IPv6 session address on Microsoft's end.
	MicrosoftSessionIPv6Address *string `json:"microsoftSessionIPv6Address,omitempty"`
	// PeerSessionIPv4Address - The IPv4 session address on peer's end.
	PeerSessionIPv4Address *string `json:"peerSessionIPv4Address,omitempty"`
	// PeerSessionIPv6Address - The IPv6 session address on peer's end.
	PeerSessionIPv6Address *string `json:"peerSessionIPv6Address,omitempty"`
	// SessionStateV4 - READ-ONLY; The state of the IPv4 session. Possible values include: 'SessionStateV4None', 'SessionStateV4Idle', 'SessionStateV4Connect', 'SessionStateV4Active', 'SessionStateV4OpenSent', 'SessionStateV4OpenConfirm', 'SessionStateV4Established', 'SessionStateV4PendingAdd', 'SessionStateV4PendingUpdate', 'SessionStateV4PendingRemove'
	SessionStateV4 SessionStateV4 `json:"sessionStateV4,omitempty"`
	// SessionStateV6 - READ-ONLY; The state of the IPv6 session. Possible values include: 'SessionStateV6None', 'SessionStateV6Idle', 'SessionStateV6Connect', 'SessionStateV6Active', 'SessionStateV6OpenSent', 'SessionStateV6OpenConfirm', 'SessionStateV6Established', 'SessionStateV6PendingAdd', 'SessionStateV6PendingUpdate', 'SessionStateV6PendingRemove'
	SessionStateV6 SessionStateV6 `json:"sessionStateV6,omitempty"`
	// MaxPrefixesAdvertisedV4 - The maximum number of prefixes advertised over the IPv4 session.
	MaxPrefixesAdvertisedV4 *int32 `json:"maxPrefixesAdvertisedV4,omitempty"`
	// MaxPrefixesAdvertisedV6 - The maximum number of prefixes advertised over the IPv6 session.
	MaxPrefixesAdvertisedV6 *int32 `json:"maxPrefixesAdvertisedV6,omitempty"`
	// Md5AuthenticationKey - The MD5 authentication key of the session.
	Md5AuthenticationKey *string `json:"md5AuthenticationKey,omitempty"`
}

// ContactInfo the contact information of the peer.
type ContactInfo struct {
	// Emails - The list of email addresses.
	Emails *[]string `json:"emails,omitempty"`
	// Phone - The list of contact numbers.
	Phone *[]string `json:"phone,omitempty"`
}

// DirectConnection the properties that define a direct connection.
type DirectConnection struct {
	// BandwidthInMbps - The bandwidth of the connection.
	BandwidthInMbps *int32 `json:"bandwidthInMbps,omitempty"`
	// ProvisionedBandwidthInMbps - The bandwidth that is actually provisioned.
	ProvisionedBandwidthInMbps *int32 `json:"provisionedBandwidthInMbps,omitempty"`
	// PeeringDBFacilityID - The PeeringDB.com ID of the facility at which the connection has to be set up.
	PeeringDBFacilityID *int32 `json:"peeringDBFacilityId,omitempty"`
	// ConnectionState - READ-ONLY; The state of the connection. Possible values include: 'None', 'PendingApproval', 'Approved', 'ProvisioningStarted', 'ProvisioningFailed', 'ProvisioningCompleted', 'Validating', 'Active'
	ConnectionState ConnectionState `json:"connectionState,omitempty"`
	// BgpSession - The BGP session associated with the connection.
	BgpSession *BgpSession `json:"bgpSession,omitempty"`
}

// DirectPeeringFacility the properties that define a direct peering facility.
type DirectPeeringFacility struct {
	// Address - The address of the direct peering facility.
	Address *string `json:"address,omitempty"`
	// PeeringDBFacilityID - The PeeringDB.com ID of the facility.
	PeeringDBFacilityID *int32 `json:"peeringDBFacilityId,omitempty"`
	// PeeringDBFacilityLink - The PeeringDB.com URL of the facility.
	PeeringDBFacilityLink *string `json:"peeringDBFacilityLink,omitempty"`
}

// ErrorResponse the error response that indicates why an operation has failed.
type ErrorResponse struct {
	// Code - READ-ONLY; The error code.
	Code *string `json:"code,omitempty"`
	// Message - READ-ONLY; The error message.
	Message *string `json:"message,omitempty"`
}

// ExchangeConnection the properties that define an exchange connection.
type ExchangeConnection struct {
	// PeeringDBFacilityID - The PeeringDB.com ID of the facility at which the connection has to be set up.
	PeeringDBFacilityID *int32 `json:"peeringDBFacilityId,omitempty"`
	// ConnectionState - READ-ONLY; The state of the connection. Possible values include: 'None', 'PendingApproval', 'Approved', 'ProvisioningStarted', 'ProvisioningFailed', 'ProvisioningCompleted', 'Validating', 'Active'
	ConnectionState ConnectionState `json:"connectionState,omitempty"`
	// BgpSession - The BGP session associated with the connection.
	BgpSession *BgpSession `json:"bgpSession,omitempty"`
}

// ExchangePeeringFacility the properties that define an exchange peering facility.
type ExchangePeeringFacility struct {
	// ExchangeName - The name of the exchange peering facility.
	ExchangeName *string `json:"exchangeName,omitempty"`
	// BandwidthInMbps - The bandwidth of the connection between Microsoft and the exchange peering facility.
	BandwidthInMbps *int32 `json:"bandwidthInMbps,omitempty"`
	// MicrosoftIPv4Address - The IPv4 address of Microsoft at the exchange peering facility.
	MicrosoftIPv4Address *string `json:"microsoftIPv4Address,omitempty"`
	// MicrosoftIPv6Address - The IPv6 address of Microsoft at the exchange peering facility.
	MicrosoftIPv6Address *string `json:"microsoftIPv6Address,omitempty"`
	// FacilityIPv4Prefix - The IPv4 prefixes associated with the exchange peering facility.
	FacilityIPv4Prefix *string `json:"facilityIPv4Prefix,omitempty"`
	// FacilityIPv6Prefix - The IPv6 prefixes associated with the exchange peering facility.
	FacilityIPv6Prefix *string `json:"facilityIPv6Prefix,omitempty"`
	// PeeringDBFacilityID - The PeeringDB.com ID of the facility.
	PeeringDBFacilityID *int32 `json:"peeringDBFacilityId,omitempty"`
	// PeeringDBFacilityLink - The PeeringDB.com URL of the facility.
	PeeringDBFacilityLink *string `json:"peeringDBFacilityLink,omitempty"`
}

// ListResult the paginated list of peerings.
type ListResult struct {
	autorest.Response `json:"-"`
	// Value - The list of peerings.
	Value *[]Model `json:"value,omitempty"`
	// NextLink - The link to fetch the next page of peerings.
	NextLink *string `json:"nextLink,omitempty"`
}

// ListResultIterator provides access to a complete listing of Model 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() Model {
	if !iter.page.NotDone() {
		return Model{}
	}
	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
}

// 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.NextLink == nil || len(to.String(lr.NextLink)) < 1 {
		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 Model 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)
		}()
	}
	next, err := page.fn(ctx, page.lr)
	if err != nil {
		return err
	}
	page.lr = next
	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() []Model {
	if page.lr.IsEmpty() {
		return nil
	}
	return *page.lr.Value
}

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

// Location peering location is where connectivity could be established to the Microsoft Cloud Edge.
type Location struct {
	// Kind - The kind of peering that the peering location supports. Possible values include: 'KindDirect', 'KindExchange'
	Kind Kind `json:"kind,omitempty"`
	// LocationProperties - The properties that define a peering location.
	*LocationProperties `json:"properties,omitempty"`
	// Name - READ-ONLY; The name of the resource.
	Name *string `json:"name,omitempty"`
	// ID - READ-ONLY; The ID of the resource.
	ID *string `json:"id,omitempty"`
	// Type - READ-ONLY; The type of the resource.
	Type *string `json:"type,omitempty"`
}

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

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

	return nil
}

// LocationListResult the paginated list of peering locations.
type LocationListResult struct {
	autorest.Response `json:"-"`
	// Value - The list of peering locations.
	Value *[]Location `json:"value,omitempty"`
	// NextLink - The link to fetch the next page of peering locations.
	NextLink *string `json:"nextLink,omitempty"`
}

// LocationListResultIterator provides access to a complete listing of Location values.
type LocationListResultIterator struct {
	i    int
	page LocationListResultPage
}

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

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

// Creates a new instance of the LocationListResultIterator type.
func NewLocationListResultIterator(page LocationListResultPage) LocationListResultIterator {
	return LocationListResultIterator{page: page}
}

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

// locationListResultPreparer prepares a request to retrieve the next set of results.
// It returns nil if no more results exist.
func (llr LocationListResult) locationListResultPreparer(ctx context.Context) (*http.Request, error) {
	if llr.NextLink == nil || len(to.String(llr.NextLink)) < 1 {
		return nil, nil
	}
	return autorest.Prepare((&http.Request{}).WithContext(ctx),
		autorest.AsJSON(),
		autorest.AsGet(),
		autorest.WithBaseURL(to.String(llr.NextLink)))
}

// LocationListResultPage contains a page of Location values.
type LocationListResultPage struct {
	fn  func(context.Context, LocationListResult) (LocationListResult, error)
	llr LocationListResult
}

// 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 *LocationListResultPage) NextWithContext(ctx context.Context) (err error) {
	if tracing.IsEnabled() {
		ctx = tracing.StartSpan(ctx, fqdn+"/LocationListResultPage.NextWithContext")
		defer func() {
			sc := -1
			if page.Response().Response.Response != nil {
				sc = page.Response().Response.Response.StatusCode
			}
			tracing.EndSpan(ctx, sc, err)
		}()
	}
	next, err := page.fn(ctx, page.llr)
	if err != nil {
		return err
	}
	page.llr = next
	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 *LocationListResultPage) Next() error {
	return page.NextWithContext(context.Background())
}

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

// Response returns the raw server response from the last page request.
func (page LocationListResultPage) Response() LocationListResult {
	return page.llr
}

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

// Creates a new instance of the LocationListResultPage type.
func NewLocationListResultPage(getNextPage func(context.Context, LocationListResult) (LocationListResult, error)) LocationListResultPage {
	return LocationListResultPage{fn: getNextPage}
}

// LocationProperties the properties that define a peering location.
type LocationProperties struct {
	// Direct - The properties that define a direct peering location.
	Direct *LocationPropertiesDirect `json:"direct,omitempty"`
	// Exchange - The properties that define an exchange peering location.
	Exchange *LocationPropertiesExchange `json:"exchange,omitempty"`
	// PeeringLocation - The name of the peering location.
	PeeringLocation *string `json:"peeringLocation,omitempty"`
	// Country - The country in which the peering location exists.
	Country *string `json:"country,omitempty"`
	// AzureRegion - The Azure region associated with the peering location.
	AzureRegion *string `json:"azureRegion,omitempty"`
}

// LocationPropertiesDirect the properties that define a direct peering location.
type LocationPropertiesDirect struct {
	// PeeringFacilities - The list of direct peering facilities at the peering location.
	PeeringFacilities *[]DirectPeeringFacility `json:"peeringFacilities,omitempty"`
	// BandwidthOffers - The list of bandwidth offers available at the peering location.
	BandwidthOffers *[]BandwidthOffer `json:"bandwidthOffers,omitempty"`
}

// LocationPropertiesExchange the properties that define an exchange peering location.
type LocationPropertiesExchange struct {
	// PeeringFacilities - The list of exchange peering facilities at the peering location.
	PeeringFacilities *[]ExchangePeeringFacility `json:"peeringFacilities,omitempty"`
}

// Model peering is a logical representation of a set of connections to the Microsoft Cloud Edge at a
// location.
type Model struct {
	autorest.Response `json:"-"`
	// Sku - The SKU that defines the tier and kind of the peering.
	Sku *Sku `json:"sku,omitempty"`
	// Kind - The kind of the peering. Possible values include: 'KindDirect', 'KindExchange'
	Kind Kind `json:"kind,omitempty"`
	// Properties - The properties that define a peering.
	*Properties `json:"properties,omitempty"`
	// Location - The location of the resource.
	Location *string `json:"location,omitempty"`
	// Tags - The resource tags.
	Tags map[string]*string `json:"tags"`
	// Name - READ-ONLY; The name of the resource.
	Name *string `json:"name,omitempty"`
	// ID - READ-ONLY; The ID of the resource.
	ID *string `json:"id,omitempty"`
	// Type - READ-ONLY; The type of the resource.
	Type *string `json:"type,omitempty"`
}

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

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

	return nil
}

// Operation the peering API operation.
type Operation struct {
	// Name - READ-ONLY; The name of the operation.
	Name *string `json:"name,omitempty"`
	// Display - READ-ONLY; The information related to the operation.
	Display *OperationDisplayInfo `json:"display,omitempty"`
	// IsDataAction - READ-ONLY; The flag that indicates whether the operation applies to data plane.
	IsDataAction *bool `json:"isDataAction,omitempty"`
}

// OperationDisplayInfo the information related to the operation.
type OperationDisplayInfo struct {
	// Provider - READ-ONLY; The name of the resource provider.
	Provider *string `json:"provider,omitempty"`
	// Resource - READ-ONLY; The type of the resource.
	Resource *string `json:"resource,omitempty"`
	// Operation - READ-ONLY; The name of the operation.
	Operation *string `json:"operation,omitempty"`
	// Description - READ-ONLY; The description of the operation.
	Description *string `json:"description,omitempty"`
}

// OperationListResult the paginated list of peering API operations.
type OperationListResult struct {
	autorest.Response `json:"-"`
	// Value - The list of peering API operations.
	Value *[]Operation `json:"value,omitempty"`
	// NextLink - The link to fetch the next page of peering API operations.
	NextLink *string `json:"nextLink,omitempty"`
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

// PeerAsn the essential information related to the peer's ASN.
type PeerAsn struct {
	autorest.Response `json:"-"`
	// PeerAsnProperties - The properties that define a peer's ASN.
	*PeerAsnProperties `json:"properties,omitempty"`
	// Name - READ-ONLY; The name of the resource.
	Name *string `json:"name,omitempty"`
	// ID - READ-ONLY; The ID of the resource.
	ID *string `json:"id,omitempty"`
	// Type - READ-ONLY; The type of the resource.
	Type *string `json:"type,omitempty"`
}

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

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

	return nil
}

// PeerAsnListResult the paginated list of peer ASNs.
type PeerAsnListResult struct {
	autorest.Response `json:"-"`
	// Value - The list of peer ASNs.
	Value *[]PeerAsn `json:"value,omitempty"`
	// NextLink - The link to fetch the next page of peer ASNs.
	NextLink *string `json:"nextLink,omitempty"`
}

// PeerAsnListResultIterator provides access to a complete listing of PeerAsn values.
type PeerAsnListResultIterator struct {
	i    int
	page PeerAsnListResultPage
}

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

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

// Creates a new instance of the PeerAsnListResultIterator type.
func NewPeerAsnListResultIterator(page PeerAsnListResultPage) PeerAsnListResultIterator {
	return PeerAsnListResultIterator{page: page}
}

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

// peerAsnListResultPreparer prepares a request to retrieve the next set of results.
// It returns nil if no more results exist.
func (palr PeerAsnListResult) peerAsnListResultPreparer(ctx context.Context) (*http.Request, error) {
	if palr.NextLink == nil || len(to.String(palr.NextLink)) < 1 {
		return nil, nil
	}
	return autorest.Prepare((&http.Request{}).WithContext(ctx),
		autorest.AsJSON(),
		autorest.AsGet(),
		autorest.WithBaseURL(to.String(palr.NextLink)))
}

// PeerAsnListResultPage contains a page of PeerAsn values.
type PeerAsnListResultPage struct {
	fn   func(context.Context, PeerAsnListResult) (PeerAsnListResult, error)
	palr PeerAsnListResult
}

// 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 *PeerAsnListResultPage) NextWithContext(ctx context.Context) (err error) {
	if tracing.IsEnabled() {
		ctx = tracing.StartSpan(ctx, fqdn+"/PeerAsnListResultPage.NextWithContext")
		defer func() {
			sc := -1
			if page.Response().Response.Response != nil {
				sc = page.Response().Response.Response.StatusCode
			}
			tracing.EndSpan(ctx, sc, err)
		}()
	}
	next, err := page.fn(ctx, page.palr)
	if err != nil {
		return err
	}
	page.palr = next
	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 *PeerAsnListResultPage) Next() error {
	return page.NextWithContext(context.Background())
}

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

// Response returns the raw server response from the last page request.
func (page PeerAsnListResultPage) Response() PeerAsnListResult {
	return page.palr
}

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

// Creates a new instance of the PeerAsnListResultPage type.
func NewPeerAsnListResultPage(getNextPage func(context.Context, PeerAsnListResult) (PeerAsnListResult, error)) PeerAsnListResultPage {
	return PeerAsnListResultPage{fn: getNextPage}
}

// PeerAsnProperties the properties that define a peer's ASN.
type PeerAsnProperties struct {
	// PeerAsn - The Autonomous System Number (ASN) of the peer.
	PeerAsn *int32 `json:"peerAsn,omitempty"`
	// PeerContactInfo - The contact information of the peer.
	PeerContactInfo *ContactInfo `json:"peerContactInfo,omitempty"`
	// PeerName - The name of the peer.
	PeerName *string `json:"peerName,omitempty"`
	// ValidationState - The validation state of the ASN associated with the peer. Possible values include: 'ValidationStateNone', 'ValidationStatePending', 'ValidationStateApproved', 'ValidationStateFailed'
	ValidationState ValidationState `json:"validationState,omitempty"`
}

// Properties the properties that define connectivity to the Microsoft Cloud Edge.
type Properties struct {
	// Direct - The properties that define a direct peering.
	Direct *PropertiesDirect `json:"direct,omitempty"`
	// Exchange - The properties that define an exchange peering.
	Exchange *PropertiesExchange `json:"exchange,omitempty"`
	// PeeringLocation - The location of the peering.
	PeeringLocation *string `json:"peeringLocation,omitempty"`
	// ProvisioningState - READ-ONLY; The provisioning state of the resource. Possible values include: 'Succeeded', 'Updating', 'Deleting', 'Failed'
	ProvisioningState ProvisioningState `json:"provisioningState,omitempty"`
}

// PropertiesDirect the properties that define a direct peering.
type PropertiesDirect struct {
	// Connections - The set of connections that constitute a direct peering.
	Connections *[]DirectConnection `json:"connections,omitempty"`
	// UseForPeeringService - The flag that indicates whether or not the peering is used for peering service.
	UseForPeeringService *bool `json:"useForPeeringService,omitempty"`
	// PeerAsn - The reference of the peer ASN.
	PeerAsn *SubResource `json:"peerAsn,omitempty"`
}

// PropertiesExchange the properties that define an exchange peering.
type PropertiesExchange struct {
	// Connections - The set of connections that constitute an exchange peering.
	Connections *[]ExchangeConnection `json:"connections,omitempty"`
	// PeerAsn - The reference of the peer ASN.
	PeerAsn *SubResource `json:"peerAsn,omitempty"`
}

// Resource the ARM resource class.
type Resource struct {
	// Name - READ-ONLY; The name of the resource.
	Name *string `json:"name,omitempty"`
	// ID - READ-ONLY; The ID of the resource.
	ID *string `json:"id,omitempty"`
	// Type - READ-ONLY; The type of the resource.
	Type *string `json:"type,omitempty"`
}

// ResourceTags the resource tags.
type ResourceTags struct {
	// Tags - Gets or sets the tags, a dictionary of descriptors arm object
	Tags map[string]*string `json:"tags"`
}

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

// Sku the SKU that defines the tier and kind of the peering.
type Sku struct {
	// Name - The name of the peering SKU. Possible values include: 'BasicExchangeFree', 'BasicDirectFree', 'PremiumDirectFree', 'PremiumExchangeMetered'
	Name Name `json:"name,omitempty"`
	// Tier - The tier of the peering SKU. Possible values include: 'Basic', 'Premium'
	Tier Tier `json:"tier,omitempty"`
	// Family - The family of the peering SKU. Possible values include: 'Direct', 'Exchange'
	Family Family `json:"family,omitempty"`
	// Size - The size of the peering SKU. Possible values include: 'Free', 'Metered', 'Unlimited'
	Size Size `json:"size,omitempty"`
}

// SubResource the sub resource.
type SubResource struct {
	// ID - The identifier of the referenced resource.
	ID *string `json:"id,omitempty"`
}
