package azurestack

// 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/azurestack/mgmt/2017-06-01/azurestack"

// ActivationKeyResult the resource containing the Azure Stack activation key.
type ActivationKeyResult struct {
	autorest.Response `json:"-"`
	// ActivationKey - Azure Stack activation key.
	ActivationKey *string `json:"activationKey,omitempty"`
}

// CloudManifestFileDeploymentData cloud specific manifest data for AzureStack deployment.
type CloudManifestFileDeploymentData struct {
	// ExternalDsmsCertificates - Dsms external certificates.
	ExternalDsmsCertificates *string `json:"externalDsmsCertificates,omitempty"`
	// CustomCloudVerificationKey - Signing verification public key.
	CustomCloudVerificationKey *string `json:"customCloudVerificationKey,omitempty"`
	// CloudManifestFileEnvironmentEndpoints - Environment endpoints.
	*CloudManifestFileEnvironmentEndpoints `json:"customEnvironmentEndpoints,omitempty"`
}

// MarshalJSON is the custom marshaler for CloudManifestFileDeploymentData.
func (cmfdd CloudManifestFileDeploymentData) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]interface{})
	if cmfdd.ExternalDsmsCertificates != nil {
		objectMap["externalDsmsCertificates"] = cmfdd.ExternalDsmsCertificates
	}
	if cmfdd.CustomCloudVerificationKey != nil {
		objectMap["customCloudVerificationKey"] = cmfdd.CustomCloudVerificationKey
	}
	if cmfdd.CloudManifestFileEnvironmentEndpoints != nil {
		objectMap["customEnvironmentEndpoints"] = cmfdd.CloudManifestFileEnvironmentEndpoints
	}
	return json.Marshal(objectMap)
}

// UnmarshalJSON is the custom unmarshaler for CloudManifestFileDeploymentData struct.
func (cmfdd *CloudManifestFileDeploymentData) 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 "externalDsmsCertificates":
			if v != nil {
				var externalDsmsCertificates string
				err = json.Unmarshal(*v, &externalDsmsCertificates)
				if err != nil {
					return err
				}
				cmfdd.ExternalDsmsCertificates = &externalDsmsCertificates
			}
		case "customCloudVerificationKey":
			if v != nil {
				var customCloudVerificationKey string
				err = json.Unmarshal(*v, &customCloudVerificationKey)
				if err != nil {
					return err
				}
				cmfdd.CustomCloudVerificationKey = &customCloudVerificationKey
			}
		case "customEnvironmentEndpoints":
			if v != nil {
				var cloudManifestFileEnvironmentEndpoints CloudManifestFileEnvironmentEndpoints
				err = json.Unmarshal(*v, &cloudManifestFileEnvironmentEndpoints)
				if err != nil {
					return err
				}
				cmfdd.CloudManifestFileEnvironmentEndpoints = &cloudManifestFileEnvironmentEndpoints
			}
		}
	}

	return nil
}

// CloudManifestFileEnvironmentEndpoints cloud specific environment endpoints for AzureStack deployment.
type CloudManifestFileEnvironmentEndpoints struct {
	// CustomCloudArmEndpoint - ARM endpoint.
	CustomCloudArmEndpoint *string `json:"customCloudArmEndpoint,omitempty"`
	// ExternalDsmsEndpoint - Dsms endpoint.
	ExternalDsmsEndpoint *string `json:"externalDsmsEndpoint,omitempty"`
}

// CloudManifestFileProperties cloud specific manifest JSON properties.
type CloudManifestFileProperties struct {
	// DeploymentData - Cloud specific manifest data.
	DeploymentData *CloudManifestFileDeploymentData `json:"deploymentData,omitempty"`
	// Signature - Signature of the cloud specific manifest data.
	Signature *string `json:"signature,omitempty"`
}

