package managedapplications

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

// ApplianceArtifactType enumerates the values for appliance artifact type.
type ApplianceArtifactType string

const (
	// Custom ...
	Custom ApplianceArtifactType = "Custom"
	// Template ...
	Template ApplianceArtifactType = "Template"
)

// PossibleApplianceArtifactTypeValues returns an array of possible values for the ApplianceArtifactType const type.
func PossibleApplianceArtifactTypeValues() []ApplianceArtifactType {
	return []ApplianceArtifactType{Custom, Template}
}

// ApplianceLockLevel enumerates the values for appliance lock level.
type ApplianceLockLevel string

const (
	// CanNotDelete ...
	CanNotDelete ApplianceLockLevel = "CanNotDelete"
	// None ...
	None ApplianceLockLevel = "None"
	// ReadOnly ...
	ReadOnly ApplianceLockLevel = "ReadOnly"
)

// PossibleApplianceLockLevelValues returns an array of possible values for the ApplianceLockLevel const type.
func PossibleApplianceLockLevelValues() []ApplianceLockLevel {
	return []ApplianceLockLevel{CanNotDelete, None, ReadOnly}
}

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

const (
	// Accepted ...
	Accepted ProvisioningState = "Accepted"
	// Canceled ...
	Canceled ProvisioningState = "Canceled"
	// Created ...
	Created ProvisioningState = "Created"
	// Creating ...
	Creating ProvisioningState = "Creating"
	// Deleted ...
	Deleted ProvisioningState = "Deleted"
	// Deleting ...
	Deleting ProvisioningState = "Deleting"
	// Failed ...
	Failed ProvisioningState = "Failed"
	// Ready ...
	Ready ProvisioningState = "Ready"
	// Running ...
	Running ProvisioningState = "Running"
	// 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{Accepted, Canceled, Created, Creating, Deleted, Deleting, Failed, Ready, Running, Succeeded, Updating}
}

// ResourceIdentityType enumerates the values for resource identity type.
type ResourceIdentityType string

const (
	// SystemAssigned ...
	SystemAssigned ResourceIdentityType = "SystemAssigned"
)

// PossibleResourceIdentityTypeValues returns an array of possible values for the ResourceIdentityType const type.
func PossibleResourceIdentityTypeValues() []ResourceIdentityType {
	return []ResourceIdentityType{SystemAssigned}
}

// Appliance information about appliance.
type Appliance struct {
	autorest.Response `json:"-"`
	// ApplianceProperties - The appliance properties.
	*ApplianceProperties `json:"properties,omitempty"`
	// Plan - The plan information.
	Plan *Plan `json:"plan,omitempty"`
	// Kind - The kind of the appliance. Allowed values are MarketPlace and ServiceCatalog.
	Kind *string `json:"kind,omitempty"`
	// ManagedBy - ID of the resource that manages this resource.
	ManagedBy *string `json:"managedBy,omitempty"`
	// Sku - The SKU of the resource.
	Sku *Sku `json:"sku,omitempty"`
	// Identity - The identity of the resource.
	Identity *Identity `json:"identity,omitempty"`
	// ID - Resource ID
	ID *string `json:"id,omitempty"`
	// Name - Resource name
	Name *string `json:"name,omitempty"`
	// Type - Resource type
	Type *string `json:"type,omitempty"`
	// Location - Resource location
	Location *string `json:"location,omitempty"`
	// Tags - Resource tags
	Tags map[string]*string `json:"tags"`
}

// MarshalJSON is the custom marshaler for Appliance.
func (a Appliance) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]interface{})
	if a.ApplianceProperties != nil {
		objectMap["properties"] = a.ApplianceProperties
	}
	if a.Plan != nil {
		objectMap["plan"] = a.Plan
	}
	if a.Kind != nil {
		objectMap["kind"] = a.Kind
	}
	if a.ManagedBy != nil {
		objectMap["managedBy"] = a.ManagedBy
	}
	if a.Sku != nil {
		objectMap["sku"] = a.Sku
	}
	if a.Identity != nil {
		objectMap["identity"] = a.Identity
	}
	if a.ID != nil {
		objectMap["id"] = a.ID
	}
	if a.Name != nil {
		objectMap["name"] = a.Name
	}
	if a.Type != nil {
		objectMap["type"] = a.Type
	}
	if a.Location != nil {
		objectMap["location"] = a.Location
	}
	if a.Tags != nil {
		objectMap["tags"] = a.Tags
	}
	return json.Marshal(objectMap)
}

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

	return nil
}

