package deploymentmanager

// Copyright (c) Microsoft and contributors.  All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//
// See the License for the specific language governing permissions and
// limitations under the License.
//
// Code generated by Microsoft (R) AutoRest Code Generator.
// Changes may cause incorrect behavior and will be lost if the code is regenerated.

import (
	"context"
	"encoding/json"
	"github.com/Azure/go-autorest/autorest"
	"github.com/Azure/go-autorest/autorest/azure"
	"github.com/Azure/go-autorest/autorest/date"
	"net/http"
)

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

// DeploymentMode enumerates the values for deployment mode.
type DeploymentMode string

const (
	// Complete ...
	Complete DeploymentMode = "Complete"
	// Incremental ...
	Incremental DeploymentMode = "Incremental"
)

// PossibleDeploymentModeValues returns an array of possible values for the DeploymentMode const type.
func PossibleDeploymentModeValues() []DeploymentMode {
	return []DeploymentMode{Complete, Incremental}
}

// StepType enumerates the values for step type.
type StepType string

const (
	// StepTypeStepProperties ...
	StepTypeStepProperties StepType = "StepProperties"
	// StepTypeWait ...
	StepTypeWait StepType = "Wait"
)

// PossibleStepTypeValues returns an array of possible values for the StepType const type.
func PossibleStepTypeValues() []StepType {
	return []StepType{StepTypeStepProperties, StepTypeWait}
}

// Type enumerates the values for type.
type Type string

const (
	// TypeAuthentication ...
	TypeAuthentication Type = "Authentication"
	// TypeSas ...
	TypeSas Type = "Sas"
)

// PossibleTypeValues returns an array of possible values for the Type const type.
func PossibleTypeValues() []Type {
	return []Type{TypeAuthentication, TypeSas}
}

// ArtifactSource the resource that defines the source location where the artifacts are located.
type ArtifactSource struct {
	autorest.Response `json:"-"`
	// ArtifactSourceProperties - The properties that define the artifact source.
	*ArtifactSourceProperties `json:"properties,omitempty"`
	// Tags - Resource tags.
	Tags map[string]*string `json:"tags"`
	// Location - The geo-location where the resource lives
	Location *string `json:"location,omitempty"`
	// ID - READ-ONLY; Fully qualified resource Id for the resource. Ex - /subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/{resourceProviderNamespace}/{resourceType}/{resourceName}
	ID *string `json:"id,omitempty"`
	// Name - READ-ONLY; The name of the resource
	Name *string `json:"name,omitempty"`
	// Type - READ-ONLY; The type of the resource. Ex- Microsoft.Compute/virtualMachines or Microsoft.Storage/storageAccounts.
	Type *string `json:"type,omitempty"`
}

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

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

	return nil
}

// ArtifactSourceProperties the properties that define the artifact source.
type ArtifactSourceProperties struct {
	// SourceType - The type of artifact source used.
	SourceType *string `json:"sourceType,omitempty"`
	// ArtifactRoot - The path from the location that the 'authentication' property [say, a SAS URI to the blob container] refers to, to the location of the artifacts. This can be used to differentiate different versions of the artifacts. Or, different types of artifacts like binaries or templates. The location referenced by the authentication property concatenated with this optional artifactRoot path forms the artifact source location where the artifacts are expected to be found.
	ArtifactRoot *string `json:"artifactRoot,omitempty"`
	// Authentication - The authentication method to use to access the artifact source.
	Authentication BasicAuthentication `json:"authentication,omitempty"`
}

// UnmarshalJSON is the custom unmarshaler for ArtifactSourceProperties struct.
func (as *ArtifactSourceProperties) 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 "sourceType":
			if v != nil {
				var sourceType string
				err = json.Unmarshal(*v, &sourceType)
				if err != nil {
					return err
				}
				as.SourceType = &sourceType
			}
		case "artifactRoot":
			if v != nil {
				var artifactRoot string
				err = json.Unmarshal(*v, &artifactRoot)
				if err != nil {
					return err
				}
				as.ArtifactRoot = &artifactRoot
			}
		case "authentication":
			if v != nil {
				authentication, err := unmarshalBasicAuthentication(*v)
				if err != nil {
					return err
				}
				as.Authentication = authentication
			}
		}
	}

	return nil
}

// ArtifactSourcePropertiesModel the properties that define the source location where the artifacts are
// located.
type ArtifactSourcePropertiesModel struct {
	// SourceType - The type of artifact source used.
	SourceType *string `json:"sourceType,omitempty"`
	// ArtifactRoot - The path from the location that the 'authentication' property [say, a SAS URI to the blob container] refers to, to the location of the artifacts. This can be used to differentiate different versions of the artifacts. Or, different types of artifacts like binaries or templates. The location referenced by the authentication property concatenated with this optional artifactRoot path forms the artifact source location where the artifacts are expected to be found.
	ArtifactRoot *string `json:"artifactRoot,omitempty"`
	// Authentication - The authentication method to use to access the artifact source.
	Authentication BasicAuthentication `json:"authentication,omitempty"`
}