// CloudManifestFileResponse cloud specific manifest GET response.
type CloudManifestFileResponse struct {
	autorest.Response `json:"-"`
	// Properties - Cloud specific manifest data.
	Properties *CloudManifestFileProperties `json:"properties,omitempty"`
	// ID - READ-ONLY; ID of the resource.
	ID *string `json:"id,omitempty"`
	// Name - READ-ONLY; Name of the resource.
	Name *string `json:"name,omitempty"`
	// Type - READ-ONLY; Type of Resource.
	Type *string `json:"type,omitempty"`
	// Etag - The entity tag used for optimistic concurrency when modifying the resource.
	Etag *string `json:"etag,omitempty"`
}

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

// Compatibility product compatibility
type Compatibility struct {
	// IsCompatible - Tells if product is compatible with current device
	IsCompatible *bool `json:"isCompatible,omitempty"`
	// Message - Short error message if any compatibility issues are found
	Message *string `json:"message,omitempty"`
	// Description - Full error message if any compatibility issues are found
	Description *string `json:"description,omitempty"`
	// Issues - List of all issues found
	Issues *[]CompatibilityIssue `json:"issues,omitempty"`
}

// CustomerSubscription customer subscription.
type CustomerSubscription struct {
	autorest.Response `json:"-"`
	// CustomerSubscriptionProperties - Customer subscription properties.
	*CustomerSubscriptionProperties `json:"properties,omitempty"`
	// ID - READ-ONLY; ID of the resource.
	ID *string `json:"id,omitempty"`
	// Name - READ-ONLY; Name of the resource.
	Name *string `json:"name,omitempty"`
	// Type - READ-ONLY; Type of Resource.
	Type *string `json:"type,omitempty"`
	// Etag - The entity tag used for optimistic concurrency when modifying the resource.
	Etag *string `json:"etag,omitempty"`
}

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

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

	return nil
}

// CustomerSubscriptionList pageable list of customer subscriptions.
type CustomerSubscriptionList struct {
	autorest.Response `json:"-"`
	// NextLink - URI to the next page.
	NextLink *string `json:"nextLink,omitempty"`
	// Value - List of customer subscriptions.
	Value *[]CustomerSubscription `json:"value,omitempty"`
}

// CustomerSubscriptionListIterator provides access to a complete listing of CustomerSubscription values.
type CustomerSubscriptionListIterator struct {
	i    int
	page CustomerSubscriptionListPage
}

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

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

// Creates a new instance of the CustomerSubscriptionListIterator type.
func NewCustomerSubscriptionListIterator(page CustomerSubscriptionListPage) CustomerSubscriptionListIterator {
	return CustomerSubscriptionListIterator{page: page}
}

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

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

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

// CustomerSubscriptionListPage contains a page of CustomerSubscription values.
type CustomerSubscriptionListPage struct {
	fn  func(context.Context, CustomerSubscriptionList) (CustomerSubscriptionList, error)
	csl CustomerSubscriptionList
}

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

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

// Response returns the raw server response from the last page request.
func (page CustomerSubscriptionListPage) Response() CustomerSubscriptionList {
	return page.csl
}

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

// Creates a new instance of the CustomerSubscriptionListPage type.
func NewCustomerSubscriptionListPage(cur CustomerSubscriptionList, getNextPage func(context.Context, CustomerSubscriptionList) (CustomerSubscriptionList, error)) CustomerSubscriptionListPage {
	return CustomerSubscriptionListPage{
		fn:  getNextPage,
		csl: cur,
	}
}

// CustomerSubscriptionProperties customer subscription properties.
type CustomerSubscriptionProperties struct {
	// TenantID - Tenant Id.
	TenantID *string `json:"tenantId,omitempty"`
}

// DataDiskImage data disk image.
type DataDiskImage struct {
	// Lun - READ-ONLY; The LUN.
	Lun *int32 `json:"lun,omitempty"`
	// SourceBlobSasURI - READ-ONLY; SAS key for source blob.
	SourceBlobSasURI *string `json:"sourceBlobSasUri,omitempty"`
}