// ApplianceArtifact appliance artifact.
type ApplianceArtifact struct {
	// Name - The appliance artifact name.
	Name *string `json:"name,omitempty"`
	// URI - The appliance artifact blob uri.
	URI *string `json:"uri,omitempty"`
	// Type - The the appliance artifact type. Possible values include: 'Template', 'Custom'
	Type ApplianceArtifactType `json:"type,omitempty"`
}

// ApplianceDefinition information about appliance definition.
type ApplianceDefinition struct {
	autorest.Response `json:"-"`
	// ApplianceDefinitionProperties - The appliance definition properties.
	*ApplianceDefinitionProperties `json:"properties,omitempty"`
	// ManagedBy - ID of the resource that manages this resource.
	ManagedBy *string `json:"managedBy,omitempty"`
	// Sku - The SKU of the resource.
	Sku *Sku `json:"sku,omitempty"`
	// Identity - The identity of the resource.
	Identity *Identity `json:"identity,omitempty"`
	// ID - Resource ID
	ID *string `json:"id,omitempty"`
	// Name - Resource name
	Name *string `json:"name,omitempty"`
	// Type - Resource type
	Type *string `json:"type,omitempty"`
	// Location - Resource location
	Location *string `json:"location,omitempty"`
	// Tags - Resource tags
	Tags map[string]*string `json:"tags"`
}

// MarshalJSON is the custom marshaler for ApplianceDefinition.
func (ad ApplianceDefinition) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]interface{})
	if ad.ApplianceDefinitionProperties != nil {
		objectMap["properties"] = ad.ApplianceDefinitionProperties
	}
	if ad.ManagedBy != nil {
		objectMap["managedBy"] = ad.ManagedBy
	}
	if ad.Sku != nil {
		objectMap["sku"] = ad.Sku
	}
	if ad.Identity != nil {
		objectMap["identity"] = ad.Identity
	}
	if ad.ID != nil {
		objectMap["id"] = ad.ID
	}
	if ad.Name != nil {
		objectMap["name"] = ad.Name
	}
	if ad.Type != nil {
		objectMap["type"] = ad.Type
	}
	if ad.Location != nil {
		objectMap["location"] = ad.Location
	}
	if ad.Tags != nil {
		objectMap["tags"] = ad.Tags
	}
	return json.Marshal(objectMap)
}

// UnmarshalJSON is the custom unmarshaler for ApplianceDefinition struct.
func (ad *ApplianceDefinition) 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 applianceDefinitionProperties ApplianceDefinitionProperties
				err = json.Unmarshal(*v, &applianceDefinitionProperties)
				if err != nil {
					return err
				}
				ad.ApplianceDefinitionProperties = &applianceDefinitionProperties
			}
		case "managedBy":
			if v != nil {
				var managedBy string
				err = json.Unmarshal(*v, &managedBy)
				if err != nil {
					return err
				}
				ad.ManagedBy = &managedBy
			}
		case "sku":
			if v != nil {
				var sku Sku
				err = json.Unmarshal(*v, &sku)
				if err != nil {
					return err
				}
				ad.Sku = &sku
			}
		case "identity":
			if v != nil {
				var identity Identity
				err = json.Unmarshal(*v, &identity)
				if err != nil {
					return err
				}
				ad.Identity = &identity
			}
		case "id":
			if v != nil {
				var ID string
				err = json.Unmarshal(*v, &ID)
				if err != nil {
					return err
				}
				ad.ID = &ID
			}
		case "name":
			if v != nil {
				var name string
				err = json.Unmarshal(*v, &name)
				if err != nil {
					return err
				}
				ad.Name = &name
			}
		case "type":
			if v != nil {
				var typeVar string
				err = json.Unmarshal(*v, &typeVar)
				if err != nil {
					return err
				}
				ad.Type = &typeVar
			}
		case "location":
			if v != nil {
				var location string
				err = json.Unmarshal(*v, &location)
				if err != nil {
					return err
				}
				ad.Location = &location
			}
		case "tags":
			if v != nil {
				var tags map[string]*string
				err = json.Unmarshal(*v, &tags)
				if err != nil {
					return err
				}
				ad.Tags = tags
			}
		}
	}

	return nil
}