// UnmarshalJSON is the custom unmarshaler for ArtifactSourcePropertiesModel struct.
func (aspm *ArtifactSourcePropertiesModel) 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 "sourceType":
			if v != nil {
				var sourceType string
				err = json.Unmarshal(*v, &sourceType)
				if err != nil {
					return err
				}
				aspm.SourceType = &sourceType
			}
		case "artifactRoot":
			if v != nil {
				var artifactRoot string
				err = json.Unmarshal(*v, &artifactRoot)
				if err != nil {
					return err
				}
				aspm.ArtifactRoot = &artifactRoot
			}
		case "authentication":
			if v != nil {
				authentication, err := unmarshalBasicAuthentication(*v)
				if err != nil {
					return err
				}
				aspm.Authentication = authentication
			}
		}
	}

	return nil
}

// BasicAuthentication defines the authentication method and properties to access the artifacts.
type BasicAuthentication interface {
	AsSasAuthentication() (*SasAuthentication, bool)
	AsAuthentication() (*Authentication, bool)
}

// Authentication defines the authentication method and properties to access the artifacts.
type Authentication struct {
	// Type - Possible values include: 'TypeAuthentication', 'TypeSas'
	Type Type `json:"type,omitempty"`
}

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

	switch m["type"] {
	case string(TypeSas):
		var sa SasAuthentication
		err := json.Unmarshal(body, &sa)
		return sa, err
	default:
		var a Authentication
		err := json.Unmarshal(body, &a)
		return a, err
	}
}
func unmarshalBasicAuthenticationArray(body []byte) ([]BasicAuthentication, error) {
	var rawMessages []*json.RawMessage
	err := json.Unmarshal(body, &rawMessages)
	if err != nil {
		return nil, err
	}

	aArray := make([]BasicAuthentication, len(rawMessages))

	for index, rawMessage := range rawMessages {
		a, err := unmarshalBasicAuthentication(*rawMessage)
		if err != nil {
			return nil, err
		}
		aArray[index] = a
	}
	return aArray, nil
}

// MarshalJSON is the custom marshaler for Authentication.
func (a Authentication) MarshalJSON() ([]byte, error) {
	a.Type = TypeAuthentication
	objectMap := make(map[string]interface{})
	if a.Type != "" {
		objectMap["type"] = a.Type
	}
	return json.Marshal(objectMap)
}

// AsSasAuthentication is the BasicAuthentication implementation for Authentication.
func (a Authentication) AsSasAuthentication() (*SasAuthentication, bool) {
	return nil, false
}

// AsAuthentication is the BasicAuthentication implementation for Authentication.
func (a Authentication) AsAuthentication() (*Authentication, bool) {
	return &a, true
}

// AsBasicAuthentication is the BasicAuthentication implementation for Authentication.
func (a Authentication) AsBasicAuthentication() (BasicAuthentication, bool) {
	return &a, true
}

// AzureEntityResource the resource model definition for a Azure Resource Manager resource with an etag.
type AzureEntityResource struct {
	// Etag - READ-ONLY; Resource Etag.
	Etag *string `json:"etag,omitempty"`
	// ID - READ-ONLY; Fully qualified resource Id for the resource. Ex - /subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/{resourceProviderNamespace}/{resourceType}/{resourceName}
	ID *string `json:"id,omitempty"`
	// Name - READ-ONLY; The name of the resource
	Name *string `json:"name,omitempty"`
	// Type - READ-ONLY; The type of the resource. Ex- Microsoft.Compute/virtualMachines or Microsoft.Storage/storageAccounts.
	Type *string `json:"type,omitempty"`
}

// CloudError the error information object.
type CloudError struct {
	// Error - The properties that define the error.
	Error *CloudErrorBody `json:"error,omitempty"`
}

// CloudErrorBody detailed error information of any failure.
type CloudErrorBody struct {
	// Code - READ-ONLY; Error code string.
	Code *string `json:"code,omitempty"`
	// Message - READ-ONLY; Descriptive error information.
	Message *string `json:"message,omitempty"`
	// Target - Error target
	Target *string `json:"target,omitempty"`
	// Details - More detailed error information.
	Details *[]CloudErrorBody `json:"details,omitempty"`
}

// Identity identity for the resource.
type Identity struct {
	// Type - The identity type.
	Type *string `json:"type,omitempty"`
	// IdentityIds - The list of identities.
	IdentityIds *[]string `json:"identityIds,omitempty"`
}