// DeviceConfiguration device Configuration.
type DeviceConfiguration struct {
	// DeviceVersion - READ-ONLY; Version of the device.
	DeviceVersion *string `json:"deviceVersion,omitempty"`
	// IdentitySystem - READ-ONLY; Identity system of the device. Possible values include: 'AzureAD', 'ADFS'
	IdentitySystem Category `json:"identitySystem,omitempty"`
}

// Display contains the localized display information for this particular operation or action.
type Display struct {
	// Provider - The localized, friendly version of the resource provider name.
	Provider *string `json:"provider,omitempty"`
	// Resource - The localized, friendly version of the resource type related to this action or operation; the resource type should match the public documentation for the resource provider.
	Resource *string `json:"resource,omitempty"`
	// Operation - The localized, friendly name for the operation. Use the name as it will displayed to the user.
	Operation *string `json:"operation,omitempty"`
	// Description - The localized, friendly description for the operation. The description will be displayed to the user. It should be thorough and concise for used in both tooltips and detailed views.
	Description *string `json:"description,omitempty"`
}

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

// ErrorResponse error response indicates that the service is not able to process the incoming request. The
// reason is provided in the error message.
type ErrorResponse struct {
	// Error - The details of the error.
	Error *ErrorDetails `json:"error,omitempty"`
}

// ExtendedProduct extended description about the product required for installing it into Azure Stack.
type ExtendedProduct struct {
	autorest.Response `json:"-"`
	// GalleryPackageBlobSasURI - READ-ONLY; The URI to the .azpkg file that provides information required for showing product in the gallery.
	GalleryPackageBlobSasURI *string `json:"galleryPackageBlobSasUri,omitempty"`
	// ProductKind - READ-ONLY; Specifies the kind of the product (virtualMachine or virtualMachineExtension).
	ProductKind *string `json:"productKind,omitempty"`
	// ExtendedProductProperties - READ-ONLY; Specifies additional properties describing the product.
	*ExtendedProductProperties `json:"properties,omitempty"`
}

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

// UnmarshalJSON is the custom unmarshaler for ExtendedProduct struct.
func (ep *ExtendedProduct) 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 "galleryPackageBlobSasUri":
			if v != nil {
				var galleryPackageBlobSasURI string
				err = json.Unmarshal(*v, &galleryPackageBlobSasURI)
				if err != nil {
					return err
				}
				ep.GalleryPackageBlobSasURI = &galleryPackageBlobSasURI
			}
		case "productKind":
			if v != nil {
				var productKind string
				err = json.Unmarshal(*v, &productKind)
				if err != nil {
					return err
				}
				ep.ProductKind = &productKind
			}
		case "properties":
			if v != nil {
				var extendedProductProperties ExtendedProductProperties
				err = json.Unmarshal(*v, &extendedProductProperties)
				if err != nil {
					return err
				}
				ep.ExtendedProductProperties = &extendedProductProperties
			}
		}
	}

	return nil
}

// ExtendedProductProperties product information.
type ExtendedProductProperties struct {
	// ComputeRole - READ-ONLY; Specifies kind of compute role included in the package. Possible values include: 'None', 'IaaS', 'PaaS'
	ComputeRole ComputeRole `json:"computeRole,omitempty"`
	// IsSystemExtension - READ-ONLY; Specifies if product is a Virtual Machine Extension.
	IsSystemExtension *bool `json:"isSystemExtension,omitempty"`
	// URI - READ-ONLY; Specifies a download location where content can be downloaded from.
	*URI `json:"sourceBlob,omitempty"`
	// SupportMultipleExtensions - READ-ONLY; Indicates if specified product supports multiple extensions.
	SupportMultipleExtensions *bool `json:"supportMultipleExtensions,omitempty"`
	// Version - READ-ONLY; Specifies product version.
	Version *string `json:"version,omitempty"`
	// VMOsType - READ-ONLY; Specifies operating system used by the product. Possible values include: 'OperatingSystemNone', 'OperatingSystemWindows', 'OperatingSystemLinux'
	VMOsType OperatingSystem `json:"vmOsType,omitempty"`
	// VMScaleSetEnabled - READ-ONLY; Indicates if virtual machine Scale Set is enabled in the specified product.
	VMScaleSetEnabled *bool `json:"vmScaleSetEnabled,omitempty"`
	// OsDiskImage - READ-ONLY; OS disk image used by product.
	OsDiskImage *OsDiskImage `json:"osDiskImage,omitempty"`
	// DataDiskImages - READ-ONLY; List of attached data disks.
	DataDiskImages *[]DataDiskImage `json:"dataDiskImages,omitempty"`
}

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