// ApplianceDefinitionListResult list of appliance definitions.
type ApplianceDefinitionListResult struct {
	autorest.Response `json:"-"`
	// Value - The array of appliance definitions.
	Value *[]ApplianceDefinition `json:"value,omitempty"`
	// NextLink - The URL to use for getting the next set of results.
	NextLink *string `json:"nextLink,omitempty"`
}

// ApplianceDefinitionListResultIterator provides access to a complete listing of ApplianceDefinition values.
type ApplianceDefinitionListResultIterator struct {
	i    int
	page ApplianceDefinitionListResultPage
}

// Next 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 *ApplianceDefinitionListResultIterator) Next() error {
	iter.i++
	if iter.i < len(iter.page.Values()) {
		return nil
	}
	err := iter.page.Next()
	if err != nil {
		iter.i--
		return err
	}
	iter.i = 0
	return nil
}

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

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

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

// ApplianceDefinitionListResultPage contains a page of ApplianceDefinition values.
type ApplianceDefinitionListResultPage struct {
	fn   func(ApplianceDefinitionListResult) (ApplianceDefinitionListResult, error)
	adlr ApplianceDefinitionListResult
}

// 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.
func (page *ApplianceDefinitionListResultPage) Next() error {
	next, err := page.fn(page.adlr)
	if err != nil {
		return err
	}
	page.adlr = next
	return nil
}

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

// Response returns the raw server response from the last page request.
func (page ApplianceDefinitionListResultPage) Response() ApplianceDefinitionListResult {
	return page.adlr
}

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

// ApplianceDefinitionProperties the appliance definition properties.
type ApplianceDefinitionProperties struct {
	// LockLevel - The appliance lock level. Possible values include: 'CanNotDelete', 'ReadOnly', 'None'
	LockLevel ApplianceLockLevel `json:"lockLevel,omitempty"`
	// DisplayName - The appliance definition display name.
	DisplayName *string `json:"displayName,omitempty"`
	// Authorizations - The appliance provider authorizations.
	Authorizations *[]ApplianceProviderAuthorization `json:"authorizations,omitempty"`
	// Artifacts - The collection of appliance artifacts. The portal will use the files specified as artifacts to construct the user experience of creating an appliance from an appliance definition.
	Artifacts *[]ApplianceArtifact `json:"artifacts,omitempty"`
	// Description - The appliance definition description.
	Description *string `json:"description,omitempty"`
	// PackageFileURI - The appliance definition package file Uri.
	PackageFileURI *string `json:"packageFileUri,omitempty"`
}

// ApplianceDefinitionsCreateOrUpdateByIDFuture an abstraction for monitoring and retrieving the results of a
// long-running operation.
type ApplianceDefinitionsCreateOrUpdateByIDFuture struct {
	azure.Future
}

// Result returns the result of the asynchronous operation.
// If the operation has not completed it will return an error.
func (future *ApplianceDefinitionsCreateOrUpdateByIDFuture) Result(client ApplianceDefinitionsClient) (ad ApplianceDefinition, err error) {
	var done bool
	done, err = future.Done(client)
	if err != nil {
		err = autorest.NewErrorWithError(err, "managedapplications.ApplianceDefinitionsCreateOrUpdateByIDFuture", "Result", future.Response(), "Polling failure")
		return
	}
	if !done {
		err = azure.NewAsyncOpIncompleteError("managedapplications.ApplianceDefinitionsCreateOrUpdateByIDFuture")
		return
	}
	sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...))
	if ad.Response.Response, err = future.GetResult(sender); err == nil && ad.Response.Response.StatusCode != http.StatusNoContent {
		ad, err = client.CreateOrUpdateByIDResponder(ad.Response.Response)
		if err != nil {
			err = autorest.NewErrorWithError(err, "managedapplications.ApplianceDefinitionsCreateOrUpdateByIDFuture", "Result", ad.Response.Response, "Failure responding to request")
		}
	}
	return
}