// ListOperation ...
type ListOperation struct {
	autorest.Response `json:"-"`
	Value             *[]Operation `json:"value,omitempty"`
}

// Message supplementary contextual messages during a rollout.
type Message struct {
	// TimeStamp - READ-ONLY; Time in UTC this message was provided.
	TimeStamp *date.Time `json:"timeStamp,omitempty"`
	// Message - READ-ONLY; The actual message text.
	Message *string `json:"message,omitempty"`
}

// Operation represents an operation that can be performed on the service.
type Operation struct {
	// Name - The name of the operation.
	Name *string `json:"name,omitempty"`
	// Display - The display name of the operation.
	Display *OperationDetail `json:"display,omitempty"`
	// Origin - The origin of the operation.
	Origin *string `json:"origin,omitempty"`
	// Properties - The properties of the operation.
	Properties interface{} `json:"properties,omitempty"`
}

// OperationDetail the detail about an operation.
type OperationDetail struct {
	// Provider - The name of the provider that supports the operation.
	Provider *string `json:"provider,omitempty"`
	// Resource - The resource type on which this operation can be performed.
	Resource *string `json:"resource,omitempty"`
	// Operation - The name of the operation.
	Operation *string `json:"operation,omitempty"`
	// Description - The description of the operation.
	Description *string `json:"description,omitempty"`
}

// PrePostStep the properties that define a step.
type PrePostStep struct {
	// StepID - The resource Id of the step to be run.
	StepID *string `json:"stepId,omitempty"`
}

// ProxyResource the resource model definition for a ARM proxy resource. It will have everything other than
// required location and tags
type ProxyResource struct {
	// ID - READ-ONLY; Fully qualified resource Id for the resource. Ex - /subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/{resourceProviderNamespace}/{resourceType}/{resourceName}
	ID *string `json:"id,omitempty"`
	// Name - READ-ONLY; The name of the resource
	Name *string `json:"name,omitempty"`
	// Type - READ-ONLY; The type of the resource. Ex- Microsoft.Compute/virtualMachines or Microsoft.Storage/storageAccounts.
	Type *string `json:"type,omitempty"`
}

// Resource ...
type Resource struct {
	// ID - READ-ONLY; Fully qualified resource Id for the resource. Ex - /subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/{resourceProviderNamespace}/{resourceType}/{resourceName}
	ID *string `json:"id,omitempty"`
	// Name - READ-ONLY; The name of the resource
	Name *string `json:"name,omitempty"`
	// Type - READ-ONLY; The type of the resource. Ex- Microsoft.Compute/virtualMachines or Microsoft.Storage/storageAccounts.
	Type *string `json:"type,omitempty"`
}

// ResourceOperation individual resource operation information.
type ResourceOperation struct {
	// ResourceName - Name of the resource as specified in the artifacts. For ARM resources, this is the name of the resource specified in the template.
	ResourceName *string `json:"resourceName,omitempty"`
	// OperationID - READ-ONLY; Unique identifier of the operation. For ARM resources, this is the operationId obtained from ARM service.
	OperationID *string `json:"operationId,omitempty"`
	// ResourceType - Type of the resource as specified in the artifacts. For ARM resources, this is the type of the resource specified in the template.
	ResourceType *string `json:"resourceType,omitempty"`
	// ProvisioningState - READ-ONLY; State of the resource deployment. For ARM resources, this is the current provisioning state of the resource.
	ProvisioningState *string `json:"provisioningState,omitempty"`
	// StatusMessage - READ-ONLY; Descriptive information of the resource operation.
	StatusMessage *string `json:"statusMessage,omitempty"`
	// StatusCode - READ-ONLY; Http status code of the operation.
	StatusCode *string `json:"statusCode,omitempty"`
}

// Rollout defines the rollout.
type Rollout struct {
	autorest.Response `json:"-"`
	// Identity - Identity for the resource.
	Identity *Identity `json:"identity,omitempty"`
	// RolloutProperties - The properties that define a rollout.
	*RolloutProperties `json:"properties,omitempty"`
	// Tags - Resource tags.
	Tags map[string]*string `json:"tags"`
	// Location - The geo-location where the resource lives
	Location *string `json:"location,omitempty"`
	// ID - READ-ONLY; Fully qualified resource Id for the resource. Ex - /subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/{resourceProviderNamespace}/{resourceType}/{resourceName}
	ID *string `json:"id,omitempty"`
	// Name - READ-ONLY; The name of the resource
	Name *string `json:"name,omitempty"`
	// Type - READ-ONLY; The type of the resource. Ex- Microsoft.Compute/virtualMachines or Microsoft.Storage/storageAccounts.
	Type *string `json:"type,omitempty"`
}

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