// UnmarshalJSON is the custom unmarshaler for ExtendedProductProperties struct.
func (epp *ExtendedProductProperties) 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 "computeRole":
			if v != nil {
				var computeRole ComputeRole
				err = json.Unmarshal(*v, &computeRole)
				if err != nil {
					return err
				}
				epp.ComputeRole = computeRole
			}
		case "isSystemExtension":
			if v != nil {
				var isSystemExtension bool
				err = json.Unmarshal(*v, &isSystemExtension)
				if err != nil {
					return err
				}
				epp.IsSystemExtension = &isSystemExtension
			}
		case "sourceBlob":
			if v != nil {
				var URI URI
				err = json.Unmarshal(*v, &URI)
				if err != nil {
					return err
				}
				epp.URI = &URI
			}
		case "supportMultipleExtensions":
			if v != nil {
				var supportMultipleExtensions bool
				err = json.Unmarshal(*v, &supportMultipleExtensions)
				if err != nil {
					return err
				}
				epp.SupportMultipleExtensions = &supportMultipleExtensions
			}
		case "version":
			if v != nil {
				var version string
				err = json.Unmarshal(*v, &version)
				if err != nil {
					return err
				}
				epp.Version = &version
			}
		case "vmOsType":
			if v != nil {
				var VMOsType OperatingSystem
				err = json.Unmarshal(*v, &VMOsType)
				if err != nil {
					return err
				}
				epp.VMOsType = VMOsType
			}
		case "vmScaleSetEnabled":
			if v != nil {
				var VMScaleSetEnabled bool
				err = json.Unmarshal(*v, &VMScaleSetEnabled)
				if err != nil {
					return err
				}
				epp.VMScaleSetEnabled = &VMScaleSetEnabled
			}
		case "osDiskImage":
			if v != nil {
				var osDiskImage OsDiskImage
				err = json.Unmarshal(*v, &osDiskImage)
				if err != nil {
					return err
				}
				epp.OsDiskImage = &osDiskImage
			}
		case "dataDiskImages":
			if v != nil {
				var dataDiskImages []DataDiskImage
				err = json.Unmarshal(*v, &dataDiskImages)
				if err != nil {
					return err
				}
				epp.DataDiskImages = &dataDiskImages
			}
		}
	}

	return nil
}

// IconUris links to product icons.
type IconUris struct {
	// Large - URI to large icon.
	Large *string `json:"large,omitempty"`
	// Wide - URI to wide icon.
	Wide *string `json:"wide,omitempty"`
	// Medium - URI to medium icon.
	Medium *string `json:"medium,omitempty"`
	// Small - URI to small icon.
	Small *string `json:"small,omitempty"`
	// Hero - URI to hero icon.
	Hero *string `json:"hero,omitempty"`
}

// MarketplaceProductLogUpdate update details for product log.
type MarketplaceProductLogUpdate struct {
	// Operation - READ-ONLY; Operation to log.
	Operation *string `json:"operation,omitempty"`
	// Status - READ-ONLY; Operation status to log.
	Status *string `json:"status,omitempty"`
	// Error - READ-ONLY; Error related to the operation.
	Error *string `json:"error,omitempty"`
	// Details - READ-ONLY; Error details related to operation.
	Details *string `json:"details,omitempty"`
}

// Operation describes the supported REST operation.
type Operation struct {
	// Name - The name of the operation being performed on this particular object.
	Name *string `json:"name,omitempty"`
	// Display - Contains the localized display information for this particular operation or action.
	Display *Display `json:"display,omitempty"`
	// Origin - The intended executor of the operation.
	Origin *string `json:"origin,omitempty"`
}