// ApplianceDefinitionsCreateOrUpdateFuture an abstraction for monitoring and retrieving the results of a
// long-running operation.
type ApplianceDefinitionsCreateOrUpdateFuture struct {
	azure.Future
}

// Result returns the result of the asynchronous operation.
// If the operation has not completed it will return an error.
func (future *ApplianceDefinitionsCreateOrUpdateFuture) Result(client ApplianceDefinitionsClient) (ad ApplianceDefinition, err error) {
	var done bool
	done, err = future.Done(client)
	if err != nil {
		err = autorest.NewErrorWithError(err, "managedapplications.ApplianceDefinitionsCreateOrUpdateFuture", "Result", future.Response(), "Polling failure")
		return
	}
	if !done {
		err = azure.NewAsyncOpIncompleteError("managedapplications.ApplianceDefinitionsCreateOrUpdateFuture")
		return
	}
	sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...))
	if ad.Response.Response, err = future.GetResult(sender); err == nil && ad.Response.Response.StatusCode != http.StatusNoContent {
		ad, err = client.CreateOrUpdateResponder(ad.Response.Response)
		if err != nil {
			err = autorest.NewErrorWithError(err, "managedapplications.ApplianceDefinitionsCreateOrUpdateFuture", "Result", ad.Response.Response, "Failure responding to request")
		}
	}
	return
}

// ApplianceDefinitionsDeleteByIDFuture an abstraction for monitoring and retrieving the results of a long-running
// operation.
type ApplianceDefinitionsDeleteByIDFuture struct {
	azure.Future
}

// Result returns the result of the asynchronous operation.
// If the operation has not completed it will return an error.
func (future *ApplianceDefinitionsDeleteByIDFuture) Result(client ApplianceDefinitionsClient) (ar autorest.Response, err error) {
	var done bool
	done, err = future.Done(client)
	if err != nil {
		err = autorest.NewErrorWithError(err, "managedapplications.ApplianceDefinitionsDeleteByIDFuture", "Result", future.Response(), "Polling failure")
		return
	}
	if !done {
		err = azure.NewAsyncOpIncompleteError("managedapplications.ApplianceDefinitionsDeleteByIDFuture")
		return
	}
	ar.Response = future.Response()
	return
}

// ApplianceDefinitionsDeleteFuture an abstraction for monitoring and retrieving the results of a long-running
// operation.
type ApplianceDefinitionsDeleteFuture struct {
	azure.Future
}

// Result returns the result of the asynchronous operation.
// If the operation has not completed it will return an error.
func (future *ApplianceDefinitionsDeleteFuture) Result(client ApplianceDefinitionsClient) (ar autorest.Response, err error) {
	var done bool
	done, err = future.Done(client)
	if err != nil {
		err = autorest.NewErrorWithError(err, "managedapplications.ApplianceDefinitionsDeleteFuture", "Result", future.Response(), "Polling failure")
		return
	}
	if !done {
		err = azure.NewAsyncOpIncompleteError("managedapplications.ApplianceDefinitionsDeleteFuture")
		return
	}
	ar.Response = future.Response()
	return
}

// ApplianceListResult list of appliances.
type ApplianceListResult struct {
	autorest.Response `json:"-"`
	// Value - The array of appliances.
	Value *[]Appliance `json:"value,omitempty"`
	// NextLink - The URL to use for getting the next set of results.
	NextLink *string `json:"nextLink,omitempty"`
}

// ApplianceListResultIterator provides access to a complete listing of Appliance values.
type ApplianceListResultIterator struct {
	i    int
	page ApplianceListResultPage
}

// Next 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 *ApplianceListResultIterator) Next() error {
	iter.i++
	if iter.i < len(iter.page.Values()) {
		return nil
	}
	err := iter.page.Next()
	if err != nil {
		iter.i--
		return err
	}
	iter.i = 0
	return nil
}

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

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

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

// ApplianceListResultPage contains a page of Appliance values.
type ApplianceListResultPage struct {
	fn  func(ApplianceListResult) (ApplianceListResult, error)
	alr ApplianceListResult
}

