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

// 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 define the source location where the artifacts are located.
type ArtifactSource struct {
	autorest.Response `json:"-"`
	// ArtifactSourceProperties - Defines the properties that make up an 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 - Fully qualified resource Id for the resource. Ex - /subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/{resourceProviderNamespace}/{resourceType}/{resourceName}
	ID *string `json:"id,omitempty"`
	// Name - The name of the resource
	Name *string `json:"name,omitempty"`
	// Type - 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
	}
	if as.ID != nil {
		objectMap["id"] = as.ID
	}
	if as.Name != nil {
		objectMap["name"] = as.Name
	}
	if as.Type != nil {
		objectMap["type"] = as.Type
	}
	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 defines the properties that make up an artifact source.
type ArtifactSourceProperties struct {
	// SourceType - The type of artifact source used.
	SourceType *string `json:"sourceType,omitempty"`
	// ArtifactRoot - The root folder under which all artifacts for all environments are expected to be organized.
	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 root folder under which all artifacts for all environments are expected to be organized.
	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 - Resource Etag.
	Etag *string `json:"etag,omitempty"`
	// ID - Fully qualified resource Id for the resource. Ex - /subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/{resourceProviderNamespace}/{resourceType}/{resourceName}
	ID *string `json:"id,omitempty"`
	// Name - The name of the resource
	Name *string `json:"name,omitempty"`
	// Type - 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 - Error code string.
	Code *string `json:"code,omitempty"`
	// Message - 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 - Time in UTC this message was provided.
	TimeStamp *date.Time `json:"timeStamp,omitempty"`
	// Message - 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 reference to the ARM resource Id of a step.
	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 - Fully qualified resource Id for the resource. Ex - /subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/{resourceProviderNamespace}/{resourceType}/{resourceName}
	ID *string `json:"id,omitempty"`
	// Name - The name of the resource
	Name *string `json:"name,omitempty"`
	// Type - The type of the resource. Ex- Microsoft.Compute/virtualMachines or Microsoft.Storage/storageAccounts.
	Type *string `json:"type,omitempty"`
}

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

// ResourceOperation individial 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 - 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 - State of the resource deployment. For ARM resources, this is the current provisioning state of the resource.
	ProvisioningState *string `json:"provisioningState,omitempty"`
	// StatusMessage - Descriptive information of the resource operation.
	StatusMessage *string `json:"statusMessage,omitempty"`
	// StatusCode - Http status code of the operation.
	StatusCode *string `json:"statusCode,omitempty"`
}

// Rollout defines the rollout resource.
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 - Fully qualified resource Id for the resource. Ex - /subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/{resourceProviderNamespace}/{resourceType}/{resourceName}
	ID *string `json:"id,omitempty"`
	// Name - The name of the resource
	Name *string `json:"name,omitempty"`
	// Type - 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
	}
	if r.ID != nil {
		objectMap["id"] = r.ID
	}
	if r.Name != nil {
		objectMap["name"] = r.Name
	}
	if r.Type != nil {
		objectMap["type"] = r.Type
	}
	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 - The ordinal count of retry attempt. 0 if no retries of the rollout have been performed.
	RetryAttempt *int32 `json:"retryAttempt,omitempty"`
	// SkipSucceededOnRetry - True if skipping all successful steps in the given retry attempt was chosen. False otherwise.
	SkipSucceededOnRetry *bool `json:"skipSucceededOnRetry,omitempty"`
	// StartTime - The start time of the rollout in UTC.
	StartTime *date.Time `json:"startTime,omitempty"`
	// EndTime - 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 - 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 ARM resource Id where the payload is located.
	ArtifactSourceID *string `json:"artifactSourceId,omitempty"`
	// TargetServiceTopologyID - The reference to the resource Id of the service topology from which services are chosen to be deployed.
	TargetServiceTopologyID *string `json:"targetServiceTopologyId,omitempty"`
	// StepGroups - The list of steps that define the orchestration.
	StepGroups *[]Step `json:"stepGroups,omitempty"`
	// Status - The current status of the rollout.
	Status *string `json:"status,omitempty"`
	// TotalRetryAttempts - The cardinal count of total number of retries performed on the rollout at a given time.
	TotalRetryAttempts *int32 `json:"totalRetryAttempts,omitempty"`
	// OperationInfo - Operational information of the rollout.
	OperationInfo *RolloutOperationInfo `json:"operationInfo,omitempty"`
	// Services - Set of detailed step result information on target resource groups.
	Services *[]Service `json:"services,omitempty"`
}

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

// RolloutRequest defines the resource format for creating a rollout.
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 - Fully qualified resource Id for the resource. Ex - /subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/{resourceProviderNamespace}/{resourceType}/{resourceName}
	ID *string `json:"id,omitempty"`
	// Name - The name of the resource
	Name *string `json:"name,omitempty"`
	// Type - 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
	}
	if rr.ID != nil {
		objectMap["id"] = rr.ID
	}
	if rr.Name != nil {
		objectMap["name"] = rr.Name
	}
	if rr.Type != nil {
		objectMap["type"] = rr.Type
	}
	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 ARM resource Id where the payload is located.
	ArtifactSourceID *string `json:"artifactSourceId,omitempty"`
	// TargetServiceTopologyID - The reference to the resource Id of the service topology from which services are chosen to be deployed.
	TargetServiceTopologyID *string `json:"targetServiceTopologyId,omitempty"`
	// StepGroups - The list of steps 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.Done(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 as specified in the rollout specification input artifact.
	Name *string `json:"name,omitempty"`
	// Status - 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 - Detailed information of specific action execution.
	OperationInfo *StepOperationInfo `json:"operationInfo,omitempty"`
	// ResourceOperations - Set of resource operations that were performed on the Azure resource that the action acted upon.
	ResourceOperations *[]ResourceOperation `json:"resourceOperations,omitempty"`
	// Messages - Supplementary informative messages during rollout.
	Messages *[]Message `json:"messages,omitempty"`
}