// OperationList list of Operations
type OperationList struct {
	autorest.Response `json:"-"`
	// Value - Array of operations
	Value *[]Operation `json:"value,omitempty"`
	// NextLink - URI to the next page of operations.
	NextLink *string `json:"nextLink,omitempty"`
}

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

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

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

// Creates a new instance of the OperationListIterator type.
func NewOperationListIterator(page OperationListPage) OperationListIterator {
	return OperationListIterator{page: page}
}

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

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

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

// OperationListPage contains a page of Operation values.
type OperationListPage struct {
	fn func(context.Context, OperationList) (OperationList, error)
	ol OperationList
}

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

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

// Response returns the raw server response from the last page request.
func (page OperationListPage) Response() OperationList {
	return page.ol
}

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

// Creates a new instance of the OperationListPage type.
func NewOperationListPage(cur OperationList, getNextPage func(context.Context, OperationList) (OperationList, error)) OperationListPage {
	return OperationListPage{
		fn: getNextPage,
		ol: cur,
	}
}

// OsDiskImage OS disk image.
type OsDiskImage struct {
	// OperatingSystem - READ-ONLY; OS operating system type. Possible values include: 'OperatingSystemNone', 'OperatingSystemWindows', 'OperatingSystemLinux'
	OperatingSystem OperatingSystem `json:"operatingSystem,omitempty"`
	// SourceBlobSasURI - READ-ONLY; SAS key for source blob.
	SourceBlobSasURI *string `json:"sourceBlobSasUri,omitempty"`
}

// Product product information.
type Product struct {
	autorest.Response `json:"-"`
	// ProductNestedProperties - Properties of the product resource.
	*ProductNestedProperties `json:"properties,omitempty"`
	// ID - READ-ONLY; ID of the resource.
	ID *string `json:"id,omitempty"`
	// Name - READ-ONLY; Name of the resource.
	Name *string `json:"name,omitempty"`
	// Type - READ-ONLY; Type of Resource.
	Type *string `json:"type,omitempty"`
	// Etag - The entity tag used for optimistic concurrency when modifying the resource.
	Etag *string `json:"etag,omitempty"`
}

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

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

	return nil
}

// ProductLink link with additional information about a product.
type ProductLink struct {
	// DisplayName - The description of the link.
	DisplayName *string `json:"displayName,omitempty"`
	// URI - The URI corresponding to the link.
	URI *string `json:"uri,omitempty"`
}

// ProductList pageable list of products.
type ProductList struct {
	autorest.Response `json:"-"`
	// NextLink - URI to the next page.
	NextLink *string `json:"nextLink,omitempty"`
	// Value - List of products.
	Value *[]Product `json:"value,omitempty"`
}

// ProductListIterator provides access to a complete listing of Product values.
type ProductListIterator struct {
	i    int
	page ProductListPage
}

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

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

// Creates a new instance of the ProductListIterator type.
func NewProductListIterator(page ProductListPage) ProductListIterator {
	return ProductListIterator{page: page}
}

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

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

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

// ProductListPage contains a page of Product values.
type ProductListPage struct {
	fn func(context.Context, ProductList) (ProductList, error)
	pl ProductList
}

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

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

// Response returns the raw server response from the last page request.
func (page ProductListPage) Response() ProductList {
	return page.pl
}

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

// Creates a new instance of the ProductListPage type.
func NewProductListPage(cur ProductList, getNextPage func(context.Context, ProductList) (ProductList, error)) ProductListPage {
	return ProductListPage{
		fn: getNextPage,
		pl: cur,
	}
}