// 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.
func (page *ApplianceListResultPage) Next() error {
	next, err := page.fn(page.alr)
	if err != nil {
		return err
	}
	page.alr = next
	return nil
}

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

// Response returns the raw server response from the last page request.
func (page ApplianceListResultPage) Response() ApplianceListResult {
	return page.alr
}

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

// AppliancePatchable information about appliance.
type AppliancePatchable struct {
	// AppliancePropertiesPatchable - The appliance properties.
	*AppliancePropertiesPatchable `json:"properties,omitempty"`
	// Plan - The plan information.
	Plan *PlanPatchable `json:"plan,omitempty"`
	// Kind - The kind of the appliance. Allowed values are MarketPlace and ServiceCatalog.
	Kind *string `json:"kind,omitempty"`
	// ManagedBy - ID of the resource that manages this resource.
	ManagedBy *string `json:"managedBy,omitempty"`
	// Sku - The SKU of the resource.
	Sku *Sku `json:"sku,omitempty"`
	// Identity - The identity of the resource.
	Identity *Identity `json:"identity,omitempty"`
	// ID - Resource ID
	ID *string `json:"id,omitempty"`
	// Name - Resource name
	Name *string `json:"name,omitempty"`
	// Type - Resource type
	Type *string `json:"type,omitempty"`
	// Location - Resource location
	Location *string `json:"location,omitempty"`
	// Tags - Resource tags
	Tags map[string]*string `json:"tags"`
}

// MarshalJSON is the custom marshaler for AppliancePatchable.
func (ap AppliancePatchable) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]interface{})
	if ap.AppliancePropertiesPatchable != nil {
		objectMap["properties"] = ap.AppliancePropertiesPatchable
	}
	if ap.Plan != nil {
		objectMap["plan"] = ap.Plan
	}
	if ap.Kind != nil {
		objectMap["kind"] = ap.Kind
	}
	if ap.ManagedBy != nil {
		objectMap["managedBy"] = ap.ManagedBy
	}
	if ap.Sku != nil {
		objectMap["sku"] = ap.Sku
	}
	if ap.Identity != nil {
		objectMap["identity"] = ap.Identity
	}
	if ap.ID != nil {
		objectMap["id"] = ap.ID
	}
	if ap.Name != nil {
		objectMap["name"] = ap.Name
	}
	if ap.Type != nil {
		objectMap["type"] = ap.Type
	}
	if ap.Location != nil {
		objectMap["location"] = ap.Location
	}
	if ap.Tags != nil {
		objectMap["tags"] = ap.Tags
	}
	return json.Marshal(objectMap)
}

// UnmarshalJSON is the custom unmarshaler for AppliancePatchable struct.
func (ap *AppliancePatchable) 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 appliancePropertiesPatchable AppliancePropertiesPatchable
				err = json.Unmarshal(*v, &appliancePropertiesPatchable)
				if err != nil {
					return err
				}
				ap.AppliancePropertiesPatchable = &appliancePropertiesPatchable
			}
		case "plan":
			if v != nil {
				var plan PlanPatchable
				err = json.Unmarshal(*v, &plan)
				if err != nil {
					return err
				}
				ap.Plan = &plan
			}
		case "kind":
			if v != nil {
				var kind string
				err = json.Unmarshal(*v, &kind)
				if err != nil {
					return err
				}
				ap.Kind = &kind
			}
		case "managedBy":
			if v != nil {
				var managedBy string
				err = json.Unmarshal(*v, &managedBy)
				if err != nil {
					return err
				}
				ap.ManagedBy = &managedBy
			}
		case "sku":
			if v != nil {
				var sku Sku
				err = json.Unmarshal(*v, &sku)
				if err != nil {
					return err
				}
				ap.Sku = &sku
			}
		case "identity":
			if v != nil {
				var identity Identity
				err = json.Unmarshal(*v, &identity)
				if err != nil {
					return err
				}
				ap.Identity = &identity
			}
		case "id":
			if v != nil {
				var ID string
				err = json.Unmarshal(*v, &ID)
				if err != nil {
					return err
				}
				ap.ID = &ID
			}
		case "name":
			if v != nil {
				var name string
				err = json.Unmarshal(*v, &name)
				if err != nil {
					return err
				}
				ap.Name = &name
			}
		case "type":
			if v != nil {
				var typeVar string
				err = json.Unmarshal(*v, &typeVar)
				if err != nil {
					return err
				}
				ap.Type = &typeVar
			}
		case "location":
			if v != nil {
				var location string
				err = json.Unmarshal(*v, &location)
				if err != nil {
					return err
				}
				ap.Location = &location
			}
		case "tags":
			if v != nil {
				var tags map[string]*string
				err = json.Unmarshal(*v, &tags)
				if err != nil {
					return err
				}
				ap.Tags = tags
			}
		}
	}

	return nil
}