// SasAuthentication defines the authentication properties to access the artifacts using 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 complete SAS URI to the location of the artifacts.
	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.
	TargetLocation *string `json:"targetLocation,omitempty"`
	// TargetSubscriptionID - The subscription to which the resources in the service belong 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.
	TargetLocation *string `json:"targetLocation,omitempty"`
	// TargetSubscriptionID - The subscription to which the resources in the service belong to.
	TargetSubscriptionID *string `json:"targetSubscriptionId,omitempty"`
}

// ServiceResource the resource representation of a service in a topology.
type ServiceResource struct {
	autorest.Response `json:"-"`
	// ServiceResourceProperties - The properties that define a service in a 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 - Fully qualified resource Id for the resource. Ex - /subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/{resourceProviderNamespace}/{resourceType}/{resourceName}
	ID *string `json:"id,omitempty"`
	// Name - The name of the resource
	Name *string `json:"name,omitempty"`
	// Type - 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
	}
	if sr.ID != nil {
		objectMap["id"] = sr.ID
	}
	if sr.Name != nil {
		objectMap["name"] = sr.Name
	}
	if sr.Type != nil {
		objectMap["type"] = sr.Type
	}
	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 topology.
type ServiceResourceProperties struct {
	// TargetLocation - The Azure location to which the resources in the service belong to.
	TargetLocation *string `json:"targetLocation,omitempty"`
	// TargetSubscriptionID - The subscription to which the resources in the service belong to.
	TargetSubscriptionID *string `json:"targetSubscriptionId,omitempty"`
}

// ServiceTopologyProperties the properties of a service topology.
type ServiceTopologyProperties struct {
	// ArtifactSourceID - 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.
	*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 - Fully qualified resource Id for the resource. Ex - /subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/{resourceProviderNamespace}/{resourceType}/{resourceName}
	ID *string `json:"id,omitempty"`
	// Name - The name of the resource
	Name *string `json:"name,omitempty"`
	// Type - 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
	}
	if str.ID != nil {
		objectMap["id"] = str.ID
	}
	if str.Name != nil {
		objectMap["name"] = str.Name
	}
	if str.Type != nil {
		objectMap["type"] = str.Type
	}
	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.
type ServiceTopologyResourceProperties struct {
	// ArtifactSourceID - 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.
	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.
	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 - Fully qualified resource Id for the resource. Ex - /subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/{resourceProviderNamespace}/{resourceType}/{resourceName}
	ID *string `json:"id,omitempty"`
	// Name - The name of the resource
	Name *string `json:"name,omitempty"`
	// Type - 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
	}
	if sur.ID != nil {
		objectMap["id"] = sur.ID
	}
	if sur.Name != nil {
		objectMap["name"] = sur.Name
	}
	if sur.Type != nil {
		objectMap["type"] = sur.Type
	}
	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.
	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.Done(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.
	Name *string `json:"name,omitempty"`
	// DependsOnStepGroup - The list of step names on which this step depends.
	DependsOnStepGroup *[]string `json:"dependsOnStepGroup,omitempty"`
	// PreDeploymentSteps - The list of step names to be run before deploying the target.
	PreDeploymentSteps *[]PrePostStep `json:"preDeploymentSteps,omitempty"`
	// DeploymentTargetID - The reference to the ARM service unit resource to be deployed.
	DeploymentTargetID *string `json:"deploymentTargetId,omitempty"`
	// PostDeploymentSteps - The list of step names to be run after deploying the target.
	PostDeploymentSteps *[]PrePostStep `json:"postDeploymentSteps,omitempty"`
}

// StepOperationInfo detailed information of specific step execution.
type StepOperationInfo struct {
	// DeploymentName - The name of the Azure Resource Manager deployment initiated as part of the step.
	DeploymentName *string `json:"deploymentName,omitempty"`
	// CorrelationID - Unique identifier to track the request for ARM-based resources.
	CorrelationID *string `json:"correlationId,omitempty"`
	// StartTime - Start time of the action in UTC.
	StartTime *date.Time `json:"startTime,omitempty"`
	// EndTime - End time of the action in UTC.
	EndTime *date.Time `json:"endTime,omitempty"`
	// LastUpdatedTime - 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 deployment step.
type StepResource struct {
	autorest.Response `json:"-"`
	// Properties - The properties for the resource.
	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 - Fully qualified resource Id for the resource. Ex - /subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/{resourceProviderNamespace}/{resourceType}/{resourceName}
	ID *string `json:"id,omitempty"`
	// Name - The name of the resource
	Name *string `json:"name,omitempty"`
	// Type - 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
	}
	if sr.ID != nil {
		objectMap["id"] = sr.ID
	}
	if sr.Name != nil {
		objectMap["name"] = sr.Name
	}
	if sr.Type != nil {
		objectMap["type"] = sr.Type
	}
	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 - Fully qualified resource Id for the resource. Ex - /subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/{resourceProviderNamespace}/{resourceType}/{resourceName}
	ID *string `json:"id,omitempty"`
	// Name - The name of the resource
	Name *string `json:"name,omitempty"`
	// Type - 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
	}
	if tr.ID != nil {
		objectMap["id"] = tr.ID
	}
	if tr.Name != nil {
		objectMap["name"] = tr.Name
	}
	if tr.Type != nil {
		objectMap["type"] = tr.Type
	}
	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
}