// ProductLog product action log.
type ProductLog struct {
	autorest.Response `json:"-"`
	// ID - READ-ONLY; Log ID.
	ID *string `json:"id,omitempty"`
	// ProductID - READ-ONLY; Logged product ID.
	ProductID *string `json:"productId,omitempty"`
	// SubscriptionID - READ-ONLY; Logged subscription ID.
	SubscriptionID *string `json:"subscriptionId,omitempty"`
	// RegistrationName - READ-ONLY; Logged registration name.
	RegistrationName *string `json:"registrationName,omitempty"`
	// ResourceGroupName - READ-ONLY; Logged resource group name.
	ResourceGroupName *string `json:"resourceGroupName,omitempty"`
	// Operation - READ-ONLY; Logged operation.
	Operation *string `json:"operation,omitempty"`
	// StartDate - READ-ONLY; Operation start datetime.
	StartDate *string `json:"startDate,omitempty"`
	// EndDate - READ-ONLY; Operation end datetime.
	EndDate *string `json:"endDate,omitempty"`
	// Status - READ-ONLY; Operation status.
	Status *string `json:"status,omitempty"`
	// Error - READ-ONLY; Operation error data.
	Error *string `json:"error,omitempty"`
	// Details - READ-ONLY; Operation error details.
	Details *string `json:"details,omitempty"`
}

// ProductNestedProperties properties portion of the product resource.
type ProductNestedProperties struct {
	// DisplayName - The display name of the product.
	DisplayName *string `json:"displayName,omitempty"`
	// Description - The description of the product.
	Description *string `json:"description,omitempty"`
	// PublisherDisplayName - The user-friendly name of the product publisher.
	PublisherDisplayName *string `json:"publisherDisplayName,omitempty"`
	// PublisherIdentifier - Publisher identifier.
	PublisherIdentifier *string `json:"publisherIdentifier,omitempty"`
	// Offer - The offer representing the product.
	Offer *string `json:"offer,omitempty"`
	// OfferVersion - The version of the product offer.
	OfferVersion *string `json:"offerVersion,omitempty"`
	// Sku - The product SKU.
	Sku *string `json:"sku,omitempty"`
	// BillingPartNumber - The part number used for billing purposes.
	BillingPartNumber *string `json:"billingPartNumber,omitempty"`
	// VMExtensionType - The type of the Virtual Machine Extension.
	VMExtensionType *string `json:"vmExtensionType,omitempty"`
	// GalleryItemIdentity - The identifier of the gallery item corresponding to the product.
	GalleryItemIdentity *string `json:"galleryItemIdentity,omitempty"`
	// IconUris - Additional links available for this product.
	IconUris *IconUris `json:"iconUris,omitempty"`
	// Links - Additional links available for this product.
	Links *[]ProductLink `json:"links,omitempty"`
	// LegalTerms - The legal terms.
	LegalTerms *string `json:"legalTerms,omitempty"`
	// PrivacyPolicy - The privacy policy.
	PrivacyPolicy *string `json:"privacyPolicy,omitempty"`
	// PayloadLength - The length of product content.
	PayloadLength *int64 `json:"payloadLength,omitempty"`
	// ProductKind - The kind of the product (virtualMachine or virtualMachineExtension)
	ProductKind *string `json:"productKind,omitempty"`
	// ProductProperties - Additional properties for the product.
	ProductProperties *ProductProperties `json:"productProperties,omitempty"`
	// Compatibility - Product compatibility with current device.
	Compatibility *Compatibility `json:"compatibility,omitempty"`
}

// ProductProperties additional properties of the product
type ProductProperties struct {
	// Version - The version.
	Version *string `json:"version,omitempty"`
}

// Registration registration information.
type Registration struct {
	autorest.Response `json:"-"`
	// RegistrationProperties - Registration resource.
	*RegistrationProperties `json:"properties,omitempty"`
	// ID - READ-ONLY; ID of the resource.
	ID *string `json:"id,omitempty"`
	// Name - READ-ONLY; Name of the resource.
	Name *string `json:"name,omitempty"`
	// Type - READ-ONLY; Type of Resource.
	Type *string `json:"type,omitempty"`
	// Location - Location of the resource.
	Location *string `json:"location,omitempty"`
	// Tags - Custom tags for the resource.
	Tags map[string]*string `json:"tags"`
	// Etag - The entity tag used for optimistic concurrency when modifying the resource.
	Etag *string `json:"etag,omitempty"`
}

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

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

	return nil
}