// ApplianceProperties the appliance properties.
type ApplianceProperties struct {
	// ManagedResourceGroupID - The managed resource group Id.
	ManagedResourceGroupID *string `json:"managedResourceGroupId,omitempty"`
	// ApplianceDefinitionID - The fully qualified path of appliance definition Id.
	ApplianceDefinitionID *string `json:"applianceDefinitionId,omitempty"`
	// Parameters - Name and value pairs that define the appliance parameters. It can be a JObject or a well formed JSON string.
	Parameters interface{} `json:"parameters,omitempty"`
	// Outputs - Name and value pairs that define the appliance outputs.
	Outputs interface{} `json:"outputs,omitempty"`
	// ProvisioningState - The appliance provisioning state. Possible values include: 'Accepted', 'Running', 'Ready', 'Creating', 'Created', 'Deleting', 'Deleted', 'Canceled', 'Failed', 'Succeeded', 'Updating'
	ProvisioningState ProvisioningState `json:"provisioningState,omitempty"`
	// UIDefinitionURI - The blob URI where the UI definition file is located.
	UIDefinitionURI *string `json:"uiDefinitionUri,omitempty"`
}

// AppliancePropertiesPatchable the appliance properties.
type AppliancePropertiesPatchable struct {
	// ManagedResourceGroupID - The managed resource group Id.
	ManagedResourceGroupID *string `json:"managedResourceGroupId,omitempty"`
	// ApplianceDefinitionID - The fully qualified path of appliance definition Id.
	ApplianceDefinitionID *string `json:"applianceDefinitionId,omitempty"`
	// Parameters - Name and value pairs that define the appliance parameters. It can be a JObject or a well formed JSON string.
	Parameters interface{} `json:"parameters,omitempty"`
	// Outputs - Name and value pairs that define the appliance outputs.
	Outputs interface{} `json:"outputs,omitempty"`
	// ProvisioningState - The appliance provisioning state. Possible values include: 'Accepted', 'Running', 'Ready', 'Creating', 'Created', 'Deleting', 'Deleted', 'Canceled', 'Failed', 'Succeeded', 'Updating'
	ProvisioningState ProvisioningState `json:"provisioningState,omitempty"`
	// UIDefinitionURI - The blob URI where the UI definition file is located.
	UIDefinitionURI *string `json:"uiDefinitionUri,omitempty"`
}

// ApplianceProviderAuthorization the appliance provider authorization.
type ApplianceProviderAuthorization struct {
	// PrincipalID - The provider's principal identifier. This is the identity that the provider will use to call ARM to manage the appliance resources.
	PrincipalID *string `json:"principalId,omitempty"`
	// RoleDefinitionID - The provider's role definition identifier. This role will define all the permissions that the provider must have on the appliance's container resource group. This role definition cannot have permission to delete the resource group.
	RoleDefinitionID *string `json:"roleDefinitionId,omitempty"`
}

// AppliancesCreateOrUpdateByIDFuture an abstraction for monitoring and retrieving the results of a long-running
// operation.
type AppliancesCreateOrUpdateByIDFuture struct {
	azure.Future
}