// UnmarshalJSON is the custom unmarshaler for Rollout struct.
func (r *Rollout) 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 "identity":
			if v != nil {
				var identity Identity
				err = json.Unmarshal(*v, &identity)
				if err != nil {
					return err
				}
				r.Identity = &identity
			}
		case "properties":
			if v != nil {
				var rolloutProperties RolloutProperties
				err = json.Unmarshal(*v, &rolloutProperties)
				if err != nil {
					return err
				}
				r.RolloutProperties = &rolloutProperties
			}
		case "tags":
			if v != nil {
				var tags map[string]*string
				err = json.Unmarshal(*v, &tags)
				if err != nil {
					return err
				}
				r.Tags = tags
			}
		case "location":
			if v != nil {
				var location string
				err = json.Unmarshal(*v, &location)
				if err != nil {
					return err
				}
				r.Location = &location
			}
		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
			}
		}
	}

	return nil
}

// RolloutOperationInfo detailed runtime information of the rollout.
type RolloutOperationInfo struct {
	// RetryAttempt - READ-ONLY; The ordinal count of the number of retry attempts on a rollout. 0 if no retries of the rollout have been performed. If the rollout is updated with a PUT, this count is reset to 0.
	RetryAttempt *int32 `json:"retryAttempt,omitempty"`
	// SkipSucceededOnRetry - READ-ONLY; True, if all steps that succeeded on the previous run/attempt were chosen to be skipped in this retry attempt. False, otherwise.
	SkipSucceededOnRetry *bool `json:"skipSucceededOnRetry,omitempty"`
	// StartTime - READ-ONLY; The start time of the rollout in UTC.
	StartTime *date.Time `json:"startTime,omitempty"`
	// EndTime - READ-ONLY; The start time of the rollout in UTC. This property will not be set if the rollout has not completed yet.
	EndTime *date.Time `json:"endTime,omitempty"`
	// Error - READ-ONLY; The detailed error information for any failure.
	Error *CloudErrorBody `json:"error,omitempty"`
}

// RolloutProperties the properties that define a rollout.
type RolloutProperties struct {
	// BuildVersion - The version of the build being deployed.
	BuildVersion *string `json:"buildVersion,omitempty"`
	// ArtifactSourceID - The reference to the artifact source resource Id where the payload is located.
	ArtifactSourceID *string `json:"artifactSourceId,omitempty"`
	// TargetServiceTopologyID - The resource Id of the service topology from which service units are being referenced in step groups to be deployed.
	TargetServiceTopologyID *string `json:"targetServiceTopologyId,omitempty"`
	// StepGroups - The list of step groups that define the orchestration.
	StepGroups *[]Step `json:"stepGroups,omitempty"`
	// Status - READ-ONLY; The current status of the rollout.
	Status *string `json:"status,omitempty"`
	// TotalRetryAttempts - READ-ONLY; The cardinal count of total number of retries performed on the rollout at a given time.
	TotalRetryAttempts *int32 `json:"totalRetryAttempts,omitempty"`
	// OperationInfo - READ-ONLY; Operational information of the rollout.
	OperationInfo *RolloutOperationInfo `json:"operationInfo,omitempty"`
	// Services - READ-ONLY; The detailed information on the services being deployed.
	Services *[]Service `json:"services,omitempty"`
}

// RolloutPropertiesModel defines the properties of a rollout.
type RolloutPropertiesModel struct {
	// Status - READ-ONLY; The current status of the rollout.
	Status *string `json:"status,omitempty"`
	// TotalRetryAttempts - READ-ONLY; The cardinal count of total number of retries performed on the rollout at a given time.
	TotalRetryAttempts *int32 `json:"totalRetryAttempts,omitempty"`
	// OperationInfo - READ-ONLY; Operational information of the rollout.
	OperationInfo *RolloutOperationInfo `json:"operationInfo,omitempty"`
	// Services - READ-ONLY; The detailed information on the services being deployed.
	Services *[]Service `json:"services,omitempty"`
}

// RolloutRequest defines the PUT rollout request body.
type RolloutRequest struct {
	autorest.Response `json:"-"`
	// Identity - Identity for the resource.
	Identity *Identity `json:"identity,omitempty"`
	// RolloutRequestProperties - Defines the properties that make up a rollout request.
	*RolloutRequestProperties `json:"properties,omitempty"`
	// Tags - Resource tags.
	Tags map[string]*string `json:"tags"`
	// Location - The geo-location where the resource lives
	Location *string `json:"location,omitempty"`
	// ID - READ-ONLY; Fully qualified resource Id for the resource. Ex - /subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/{resourceProviderNamespace}/{resourceType}/{resourceName}
	ID *string `json:"id,omitempty"`
	// Name - READ-ONLY; The name of the resource
	Name *string `json:"name,omitempty"`
	// Type - READ-ONLY; The type of the resource. Ex- Microsoft.Compute/virtualMachines or Microsoft.Storage/storageAccounts.
	Type *string `json:"type,omitempty"`
}

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

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

	return nil
}