// RegistrationList pageable list of registrations.
type RegistrationList struct {
	autorest.Response `json:"-"`
	// NextLink - URI to the next page.
	NextLink *string `json:"nextLink,omitempty"`
	// Value - List of Registrations
	Value *[]Registration `json:"value,omitempty"`
}

// RegistrationListIterator provides access to a complete listing of Registration values.
type RegistrationListIterator struct {
	i    int
	page RegistrationListPage
}

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

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

// Creates a new instance of the RegistrationListIterator type.
func NewRegistrationListIterator(page RegistrationListPage) RegistrationListIterator {
	return RegistrationListIterator{page: page}
}

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

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

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

// RegistrationListPage contains a page of Registration values.
type RegistrationListPage struct {
	fn func(context.Context, RegistrationList) (RegistrationList, error)
	rl RegistrationList
}

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

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

// Response returns the raw server response from the last page request.
func (page RegistrationListPage) Response() RegistrationList {
	return page.rl
}

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

// Creates a new instance of the RegistrationListPage type.
func NewRegistrationListPage(cur RegistrationList, getNextPage func(context.Context, RegistrationList) (RegistrationList, error)) RegistrationListPage {
	return RegistrationListPage{
		fn: getNextPage,
		rl: cur,
	}
}

// RegistrationParameter registration resource
type RegistrationParameter struct {
	// RegistrationParameterProperties - Properties of the Azure Stack registration resource
	*RegistrationParameterProperties `json:"properties,omitempty"`
	// Location - Location of the resource.
	Location *string `json:"location,omitempty"`
}

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

// UnmarshalJSON is the custom unmarshaler for RegistrationParameter struct.
func (rp *RegistrationParameter) 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 registrationParameterProperties RegistrationParameterProperties
				err = json.Unmarshal(*v, &registrationParameterProperties)
				if err != nil {
					return err
				}
				rp.RegistrationParameterProperties = &registrationParameterProperties
			}
		case "location":
			if v != nil {
				var location string
				err = json.Unmarshal(*v, &location)
				if err != nil {
					return err
				}
				rp.Location = &location
			}
		}
	}

	return nil
}

// RegistrationParameterProperties properties of the Azure Stack registration resource
type RegistrationParameterProperties struct {
	// RegistrationToken - The token identifying registered Azure Stack
	RegistrationToken *string `json:"registrationToken,omitempty"`
}

// RegistrationProperties properties portion of the registration resource.
type RegistrationProperties struct {
	// ObjectID - The object identifier associated with the Azure Stack connecting to Azure.
	ObjectID *string `json:"objectId,omitempty"`
	// CloudID - The identifier of the registered Azure Stack.
	CloudID *string `json:"cloudId,omitempty"`
	// BillingModel - Specifies the billing mode for the Azure Stack registration.
	BillingModel *string `json:"billingModel,omitempty"`
}

// Resource base resource object.
type Resource struct {
	// ID - READ-ONLY; ID of the resource.
	ID *string `json:"id,omitempty"`
	// Name - READ-ONLY; Name of the resource.
	Name *string `json:"name,omitempty"`
	// Type - READ-ONLY; Type of Resource.
	Type *string `json:"type,omitempty"`
	// Etag - The entity tag used for optimistic concurrency when modifying the resource.
	Etag *string `json:"etag,omitempty"`
}

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

// TrackedResource base resource object.
type TrackedResource struct {
	// ID - READ-ONLY; ID of the resource.
	ID *string `json:"id,omitempty"`
	// Name - READ-ONLY; Name of the resource.
	Name *string `json:"name,omitempty"`
	// Type - READ-ONLY; Type of Resource.
	Type *string `json:"type,omitempty"`
	// Location - Location of the resource.
	Location *string `json:"location,omitempty"`
	// Tags - Custom tags for the resource.
	Tags map[string]*string `json:"tags"`
	// Etag - The entity tag used for optimistic concurrency when modifying the resource.
	Etag *string `json:"etag,omitempty"`
}

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