// Result returns the result of the asynchronous operation.
// If the operation has not completed it will return an error.
func (future *AppliancesCreateOrUpdateByIDFuture) Result(client AppliancesClient) (a Appliance, err error) {
	var done bool
	done, err = future.Done(client)
	if err != nil {
		err = autorest.NewErrorWithError(err, "managedapplications.AppliancesCreateOrUpdateByIDFuture", "Result", future.Response(), "Polling failure")
		return
	}
	if !done {
		err = azure.NewAsyncOpIncompleteError("managedapplications.AppliancesCreateOrUpdateByIDFuture")
		return
	}
	sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...))
	if a.Response.Response, err = future.GetResult(sender); err == nil && a.Response.Response.StatusCode != http.StatusNoContent {
		a, err = client.CreateOrUpdateByIDResponder(a.Response.Response)
		if err != nil {
			err = autorest.NewErrorWithError(err, "managedapplications.AppliancesCreateOrUpdateByIDFuture", "Result", a.Response.Response, "Failure responding to request")
		}
	}
	return
}

// AppliancesCreateOrUpdateFuture an abstraction for monitoring and retrieving the results of a long-running
// operation.
type AppliancesCreateOrUpdateFuture struct {
	azure.Future
}

// Result returns the result of the asynchronous operation.
// If the operation has not completed it will return an error.
func (future *AppliancesCreateOrUpdateFuture) Result(client AppliancesClient) (a Appliance, err error) {
	var done bool
	done, err = future.Done(client)
	if err != nil {
		err = autorest.NewErrorWithError(err, "managedapplications.AppliancesCreateOrUpdateFuture", "Result", future.Response(), "Polling failure")
		return
	}
	if !done {
		err = azure.NewAsyncOpIncompleteError("managedapplications.AppliancesCreateOrUpdateFuture")
		return
	}
	sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...))
	if a.Response.Response, err = future.GetResult(sender); err == nil && a.Response.Response.StatusCode != http.StatusNoContent {
		a, err = client.CreateOrUpdateResponder(a.Response.Response)
		if err != nil {
			err = autorest.NewErrorWithError(err, "managedapplications.AppliancesCreateOrUpdateFuture", "Result", a.Response.Response, "Failure responding to request")
		}
	}
	return
}

// AppliancesDeleteByIDFuture an abstraction for monitoring and retrieving the results of a long-running operation.
type AppliancesDeleteByIDFuture struct {
	azure.Future
}

// Result returns the result of the asynchronous operation.
// If the operation has not completed it will return an error.
func (future *AppliancesDeleteByIDFuture) Result(client AppliancesClient) (ar autorest.Response, err error) {
	var done bool
	done, err = future.Done(client)
	if err != nil {
		err = autorest.NewErrorWithError(err, "managedapplications.AppliancesDeleteByIDFuture", "Result", future.Response(), "Polling failure")
		return
	}
	if !done {
		err = azure.NewAsyncOpIncompleteError("managedapplications.AppliancesDeleteByIDFuture")
		return
	}
	ar.Response = future.Response()
	return
}

// AppliancesDeleteFuture an abstraction for monitoring and retrieving the results of a long-running operation.
type AppliancesDeleteFuture struct {
	azure.Future
}

// Result returns the result of the asynchronous operation.
// If the operation has not completed it will return an error.
func (future *AppliancesDeleteFuture) Result(client AppliancesClient) (ar autorest.Response, err error) {
	var done bool
	done, err = future.Done(client)
	if err != nil {
		err = autorest.NewErrorWithError(err, "managedapplications.AppliancesDeleteFuture", "Result", future.Response(), "Polling failure")
		return
	}
	if !done {
		err = azure.NewAsyncOpIncompleteError("managedapplications.AppliancesDeleteFuture")
		return
	}
	ar.Response = future.Response()
	return
}

// ErrorResponse error reponse indicates ARM appliance is not able to process the incoming request. The reason is
// provided in the error message.
type ErrorResponse struct {
	// HTTPStatus - Http status code.
	HTTPStatus *string `json:"httpStatus,omitempty"`
	// ErrorCode - Error code.
	ErrorCode *string `json:"errorCode,omitempty"`
	// ErrorMessage - Error message indicating why the operation failed.
	ErrorMessage *string `json:"errorMessage,omitempty"`
}