// RolloutRequestProperties the properties for defining a rollout.
type RolloutRequestProperties struct {
	// BuildVersion - The version of the build being deployed.
	BuildVersion *string `json:"buildVersion,omitempty"`
	// ArtifactSourceID - The reference to the artifact source resource Id where the payload is located.
	ArtifactSourceID *string `json:"artifactSourceId,omitempty"`
	// TargetServiceTopologyID - The resource Id of the service topology from which service units are being referenced in step groups to be deployed.
	TargetServiceTopologyID *string `json:"targetServiceTopologyId,omitempty"`
	// StepGroups - The list of step groups that define the orchestration.
	StepGroups *[]Step `json:"stepGroups,omitempty"`
}

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

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

// RolloutStep defines a specific step on a target service unit.
type RolloutStep struct {
	// Name - Name of the step.
	Name *string `json:"name,omitempty"`
	// Status - READ-ONLY; Current state of the step.
	Status *string `json:"status,omitempty"`
	// StepGroup - The step group the current step is part of.
	StepGroup *string `json:"stepGroup,omitempty"`
	// OperationInfo - READ-ONLY; Detailed information of specific action execution.
	OperationInfo *StepOperationInfo `json:"operationInfo,omitempty"`
	// ResourceOperations - READ-ONLY; Set of resource operations that were performed, if any, on an Azure resource.
	ResourceOperations *[]ResourceOperation `json:"resourceOperations,omitempty"`
	// Messages - READ-ONLY; Supplementary informative messages during rollout.
	Messages *[]Message `json:"messages,omitempty"`
}

// SasAuthentication defines the properties to access the artifacts using an Azure Storage SAS URI.
type SasAuthentication struct {
	// SasProperties - The SAS properties
	*SasProperties `json:"properties,omitempty"`
	// Type - Possible values include: 'TypeAuthentication', 'TypeSas'
	Type Type `json:"type,omitempty"`
}

// MarshalJSON is the custom marshaler for SasAuthentication.
func (sa SasAuthentication) MarshalJSON() ([]byte, error) {
	sa.Type = TypeSas
	objectMap := make(map[string]interface{})
	if sa.SasProperties != nil {
		objectMap["properties"] = sa.SasProperties
	}
	if sa.Type != "" {
		objectMap["type"] = sa.Type
	}
	return json.Marshal(objectMap)
}

// AsSasAuthentication is the BasicAuthentication implementation for SasAuthentication.
func (sa SasAuthentication) AsSasAuthentication() (*SasAuthentication, bool) {
	return &sa, true
}

// AsAuthentication is the BasicAuthentication implementation for SasAuthentication.
func (sa SasAuthentication) AsAuthentication() (*Authentication, bool) {
	return nil, false
}

// AsBasicAuthentication is the BasicAuthentication implementation for SasAuthentication.
func (sa SasAuthentication) AsBasicAuthentication() (BasicAuthentication, bool) {
	return &sa, true
}

// UnmarshalJSON is the custom unmarshaler for SasAuthentication struct.
func (sa *SasAuthentication) 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 sasProperties SasProperties
				err = json.Unmarshal(*v, &sasProperties)
				if err != nil {
					return err
				}
				sa.SasProperties = &sasProperties
			}
		case "type":
			if v != nil {
				var typeVar Type
				err = json.Unmarshal(*v, &typeVar)
				if err != nil {
					return err
				}
				sa.Type = typeVar
			}
		}
	}

	return nil
}

// SasProperties the properties that define SAS authentication.
type SasProperties struct {
	// SasURI - The SAS URI to the Azure Storage blob container. Any offset from the root of the container to where the artifacts are located can be defined in the artifactRoot.
	SasURI *string `json:"sasUri,omitempty"`
}

// Service defines a service.
type Service struct {
	// Name - Name of the service.
	Name *string `json:"name,omitempty"`
	// ServiceUnits - The detailed information about the units that make up the service.
	ServiceUnits *[]ServiceUnit `json:"serviceUnits,omitempty"`
	// TargetLocation - The Azure location to which the resources in the service belong to or should be deployed to.
	TargetLocation *string `json:"targetLocation,omitempty"`
	// TargetSubscriptionID - The subscription to which the resources in the service belong to or should be deployed to.
	TargetSubscriptionID *string `json:"targetSubscriptionId,omitempty"`
}

// ServiceProperties the properties of a service.
type ServiceProperties struct {
	// TargetLocation - The Azure location to which the resources in the service belong to or should be deployed to.
	TargetLocation *string `json:"targetLocation,omitempty"`
	// TargetSubscriptionID - The subscription to which the resources in the service belong to or should be deployed to.
	TargetSubscriptionID *string `json:"targetSubscriptionId,omitempty"`
}