// URI the URI.
type URI struct {
	// URI - READ-ONLY; The URI.
	URI *string `json:"uri,omitempty"`
}

// VirtualMachineExtensionProductProperties product information.
type VirtualMachineExtensionProductProperties struct {
	// ComputeRole - READ-ONLY; Specifies kind of compute role included in the package. Possible values include: 'None', 'IaaS', 'PaaS'
	ComputeRole ComputeRole `json:"computeRole,omitempty"`
	// IsSystemExtension - READ-ONLY; Specifies if product is a Virtual Machine Extension.
	IsSystemExtension *bool `json:"isSystemExtension,omitempty"`
	// URI - READ-ONLY; Specifies a download location where content can be downloaded from.
	*URI `json:"sourceBlob,omitempty"`
	// SupportMultipleExtensions - READ-ONLY; Indicates if specified product supports multiple extensions.
	SupportMultipleExtensions *bool `json:"supportMultipleExtensions,omitempty"`
	// Version - READ-ONLY; Specifies product version.
	Version *string `json:"version,omitempty"`
	// VMOsType - READ-ONLY; Specifies operating system used by the product. Possible values include: 'OperatingSystemNone', 'OperatingSystemWindows', 'OperatingSystemLinux'
	VMOsType OperatingSystem `json:"vmOsType,omitempty"`
	// VMScaleSetEnabled - READ-ONLY; Indicates if virtual machine Scale Set is enabled in the specified product.
	VMScaleSetEnabled *bool `json:"vmScaleSetEnabled,omitempty"`
}

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

// UnmarshalJSON is the custom unmarshaler for VirtualMachineExtensionProductProperties struct.
func (vmepp *VirtualMachineExtensionProductProperties) 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 "computeRole":
			if v != nil {
				var computeRole ComputeRole
				err = json.Unmarshal(*v, &computeRole)
				if err != nil {
					return err
				}
				vmepp.ComputeRole = computeRole
			}
		case "isSystemExtension":
			if v != nil {
				var isSystemExtension bool
				err = json.Unmarshal(*v, &isSystemExtension)
				if err != nil {
					return err
				}
				vmepp.IsSystemExtension = &isSystemExtension
			}
		case "sourceBlob":
			if v != nil {
				var URI URI
				err = json.Unmarshal(*v, &URI)
				if err != nil {
					return err
				}
				vmepp.URI = &URI
			}
		case "supportMultipleExtensions":
			if v != nil {
				var supportMultipleExtensions bool
				err = json.Unmarshal(*v, &supportMultipleExtensions)
				if err != nil {
					return err
				}
				vmepp.SupportMultipleExtensions = &supportMultipleExtensions
			}
		case "version":
			if v != nil {
				var version string
				err = json.Unmarshal(*v, &version)
				if err != nil {
					return err
				}
				vmepp.Version = &version
			}
		case "vmOsType":
			if v != nil {
				var VMOsType OperatingSystem
				err = json.Unmarshal(*v, &VMOsType)
				if err != nil {
					return err
				}
				vmepp.VMOsType = VMOsType
			}
		case "vmScaleSetEnabled":
			if v != nil {
				var VMScaleSetEnabled bool
				err = json.Unmarshal(*v, &VMScaleSetEnabled)
				if err != nil {
					return err
				}
				vmepp.VMScaleSetEnabled = &VMScaleSetEnabled
			}
		}
	}

	return nil
}

// VirtualMachineProductProperties product information.
type VirtualMachineProductProperties struct {
	// Version - READ-ONLY; Specifies product version.
	Version *string `json:"version,omitempty"`
	// OsDiskImage - READ-ONLY; OS disk image used by product.
	OsDiskImage *OsDiskImage `json:"osDiskImage,omitempty"`
	// DataDiskImages - READ-ONLY; List of attached data disks.
	DataDiskImages *[]DataDiskImage `json:"dataDiskImages,omitempty"`
}