// GenericResource resource information.
type GenericResource struct {
	// ManagedBy - ID of the resource that manages this resource.
	ManagedBy *string `json:"managedBy,omitempty"`
	// Sku - The SKU of the resource.
	Sku *Sku `json:"sku,omitempty"`
	// Identity - The identity of the resource.
	Identity *Identity `json:"identity,omitempty"`
	// ID - Resource ID
	ID *string `json:"id,omitempty"`
	// Name - Resource name
	Name *string `json:"name,omitempty"`
	// Type - Resource type
	Type *string `json:"type,omitempty"`
	// Location - Resource location
	Location *string `json:"location,omitempty"`
	// Tags - Resource tags
	Tags map[string]*string `json:"tags"`
}

// MarshalJSON is the custom marshaler for GenericResource.
func (gr GenericResource) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]interface{})
	if gr.ManagedBy != nil {
		objectMap["managedBy"] = gr.ManagedBy
	}
	if gr.Sku != nil {
		objectMap["sku"] = gr.Sku
	}
	if gr.Identity != nil {
		objectMap["identity"] = gr.Identity
	}
	if gr.ID != nil {
		objectMap["id"] = gr.ID
	}
	if gr.Name != nil {
		objectMap["name"] = gr.Name
	}
	if gr.Type != nil {
		objectMap["type"] = gr.Type
	}
	if gr.Location != nil {
		objectMap["location"] = gr.Location
	}
	if gr.Tags != nil {
		objectMap["tags"] = gr.Tags
	}
	return json.Marshal(objectMap)
}

// Identity identity for the resource.
type Identity struct {
	// PrincipalID - The principal ID of resource identity.
	PrincipalID *string `json:"principalId,omitempty"`
	// TenantID - The tenant ID of resource.
	TenantID *string `json:"tenantId,omitempty"`
	// Type - The identity type. Possible values include: 'SystemAssigned'
	Type ResourceIdentityType `json:"type,omitempty"`
}

// Plan plan for the appliance.
type Plan struct {
	// Name - The plan name.
	Name *string `json:"name,omitempty"`
	// Publisher - The publisher ID.
	Publisher *string `json:"publisher,omitempty"`
	// Product - The product code.
	Product *string `json:"product,omitempty"`
	// PromotionCode - The promotion code.
	PromotionCode *string `json:"promotionCode,omitempty"`
	// Version - The plan's version.
	Version *string `json:"version,omitempty"`
}

// PlanPatchable plan for the appliance.
type PlanPatchable struct {
	// Name - The plan name.
	Name *string `json:"name,omitempty"`
	// Publisher - The publisher ID.
	Publisher *string `json:"publisher,omitempty"`
	// Product - The product code.
	Product *string `json:"product,omitempty"`
	// PromotionCode - The promotion code.
	PromotionCode *string `json:"promotionCode,omitempty"`
	// Version - The plan's version.
	Version *string `json:"version,omitempty"`
}

// Resource resource information.
type Resource struct {
	// ID - Resource ID
	ID *string `json:"id,omitempty"`
	// Name - Resource name
	Name *string `json:"name,omitempty"`
	// Type - Resource type
	Type *string `json:"type,omitempty"`
	// Location - Resource location
	Location *string `json:"location,omitempty"`
	// Tags - Resource tags
	Tags map[string]*string `json:"tags"`
}

// MarshalJSON is the custom marshaler for Resource.
func (r Resource) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]interface{})
	if r.ID != nil {
		objectMap["id"] = r.ID
	}
	if r.Name != nil {
		objectMap["name"] = r.Name
	}
	if r.Type != nil {
		objectMap["type"] = r.Type
	}
	if r.Location != nil {
		objectMap["location"] = r.Location
	}
	if r.Tags != nil {
		objectMap["tags"] = r.Tags
	}
	return json.Marshal(objectMap)
}

// Sku SKU for the resource.
type Sku struct {
	// Name - The SKU name.
	Name *string `json:"name,omitempty"`
	// Tier - The SKU tier.
	Tier *string `json:"tier,omitempty"`
	// Size - The SKU size.
	Size *string `json:"size,omitempty"`
	// Family - The SKU family.
	Family *string `json:"family,omitempty"`
	// Model - The SKU model.
	Model *string `json:"model,omitempty"`
	// Capacity - The SKU capacity.
	Capacity *int32 `json:"capacity,omitempty"`
}