// ServiceResource the resource representation of a service in a service topology.
type ServiceResource struct {
	autorest.Response `json:"-"`
	// ServiceResourceProperties - The properties that define a service in a service topology.
	*ServiceResourceProperties `json:"properties,omitempty"`
	// Tags - Resource tags.
	Tags map[string]*string `json:"tags"`
	// Location - The geo-location where the resource lives
	Location *string `json:"location,omitempty"`
	// ID - READ-ONLY; Fully qualified resource Id for the resource. Ex - /subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/{resourceProviderNamespace}/{resourceType}/{resourceName}
	ID *string `json:"id,omitempty"`
	// Name - READ-ONLY; The name of the resource
	Name *string `json:"name,omitempty"`
	// Type - READ-ONLY; The type of the resource. Ex- Microsoft.Compute/virtualMachines or Microsoft.Storage/storageAccounts.
	Type *string `json:"type,omitempty"`
}

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

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

	return nil
}

// ServiceResourceProperties the properties that define a service in a service topology.
type ServiceResourceProperties struct {
	// TargetLocation - The Azure location to which the resources in the service belong to or should be deployed to.
	TargetLocation *string `json:"targetLocation,omitempty"`
	// TargetSubscriptionID - The subscription to which the resources in the service belong to or should be deployed to.
	TargetSubscriptionID *string `json:"targetSubscriptionId,omitempty"`
}

// ServiceTopologyProperties the properties of a service topology.
type ServiceTopologyProperties struct {
	// ArtifactSourceID - The resource Id of the artifact source that contains the artifacts that can be referenced in the service units.
	ArtifactSourceID *string `json:"artifactSourceId,omitempty"`
}

// ServiceTopologyResource the resource representation of a service topology.
type ServiceTopologyResource struct {
	autorest.Response `json:"-"`
	// ServiceTopologyResourceProperties - The properties that define the service topology.
	*ServiceTopologyResourceProperties `json:"properties,omitempty"`
	// Tags - Resource tags.
	Tags map[string]*string `json:"tags"`
	// Location - The geo-location where the resource lives
	Location *string `json:"location,omitempty"`
	// ID - READ-ONLY; Fully qualified resource Id for the resource. Ex - /subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/{resourceProviderNamespace}/{resourceType}/{resourceName}
	ID *string `json:"id,omitempty"`
	// Name - READ-ONLY; The name of the resource
	Name *string `json:"name,omitempty"`
	// Type - READ-ONLY; The type of the resource. Ex- Microsoft.Compute/virtualMachines or Microsoft.Storage/storageAccounts.
	Type *string `json:"type,omitempty"`
}

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

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

	return nil
}

// ServiceTopologyResourceProperties the properties that define the service topology.
type ServiceTopologyResourceProperties struct {
	// ArtifactSourceID - The resource Id of the artifact source that contains the artifacts that can be referenced in the service units.
	ArtifactSourceID *string `json:"artifactSourceId,omitempty"`
}

// ServiceUnit defines a service unit.
type ServiceUnit struct {
	// Name - Name of the service unit.
	Name *string `json:"name,omitempty"`
	// Steps - Detailed step information, if present.
	Steps *[]RolloutStep `json:"steps,omitempty"`
	// TargetResourceGroup - The Azure Resource Group to which the resources in the service unit belong to or should be deployed to.
	TargetResourceGroup *string `json:"targetResourceGroup,omitempty"`
	// DeploymentMode - Describes the type of ARM deployment to be performed on the resource. Possible values include: 'Incremental', 'Complete'
	DeploymentMode DeploymentMode `json:"deploymentMode,omitempty"`
	// Artifacts - The artifacts for the service unit.
	Artifacts *ServiceUnitArtifacts `json:"artifacts,omitempty"`
}

// ServiceUnitArtifacts defines the artifacts of a service unit.
type ServiceUnitArtifacts struct {
	// TemplateURI - The full URI of the ARM template file with the SAS token.
	TemplateURI *string `json:"templateUri,omitempty"`
	// ParametersURI - The full URI of the ARM parameters file with the SAS token.
	ParametersURI *string `json:"parametersUri,omitempty"`
	// TemplateArtifactSourceRelativePath - The path to the ARM template file relative to the artifact source.
	TemplateArtifactSourceRelativePath *string `json:"templateArtifactSourceRelativePath,omitempty"`
	// ParametersArtifactSourceRelativePath - The path to the ARM parameters file relative to the artifact source.
	ParametersArtifactSourceRelativePath *string `json:"parametersArtifactSourceRelativePath,omitempty"`
}

// ServiceUnitProperties defines the properties of a service unit.
type ServiceUnitProperties struct {
	// TargetResourceGroup - The Azure Resource Group to which the resources in the service unit belong to or should be deployed to.
	TargetResourceGroup *string `json:"targetResourceGroup,omitempty"`
	// DeploymentMode - Describes the type of ARM deployment to be performed on the resource. Possible values include: 'Incremental', 'Complete'
	DeploymentMode DeploymentMode `json:"deploymentMode,omitempty"`
	// Artifacts - The artifacts for the service unit.
	Artifacts *ServiceUnitArtifacts `json:"artifacts,omitempty"`
}

// ServiceUnitResource represents the response of a service unit resource.
type ServiceUnitResource struct {
	autorest.Response `json:"-"`
	// ServiceUnitResourceProperties - The properties that define the service unit.
	*ServiceUnitResourceProperties `json:"properties,omitempty"`
	// Tags - Resource tags.
	Tags map[string]*string `json:"tags"`
	// Location - The geo-location where the resource lives
	Location *string `json:"location,omitempty"`
	// ID - READ-ONLY; Fully qualified resource Id for the resource. Ex - /subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/{resourceProviderNamespace}/{resourceType}/{resourceName}
	ID *string `json:"id,omitempty"`
	// Name - READ-ONLY; The name of the resource
	Name *string `json:"name,omitempty"`
	// Type - READ-ONLY; The type of the resource. Ex- Microsoft.Compute/virtualMachines or Microsoft.Storage/storageAccounts.
	Type *string `json:"type,omitempty"`
}

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

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

	return nil
}

// ServiceUnitResourceProperties the properties that define the service unit.
type ServiceUnitResourceProperties struct {
	// TargetResourceGroup - The Azure Resource Group to which the resources in the service unit belong to or should be deployed to.
	TargetResourceGroup *string `json:"targetResourceGroup,omitempty"`
	// DeploymentMode - Describes the type of ARM deployment to be performed on the resource. Possible values include: 'Incremental', 'Complete'
	DeploymentMode DeploymentMode `json:"deploymentMode,omitempty"`
	// Artifacts - The artifacts for the service unit.
	Artifacts *ServiceUnitArtifacts `json:"artifacts,omitempty"`
}

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

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

// Step the properties that define an Azure Deployment Manager step.
type Step struct {
	// Name - The name of the step group.
	Name *string `json:"name,omitempty"`
	// DependsOnStepGroups - The list of step group names on which this step group depends on.
	DependsOnStepGroups *[]string `json:"dependsOnStepGroups,omitempty"`
	// PreDeploymentSteps - The list of steps to be run before deploying the target.
	PreDeploymentSteps *[]PrePostStep `json:"preDeploymentSteps,omitempty"`
	// DeploymentTargetID - The resource Id of service unit to be deployed. The service unit should be from the service topology referenced in targetServiceTopologyId
	DeploymentTargetID *string `json:"deploymentTargetId,omitempty"`
	// PostDeploymentSteps - The list of steps to be run after deploying the target.
	PostDeploymentSteps *[]PrePostStep `json:"postDeploymentSteps,omitempty"`
}

// StepOperationInfo detailed information of a specific step run.
type StepOperationInfo struct {
	// DeploymentName - READ-ONLY; The name of the ARM deployment initiated as part of the step.
	DeploymentName *string `json:"deploymentName,omitempty"`
	// CorrelationID - READ-ONLY; Unique identifier to track the request for ARM-based resources.
	CorrelationID *string `json:"correlationId,omitempty"`
	// StartTime - READ-ONLY; Start time of the action in UTC.
	StartTime *date.Time `json:"startTime,omitempty"`
	// EndTime - READ-ONLY; End time of the action in UTC.
	EndTime *date.Time `json:"endTime,omitempty"`
	// LastUpdatedTime - READ-ONLY; Last time in UTC this operation was updated.
	LastUpdatedTime *date.Time `json:"lastUpdatedTime,omitempty"`
	// Error - The errors, if any, for the action.
	Error *CloudErrorBody `json:"error,omitempty"`
}

// BasicStepProperties the properties of a step resource.
type BasicStepProperties interface {
	AsWaitStepProperties() (*WaitStepProperties, bool)
	AsStepProperties() (*StepProperties, bool)
}

// StepProperties the properties of a step resource.
type StepProperties struct {
	// StepType - Possible values include: 'StepTypeStepProperties', 'StepTypeWait'
	StepType StepType `json:"stepType,omitempty"`
}

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

	switch m["stepType"] {
	case string(StepTypeWait):
		var wsp WaitStepProperties
		err := json.Unmarshal(body, &wsp)
		return wsp, err
	default:
		var sp StepProperties
		err := json.Unmarshal(body, &sp)
		return sp, err
	}
}
func unmarshalBasicStepPropertiesArray(body []byte) ([]BasicStepProperties, error) {
	var rawMessages []*json.RawMessage
	err := json.Unmarshal(body, &rawMessages)
	if err != nil {
		return nil, err
	}

	spArray := make([]BasicStepProperties, len(rawMessages))

	for index, rawMessage := range rawMessages {
		sp, err := unmarshalBasicStepProperties(*rawMessage)
		if err != nil {
			return nil, err
		}
		spArray[index] = sp
	}
	return spArray, nil
}

// MarshalJSON is the custom marshaler for StepProperties.
func (sp StepProperties) MarshalJSON() ([]byte, error) {
	sp.StepType = StepTypeStepProperties
	objectMap := make(map[string]interface{})
	if sp.StepType != "" {
		objectMap["stepType"] = sp.StepType
	}
	return json.Marshal(objectMap)
}

// AsWaitStepProperties is the BasicStepProperties implementation for StepProperties.
func (sp StepProperties) AsWaitStepProperties() (*WaitStepProperties, bool) {
	return nil, false
}

// AsStepProperties is the BasicStepProperties implementation for StepProperties.
func (sp StepProperties) AsStepProperties() (*StepProperties, bool) {
	return &sp, true
}

// AsBasicStepProperties is the BasicStepProperties implementation for StepProperties.
func (sp StepProperties) AsBasicStepProperties() (BasicStepProperties, bool) {
	return &sp, true
}

// StepResource the resource representation of a rollout step.
type StepResource struct {
	autorest.Response `json:"-"`
	// Properties - The properties that define the step.
	Properties BasicStepProperties `json:"properties,omitempty"`
	// Tags - Resource tags.
	Tags map[string]*string `json:"tags"`
	// Location - The geo-location where the resource lives
	Location *string `json:"location,omitempty"`
	// ID - READ-ONLY; Fully qualified resource Id for the resource. Ex - /subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/{resourceProviderNamespace}/{resourceType}/{resourceName}
	ID *string `json:"id,omitempty"`
	// Name - READ-ONLY; The name of the resource
	Name *string `json:"name,omitempty"`
	// Type - READ-ONLY; The type of the resource. Ex- Microsoft.Compute/virtualMachines or Microsoft.Storage/storageAccounts.
	Type *string `json:"type,omitempty"`
}

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

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

	return nil
}

// TrackedResource the resource model definition for a ARM tracked top level resource
type TrackedResource struct {
	// Tags - Resource tags.
	Tags map[string]*string `json:"tags"`
	// Location - The geo-location where the resource lives
	Location *string `json:"location,omitempty"`
	// ID - READ-ONLY; Fully qualified resource Id for the resource. Ex - /subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/{resourceProviderNamespace}/{resourceType}/{resourceName}
	ID *string `json:"id,omitempty"`
	// Name - READ-ONLY; The name of the resource
	Name *string `json:"name,omitempty"`
	// Type - READ-ONLY; The type of the resource. Ex- Microsoft.Compute/virtualMachines or Microsoft.Storage/storageAccounts.
	Type *string `json:"type,omitempty"`
}

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

// WaitStepAttributes the parameters for the wait step.
type WaitStepAttributes struct {
	// Duration - The duration in ISO 8601 format of how long the wait should be.
	Duration *string `json:"duration,omitempty"`
}

// WaitStepProperties defines the properties of a Wait step.
type WaitStepProperties struct {
	// Attributes - The Wait attributes
	Attributes *WaitStepAttributes `json:"attributes,omitempty"`
	// StepType - Possible values include: 'StepTypeStepProperties', 'StepTypeWait'
	StepType StepType `json:"stepType,omitempty"`
}

// MarshalJSON is the custom marshaler for WaitStepProperties.
func (wsp WaitStepProperties) MarshalJSON() ([]byte, error) {
	wsp.StepType = StepTypeWait
	objectMap := make(map[string]interface{})
	if wsp.Attributes != nil {
		objectMap["attributes"] = wsp.Attributes
	}
	if wsp.StepType != "" {
		objectMap["stepType"] = wsp.StepType
	}
	return json.Marshal(objectMap)
}

// AsWaitStepProperties is the BasicStepProperties implementation for WaitStepProperties.
func (wsp WaitStepProperties) AsWaitStepProperties() (*WaitStepProperties, bool) {
	return &wsp, true
}

// AsStepProperties is the BasicStepProperties implementation for WaitStepProperties.
func (wsp WaitStepProperties) AsStepProperties() (*StepProperties, bool) {
	return nil, false
}

// AsBasicStepProperties is the BasicStepProperties implementation for WaitStepProperties.
func (wsp WaitStepProperties) AsBasicStepProperties() (BasicStepProperties, bool) {
	return &wsp, true
}
