package batchai

// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
//
// 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"
	"github.com/Azure/go-autorest/autorest/to"
	"github.com/Azure/go-autorest/tracing"
	"net/http"
)

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

// AutoScaleSettings the system automatically scales the cluster up and down (within minimumNodeCount and
// maximumNodeCount) based on the pending and running jobs on the cluster.
type AutoScaleSettings struct {
	MinimumNodeCount *int32 `json:"minimumNodeCount,omitempty"`
	MaximumNodeCount *int32 `json:"maximumNodeCount,omitempty"`
	InitialNodeCount *int32 `json:"initialNodeCount,omitempty"`
}

// AzureBlobFileSystemReference provides required information, for the service to be able to mount Azure
// Blob Storage container on the cluster nodes.
type AzureBlobFileSystemReference struct {
	AccountName   *string                      `json:"accountName,omitempty"`
	ContainerName *string                      `json:"containerName,omitempty"`
	Credentials   *AzureStorageCredentialsInfo `json:"credentials,omitempty"`
	// RelativeMountPath - Note that all blob file systems will be mounted under $AZ_BATCHAI_MOUNT_ROOT location.
	RelativeMountPath *string `json:"relativeMountPath,omitempty"`
	MountOptions      *string `json:"mountOptions,omitempty"`
}

// AzureFileShareReference details of the Azure File Share to mount on the cluster.
type AzureFileShareReference struct {
	AccountName  *string                      `json:"accountName,omitempty"`
	AzureFileURL *string                      `json:"azureFileUrl,omitempty"`
	Credentials  *AzureStorageCredentialsInfo `json:"credentials,omitempty"`
	// RelativeMountPath - Note that all file shares will be mounted under $AZ_BATCHAI_MOUNT_ROOT location.
	RelativeMountPath *string `json:"relativeMountPath,omitempty"`
	// FileMode - Default value is 0777. Valid only if OS is linux.
	FileMode *string `json:"fileMode,omitempty"`
	// DirectoryMode - Default value is 0777. Valid only if OS is linux.
	DirectoryMode *string `json:"directoryMode,omitempty"`
}

// AzureStorageCredentialsInfo credentials to access Azure File Share.
type AzureStorageCredentialsInfo struct {
	// AccountKey - One of accountKey or accountKeySecretReference must be specified.
	AccountKey *string `json:"accountKey,omitempty"`
	// AccountKeySecretReference - Users can store their secrets in Azure KeyVault and pass it to the Batch AI Service to integrate with KeyVault. One of accountKey or accountKeySecretReference must be specified.
	AccountKeySecretReference *KeyVaultSecretReference `json:"accountKeySecretReference,omitempty"`
}

// Caffe2Settings specifies the settings for Caffe2 job.
type Caffe2Settings struct {
	PythonScriptFilePath  *string `json:"pythonScriptFilePath,omitempty"`
	PythonInterpreterPath *string `json:"pythonInterpreterPath,omitempty"`
	CommandLineArgs       *string `json:"commandLineArgs,omitempty"`
}

// CaffeSettings specifies the settings for Caffe job.
type CaffeSettings struct {
	// ConfigFilePath - This property cannot be specified if pythonScriptFilePath is specified.
	ConfigFilePath *string `json:"configFilePath,omitempty"`
	// PythonScriptFilePath - This property cannot be specified if configFilePath is specified.
	PythonScriptFilePath *string `json:"pythonScriptFilePath,omitempty"`
	// PythonInterpreterPath - This property can be specified only if the pythonScriptFilePath is specified.
	PythonInterpreterPath *string `json:"pythonInterpreterPath,omitempty"`
	CommandLineArgs       *string `json:"commandLineArgs,omitempty"`
	// ProcessCount - The default value for this property is equal to nodeCount property
	ProcessCount *int32 `json:"processCount,omitempty"`
}

// ChainerSettings specifies the settings for Chainer job.
type ChainerSettings struct {
	PythonScriptFilePath  *string `json:"pythonScriptFilePath,omitempty"`
	PythonInterpreterPath *string `json:"pythonInterpreterPath,omitempty"`
	CommandLineArgs       *string `json:"commandLineArgs,omitempty"`
	// ProcessCount - The default value for this property is equal to nodeCount property
	ProcessCount *int32 `json:"processCount,omitempty"`
}

// CloudError an error response from the Batch AI service.
type CloudError struct {
	// Error - An error response from the Batch AI service.
	Error *CloudErrorBody `json:"error,omitempty"`
}

// CloudErrorBody an error response from the Batch AI service.
type CloudErrorBody struct {
	// Code - An identifier for the error. Codes are invariant and are intended to be consumed programmatically.
	Code *string `json:"code,omitempty"`
	// Message - A message describing the error, intended to be suitable for display in a user interface.
	Message *string `json:"message,omitempty"`
	// Target - The target of the particular error. For example, the name of the property in error.
	Target *string `json:"target,omitempty"`
	// Details - A list of additional details about the error.
	Details *[]CloudErrorBody `json:"details,omitempty"`
}

// Cluster contains information about a Cluster.
type Cluster struct {
	autorest.Response `json:"-"`
	// ClusterProperties - The properties associated with the Cluster.
	*ClusterProperties `json:"properties,omitempty"`
	// ID - READ-ONLY; The ID of the resource
	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
	Type *string `json:"type,omitempty"`
	// Location - READ-ONLY; The location of the resource
	Location *string `json:"location,omitempty"`
	// Tags - READ-ONLY; The tags of the resource
	Tags map[string]*string `json:"tags"`
}

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

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

	return nil
}

// ClusterBaseProperties the properties of a Cluster.
type ClusterBaseProperties struct {
	// VMSize - All virtual machines in a cluster are the same size. For information about available VM sizes for clusters using images from the Virtual Machines Marketplace (see Sizes for Virtual Machines (Linux) or Sizes for Virtual Machines (Windows). Batch AI service supports all Azure VM sizes except STANDARD_A0 and those with premium storage (STANDARD_GS, STANDARD_DS, and STANDARD_DSV2 series).
	VMSize *string `json:"vmSize,omitempty"`
	// VMPriority - Default is dedicated. Possible values include: 'Dedicated', 'Lowpriority'
	VMPriority                  VMPriority                   `json:"vmPriority,omitempty"`
	ScaleSettings               *ScaleSettings               `json:"scaleSettings,omitempty"`
	VirtualMachineConfiguration *VirtualMachineConfiguration `json:"virtualMachineConfiguration,omitempty"`
	NodeSetup                   *NodeSetup                   `json:"nodeSetup,omitempty"`
	UserAccountSettings         *UserAccountSettings         `json:"userAccountSettings,omitempty"`
	Subnet                      *ResourceID                  `json:"subnet,omitempty"`
}

// ClusterCreateParameters parameters supplied to the Create operation.
type ClusterCreateParameters struct {
	// Location - The region in which to create the cluster.
	Location *string `json:"location,omitempty"`
	// Tags - The user specified tags associated with the Cluster.
	Tags map[string]*string `json:"tags"`
	// ClusterBaseProperties - The properties of the Cluster.
	*ClusterBaseProperties `json:"properties,omitempty"`
}

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

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

	return nil
}

// ClusterListResult values returned by the List Clusters operation.
type ClusterListResult struct {
	autorest.Response `json:"-"`
	// Value - The collection of returned Clusters.
	Value *[]Cluster `json:"value,omitempty"`
	// NextLink - The continuation token.
	NextLink *string `json:"nextLink,omitempty"`
}

// ClusterListResultIterator provides access to a complete listing of Cluster values.
type ClusterListResultIterator struct {
	i    int
	page ClusterListResultPage
}

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

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

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

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

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

// Creates a new instance of the ClusterListResultIterator type.
func NewClusterListResultIterator(page ClusterListResultPage) ClusterListResultIterator {
	return ClusterListResultIterator{page: page}
}

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

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

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

// ClusterListResultPage contains a page of Cluster values.
type ClusterListResultPage struct {
	fn  func(context.Context, ClusterListResult) (ClusterListResult, error)
	clr ClusterListResult
}

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

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

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

// Response returns the raw server response from the last page request.
func (page ClusterListResultPage) Response() ClusterListResult {
	return page.clr
}

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

// Creates a new instance of the ClusterListResultPage type.
func NewClusterListResultPage(cur ClusterListResult, getNextPage func(context.Context, ClusterListResult) (ClusterListResult, error)) ClusterListResultPage {
	return ClusterListResultPage{
		fn:  getNextPage,
		clr: cur,
	}
}

// ClusterProperties job specific properties.
type ClusterProperties struct {
	// VMSize - All virtual machines in a cluster are the same size. For information about available VM sizes for clusters using images from the Virtual Machines Marketplace (see Sizes for Virtual Machines (Linux) or Sizes for Virtual Machines (Windows). Batch AI service supports all Azure VM sizes except STANDARD_A0 and those with premium storage (STANDARD_GS, STANDARD_DS, and STANDARD_DSV2 series).
	VMSize *string `json:"vmSize,omitempty"`
	// VMPriority - The default value is dedicated. The node can get preempted while the task is running if lowpriority is chosen. This is best suited if the workload is checkpointing and can be restarted. Possible values include: 'Dedicated', 'Lowpriority'
	VMPriority                  VMPriority                   `json:"vmPriority,omitempty"`
	ScaleSettings               *ScaleSettings               `json:"scaleSettings,omitempty"`
	VirtualMachineConfiguration *VirtualMachineConfiguration `json:"virtualMachineConfiguration,omitempty"`
	NodeSetup                   *NodeSetup                   `json:"nodeSetup,omitempty"`
	UserAccountSettings         *UserAccountSettings         `json:"userAccountSettings,omitempty"`
	Subnet                      *ResourceID                  `json:"subnet,omitempty"`
	// CreationTime - READ-ONLY
	CreationTime *date.Time `json:"creationTime,omitempty"`
	// ProvisioningState - READ-ONLY; Possible value are: creating - Specifies that the cluster is being created. succeeded - Specifies that the cluster has been created successfully. failed - Specifies that the cluster creation has failed. deleting - Specifies that the cluster is being deleted. Possible values include: 'ProvisioningStateCreating', 'ProvisioningStateSucceeded', 'ProvisioningStateFailed', 'ProvisioningStateDeleting'
	ProvisioningState ProvisioningState `json:"provisioningState,omitempty"`
	// ProvisioningStateTransitionTime - READ-ONLY
	ProvisioningStateTransitionTime *date.Time `json:"provisioningStateTransitionTime,omitempty"`
	// AllocationState - READ-ONLY; Possible values are: steady and resizing. steady state indicates that the cluster is not resizing. There are no changes to the number of compute nodes in the cluster in progress. A cluster enters this state when it is created and when no operations are being performed on the cluster to change the number of compute nodes. resizing state indicates that the cluster is resizing; that is, compute nodes are being added to or removed from the cluster. Possible values include: 'Steady', 'Resizing'
	AllocationState AllocationState `json:"allocationState,omitempty"`
	// AllocationStateTransitionTime - READ-ONLY
	AllocationStateTransitionTime *date.Time `json:"allocationStateTransitionTime,omitempty"`
	// Errors - This element contains all the errors encountered by various compute nodes during node setup.
	Errors *[]Error `json:"errors,omitempty"`
	// CurrentNodeCount - READ-ONLY
	CurrentNodeCount *int32 `json:"currentNodeCount,omitempty"`
	// NodeStateCounts - READ-ONLY
	NodeStateCounts *NodeStateCounts `json:"nodeStateCounts,omitempty"`
}

// MarshalJSON is the custom marshaler for ClusterProperties.
func (cp ClusterProperties) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]interface{})
	if cp.VMSize != nil {
		objectMap["vmSize"] = cp.VMSize
	}
	if cp.VMPriority != "" {
		objectMap["vmPriority"] = cp.VMPriority
	}
	if cp.ScaleSettings != nil {
		objectMap["scaleSettings"] = cp.ScaleSettings
	}
	if cp.VirtualMachineConfiguration != nil {
		objectMap["virtualMachineConfiguration"] = cp.VirtualMachineConfiguration
	}
	if cp.NodeSetup != nil {
		objectMap["nodeSetup"] = cp.NodeSetup
	}
	if cp.UserAccountSettings != nil {
		objectMap["userAccountSettings"] = cp.UserAccountSettings
	}
	if cp.Subnet != nil {
		objectMap["subnet"] = cp.Subnet
	}
	if cp.Errors != nil {
		objectMap["errors"] = cp.Errors
	}
	return json.Marshal(objectMap)
}

// ClustersCreateFuture an abstraction for monitoring and retrieving the results of a long-running
// operation.
type ClustersCreateFuture struct {
	azure.FutureAPI
	// Result returns the result of the asynchronous operation.
	// If the operation has not completed it will return an error.
	Result func(ClustersClient) (Cluster, error)
}

// UnmarshalJSON is the custom unmarshaller for CreateFuture.
func (future *ClustersCreateFuture) UnmarshalJSON(body []byte) error {
	var azFuture azure.Future
	if err := json.Unmarshal(body, &azFuture); err != nil {
		return err
	}
	future.FutureAPI = &azFuture
	future.Result = future.result
	return nil
}

// result is the default implementation for ClustersCreateFuture.Result.
func (future *ClustersCreateFuture) result(client ClustersClient) (c Cluster, err error) {
	var done bool
	done, err = future.DoneWithContext(context.Background(), client)
	if err != nil {
		err = autorest.NewErrorWithError(err, "batchai.ClustersCreateFuture", "Result", future.Response(), "Polling failure")
		return
	}
	if !done {
		c.Response.Response = future.Response()
		err = azure.NewAsyncOpIncompleteError("batchai.ClustersCreateFuture")
		return
	}
	sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...))
	if c.Response.Response, err = future.GetResult(sender); err == nil && c.Response.Response.StatusCode != http.StatusNoContent {
		c, err = client.CreateResponder(c.Response.Response)
		if err != nil {
			err = autorest.NewErrorWithError(err, "batchai.ClustersCreateFuture", "Result", c.Response.Response, "Failure responding to request")
		}
	}
	return
}

// ClustersDeleteFuture an abstraction for monitoring and retrieving the results of a long-running
// operation.
type ClustersDeleteFuture struct {
	azure.FutureAPI
	// Result returns the result of the asynchronous operation.
	// If the operation has not completed it will return an error.
	Result func(ClustersClient) (autorest.Response, error)
}

// UnmarshalJSON is the custom unmarshaller for CreateFuture.
func (future *ClustersDeleteFuture) UnmarshalJSON(body []byte) error {
	var azFuture azure.Future
	if err := json.Unmarshal(body, &azFuture); err != nil {
		return err
	}
	future.FutureAPI = &azFuture
	future.Result = future.result
	return nil
}

// result is the default implementation for ClustersDeleteFuture.Result.
func (future *ClustersDeleteFuture) result(client ClustersClient) (ar autorest.Response, err error) {
	var done bool
	done, err = future.DoneWithContext(context.Background(), client)
	if err != nil {
		err = autorest.NewErrorWithError(err, "batchai.ClustersDeleteFuture", "Result", future.Response(), "Polling failure")
		return
	}
	if !done {
		ar.Response = future.Response()
		err = azure.NewAsyncOpIncompleteError("batchai.ClustersDeleteFuture")
		return
	}
	ar.Response = future.Response()
	return
}

// ClusterUpdateParameters parameters supplied to the Update operation.
type ClusterUpdateParameters struct {
	// Tags - The user specified tags associated with the Cluster.
	Tags map[string]*string `json:"tags"`
	// ClusterUpdateProperties - The properties of the Cluster.
	*ClusterUpdateProperties `json:"properties,omitempty"`
}

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

// UnmarshalJSON is the custom unmarshaler for ClusterUpdateParameters struct.
func (cup *ClusterUpdateParameters) 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 "tags":
			if v != nil {
				var tags map[string]*string
				err = json.Unmarshal(*v, &tags)
				if err != nil {
					return err
				}
				cup.Tags = tags
			}
		case "properties":
			if v != nil {
				var clusterUpdateProperties ClusterUpdateProperties
				err = json.Unmarshal(*v, &clusterUpdateProperties)
				if err != nil {
					return err
				}
				cup.ClusterUpdateProperties = &clusterUpdateProperties
			}
		}
	}

	return nil
}

// ClusterUpdateProperties the properties of a Cluster that need to be updated.
type ClusterUpdateProperties struct {
	ScaleSettings *ScaleSettings `json:"scaleSettings,omitempty"`
}

// CNTKsettings specifies the settings for CNTK (aka Microsoft Cognitive Toolkit) job.
type CNTKsettings struct {
	// LanguageType - Valid values are 'BrainScript' or 'Python'.
	LanguageType *string `json:"languageType,omitempty"`
	// ConfigFilePath - This property can be specified only if the languageType is 'BrainScript'.
	ConfigFilePath *string `json:"configFilePath,omitempty"`
	// PythonScriptFilePath - This property can be specified only if the languageType is 'Python'.
	PythonScriptFilePath *string `json:"pythonScriptFilePath,omitempty"`
	// PythonInterpreterPath - This property can be specified only if the languageType is 'Python'.
	PythonInterpreterPath *string `json:"pythonInterpreterPath,omitempty"`
	CommandLineArgs       *string `json:"commandLineArgs,omitempty"`
	// ProcessCount - The default value for this property is equal to nodeCount property
	ProcessCount *int32 `json:"processCount,omitempty"`
}

// ContainerSettings settings for the container to be downloaded.
type ContainerSettings struct {
	ImageSourceRegistry *ImageSourceRegistry `json:"imageSourceRegistry,omitempty"`
}

// CustomToolkitSettings specifies the settings for a custom tool kit job.
type CustomToolkitSettings struct {
	CommandLine *string `json:"commandLine,omitempty"`
}

// DataDisks settings for the data disk which would be created for the File Server.
type DataDisks struct {
	DiskSizeInGB *int32 `json:"diskSizeInGB,omitempty"`
	// CachingType - READ-ONLY; Possible values include: 'None', 'Readonly', 'Readwrite'
	CachingType CachingType `json:"cachingType,omitempty"`
	DiskCount   *int32      `json:"diskCount,omitempty"`
	// StorageAccountType - Possible values include: 'StandardLRS', 'PremiumLRS'
	StorageAccountType StorageAccountType `json:"storageAccountType,omitempty"`
}

// MarshalJSON is the custom marshaler for DataDisks.
func (dd DataDisks) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]interface{})
	if dd.DiskSizeInGB != nil {
		objectMap["diskSizeInGB"] = dd.DiskSizeInGB
	}
	if dd.DiskCount != nil {
		objectMap["diskCount"] = dd.DiskCount
	}
	if dd.StorageAccountType != "" {
		objectMap["storageAccountType"] = dd.StorageAccountType
	}
	return json.Marshal(objectMap)
}

// EnvironmentSetting a collection of environment variables to set.
type EnvironmentSetting struct {
	Name  *string `json:"name,omitempty"`
	Value *string `json:"value,omitempty"`
}

// Error an error response from the Batch AI service.
type Error struct {
	// Code - An identifier for the error. Codes are invariant and are intended to be consumed programmatically.
	Code *string `json:"code,omitempty"`
	// Message - A message describing the error, intended to be suitable for display in a user interface.
	Message *string `json:"message,omitempty"`
	// Details - A list of additional details about the error.
	Details *[]NameValuePair `json:"details,omitempty"`
}

// File properties of the file.
type File struct {
	// Name - file name
	Name *string `json:"name,omitempty"`
	// DownloadURL - This will be returned only if the model has been archived. During job run, this won't be returned and customers can use SSH tunneling to download. Users can use Get Remote Login Information API to get the IP address and port information of all the compute nodes running the job.
	DownloadURL *string `json:"downloadUrl,omitempty"`
	// FileProperties - The properties associated with the file.
	*FileProperties `json:"properties,omitempty"`
}

// MarshalJSON is the custom marshaler for File.
func (f File) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]interface{})
	if f.Name != nil {
		objectMap["name"] = f.Name
	}
	if f.DownloadURL != nil {
		objectMap["downloadUrl"] = f.DownloadURL
	}
	if f.FileProperties != nil {
		objectMap["properties"] = f.FileProperties
	}
	return json.Marshal(objectMap)
}

// UnmarshalJSON is the custom unmarshaler for File struct.
func (f *File) 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 "name":
			if v != nil {
				var name string
				err = json.Unmarshal(*v, &name)
				if err != nil {
					return err
				}
				f.Name = &name
			}
		case "downloadUrl":
			if v != nil {
				var downloadURL string
				err = json.Unmarshal(*v, &downloadURL)
				if err != nil {
					return err
				}
				f.DownloadURL = &downloadURL
			}
		case "properties":
			if v != nil {
				var fileProperties FileProperties
				err = json.Unmarshal(*v, &fileProperties)
				if err != nil {
					return err
				}
				f.FileProperties = &fileProperties
			}
		}
	}

	return nil
}

// FileListResult values returned by the List operation.
type FileListResult struct {
	autorest.Response `json:"-"`
	// Value - READ-ONLY; The collection of returned job files.
	Value *[]File `json:"value,omitempty"`
	// NextLink - The continuation token.
	NextLink *string `json:"nextLink,omitempty"`
}

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

// FileListResultIterator provides access to a complete listing of File values.
type FileListResultIterator struct {
	i    int
	page FileListResultPage
}

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

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

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

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

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

// Creates a new instance of the FileListResultIterator type.
func NewFileListResultIterator(page FileListResultPage) FileListResultIterator {
	return FileListResultIterator{page: page}
}

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

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

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

// FileListResultPage contains a page of File values.
type FileListResultPage struct {
	fn  func(context.Context, FileListResult) (FileListResult, error)
	flr FileListResult
}

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

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

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

// Response returns the raw server response from the last page request.
func (page FileListResultPage) Response() FileListResult {
	return page.flr
}

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

// Creates a new instance of the FileListResultPage type.
func NewFileListResultPage(cur FileListResult, getNextPage func(context.Context, FileListResult) (FileListResult, error)) FileListResultPage {
	return FileListResultPage{
		fn:  getNextPage,
		flr: cur,
	}
}

// FileProperties file specific properties.
type FileProperties struct {
	// LastModified - The time at which the file was last modified.
	LastModified *date.Time `json:"lastModified,omitempty"`
	// ContentLength - The file size.
	ContentLength *int64 `json:"contentLength,omitempty"`
}

// FileServer contains information about the File Server.
type FileServer struct {
	autorest.Response `json:"-"`
	// FileServerProperties - The properties associated with the File Server.
	*FileServerProperties `json:"properties,omitempty"`
	// ID - READ-ONLY; The ID of the resource
	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
	Type *string `json:"type,omitempty"`
	// Location - READ-ONLY; The location of the resource
	Location *string `json:"location,omitempty"`
	// Tags - READ-ONLY; The tags of the resource
	Tags map[string]*string `json:"tags"`
}

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

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

	return nil
}

// FileServerBaseProperties the properties of a file server.
type FileServerBaseProperties struct {
	// VMSize - For information about available VM sizes for fileservers from the Virtual Machines Marketplace, see Sizes for Virtual Machines (Linux).
	VMSize           *string           `json:"vmSize,omitempty"`
	SSHConfiguration *SSHConfiguration `json:"sshConfiguration,omitempty"`
	DataDisks        *DataDisks        `json:"dataDisks,omitempty"`
	Subnet           *ResourceID       `json:"subnet,omitempty"`
}

// FileServerCreateParameters parameters supplied to the Create operation.
type FileServerCreateParameters struct {
	// Location - The region in which to create the File Server.
	Location *string `json:"location,omitempty"`
	// Tags - The user specified tags associated with the File Server.
	Tags map[string]*string `json:"tags"`
	// FileServerBaseProperties - The properties of the File Server.
	*FileServerBaseProperties `json:"properties,omitempty"`
}

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

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

	return nil
}

// FileServerListResult values returned by the List operation.
type FileServerListResult struct {
	autorest.Response `json:"-"`
	// Value - The collection of File Servers.
	Value *[]FileServer `json:"value,omitempty"`
	// NextLink - The continuation token.
	NextLink *string `json:"nextLink,omitempty"`
}

// FileServerListResultIterator provides access to a complete listing of FileServer values.
type FileServerListResultIterator struct {
	i    int
	page FileServerListResultPage
}

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

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

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

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

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

// Creates a new instance of the FileServerListResultIterator type.
func NewFileServerListResultIterator(page FileServerListResultPage) FileServerListResultIterator {
	return FileServerListResultIterator{page: page}
}

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

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

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

// FileServerListResultPage contains a page of FileServer values.
type FileServerListResultPage struct {
	fn   func(context.Context, FileServerListResult) (FileServerListResult, error)
	fslr FileServerListResult
}

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

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

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

// Response returns the raw server response from the last page request.
func (page FileServerListResultPage) Response() FileServerListResult {
	return page.fslr
}

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

// Creates a new instance of the FileServerListResultPage type.
func NewFileServerListResultPage(cur FileServerListResult, getNextPage func(context.Context, FileServerListResult) (FileServerListResult, error)) FileServerListResultPage {
	return FileServerListResultPage{
		fn:   getNextPage,
		fslr: cur,
	}
}

// FileServerProperties file server specific properties.
type FileServerProperties struct {
	// VMSize - For information about available VM sizes for File Server from the Virtual Machines Marketplace, see Sizes for Virtual Machines (Linux).
	VMSize           *string           `json:"vmSize,omitempty"`
	SSHConfiguration *SSHConfiguration `json:"sshConfiguration,omitempty"`
	DataDisks        *DataDisks        `json:"dataDisks,omitempty"`
	Subnet           *ResourceID       `json:"subnet,omitempty"`
	// MountSettings - READ-ONLY
	MountSettings *MountSettings `json:"mountSettings,omitempty"`
	// ProvisioningStateTransitionTime - READ-ONLY
	ProvisioningStateTransitionTime *date.Time `json:"provisioningStateTransitionTime,omitempty"`
	// CreationTime - READ-ONLY
	CreationTime *date.Time `json:"creationTime,omitempty"`
	// ProvisioningState - READ-ONLY; Possible values: creating - The File Server is getting created. updating - The File Server creation has been accepted and it is getting updated. deleting - The user has requested that the File Server be deleted, and it is in the process of being deleted. failed - The File Server creation has failed with the specified errorCode. Details about the error code are specified in the message field. succeeded - The File Server creation has succeeded. Possible values include: 'FileServerProvisioningStateCreating', 'FileServerProvisioningStateUpdating', 'FileServerProvisioningStateDeleting', 'FileServerProvisioningStateSucceeded', 'FileServerProvisioningStateFailed'
	ProvisioningState FileServerProvisioningState `json:"provisioningState,omitempty"`
}

// MarshalJSON is the custom marshaler for FileServerProperties.
func (fsp FileServerProperties) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]interface{})
	if fsp.VMSize != nil {
		objectMap["vmSize"] = fsp.VMSize
	}
	if fsp.SSHConfiguration != nil {
		objectMap["sshConfiguration"] = fsp.SSHConfiguration
	}
	if fsp.DataDisks != nil {
		objectMap["dataDisks"] = fsp.DataDisks
	}
	if fsp.Subnet != nil {
		objectMap["subnet"] = fsp.Subnet
	}
	return json.Marshal(objectMap)
}

// FileServerReference provides required information, for the service to be able to mount Azure FileShare
// on the cluster nodes.
type FileServerReference struct {
	FileServer *ResourceID `json:"fileServer,omitempty"`
	// SourceDirectory - If this property is not specified, the entire File Server will be mounted.
	SourceDirectory *string `json:"sourceDirectory,omitempty"`
	// RelativeMountPath - Note that all file shares will be mounted under $AZ_BATCHAI_MOUNT_ROOT location.
	RelativeMountPath *string `json:"relativeMountPath,omitempty"`
	MountOptions      *string `json:"mountOptions,omitempty"`
}

// FileServersCreateFuture an abstraction for monitoring and retrieving the results of a long-running
// operation.
type FileServersCreateFuture struct {
	azure.FutureAPI
	// Result returns the result of the asynchronous operation.
	// If the operation has not completed it will return an error.
	Result func(FileServersClient) (FileServer, error)
}

// UnmarshalJSON is the custom unmarshaller for CreateFuture.
func (future *FileServersCreateFuture) UnmarshalJSON(body []byte) error {
	var azFuture azure.Future
	if err := json.Unmarshal(body, &azFuture); err != nil {
		return err
	}
	future.FutureAPI = &azFuture
	future.Result = future.result
	return nil
}

// result is the default implementation for FileServersCreateFuture.Result.
func (future *FileServersCreateFuture) result(client FileServersClient) (fs FileServer, err error) {
	var done bool
	done, err = future.DoneWithContext(context.Background(), client)
	if err != nil {
		err = autorest.NewErrorWithError(err, "batchai.FileServersCreateFuture", "Result", future.Response(), "Polling failure")
		return
	}
	if !done {
		fs.Response.Response = future.Response()
		err = azure.NewAsyncOpIncompleteError("batchai.FileServersCreateFuture")
		return
	}
	sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...))
	if fs.Response.Response, err = future.GetResult(sender); err == nil && fs.Response.Response.StatusCode != http.StatusNoContent {
		fs, err = client.CreateResponder(fs.Response.Response)
		if err != nil {
			err = autorest.NewErrorWithError(err, "batchai.FileServersCreateFuture", "Result", fs.Response.Response, "Failure responding to request")
		}
	}
	return
}

// FileServersDeleteFuture an abstraction for monitoring and retrieving the results of a long-running
// operation.
type FileServersDeleteFuture struct {
	azure.FutureAPI
	// Result returns the result of the asynchronous operation.
	// If the operation has not completed it will return an error.
	Result func(FileServersClient) (autorest.Response, error)
}

// UnmarshalJSON is the custom unmarshaller for CreateFuture.
func (future *FileServersDeleteFuture) UnmarshalJSON(body []byte) error {
	var azFuture azure.Future
	if err := json.Unmarshal(body, &azFuture); err != nil {
		return err
	}
	future.FutureAPI = &azFuture
	future.Result = future.result
	return nil
}

// result is the default implementation for FileServersDeleteFuture.Result.
func (future *FileServersDeleteFuture) result(client FileServersClient) (ar autorest.Response, err error) {
	var done bool
	done, err = future.DoneWithContext(context.Background(), client)
	if err != nil {
		err = autorest.NewErrorWithError(err, "batchai.FileServersDeleteFuture", "Result", future.Response(), "Polling failure")
		return
	}
	if !done {
		ar.Response = future.Response()
		err = azure.NewAsyncOpIncompleteError("batchai.FileServersDeleteFuture")
		return
	}
	ar.Response = future.Response()
	return
}

// ImageReference the image reference.
type ImageReference struct {
	Publisher *string `json:"publisher,omitempty"`
	Offer     *string `json:"offer,omitempty"`
	Sku       *string `json:"sku,omitempty"`
	Version   *string `json:"version,omitempty"`
}

// ImageSourceRegistry details of the container image such as name, URL and credentials.
type ImageSourceRegistry struct {
	ServerURL   *string                     `json:"serverUrl,omitempty"`
	Image       *string                     `json:"image,omitempty"`
	Credentials *PrivateRegistryCredentials `json:"credentials,omitempty"`
}

// InputDirectory input directory for the job.
type InputDirectory struct {
	// ID - It will be available for the job as an environment variable under AZ_BATCHAI_INPUT_id. The service will also provide the following  environment variable: AZ_BATCHAI_PREV_OUTPUT_Name. The value of the variable will be populated if the job is being retried after a previous failure, otherwise it will be set to nothing.
	ID   *string `json:"id,omitempty"`
	Path *string `json:"path,omitempty"`
}

// Job contains information about the job.
type Job struct {
	autorest.Response `json:"-"`
	// JobProperties - The properties associated with the job.
	*JobProperties `json:"properties,omitempty"`
	// ID - READ-ONLY; The ID of the resource
	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
	Type *string `json:"type,omitempty"`
	// Location - READ-ONLY; The location of the resource
	Location *string `json:"location,omitempty"`
	// Tags - READ-ONLY; The tags of the resource
	Tags map[string]*string `json:"tags"`
}

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

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

	return nil
}

// JobBaseProperties the properties of a Batch AI job.
type JobBaseProperties struct {
	// ExperimentName - Describe the experiment information of the job
	ExperimentName *string `json:"experimentName,omitempty"`
	// Priority - Priority associated with the job. Priority values can range from -1000 to 1000, with -1000 being the lowest priority and 1000 being the highest priority. The default value is 0.
	Priority *int32      `json:"priority,omitempty"`
	Cluster  *ResourceID `json:"cluster,omitempty"`
	// NodeCount - The job will be gang scheduled on that many compute nodes
	NodeCount *int32 `json:"nodeCount,omitempty"`
	// ContainerSettings - If the container was downloaded as part of cluster setup then the same container image will be used. If not provided, the job will run on the VM.
	ContainerSettings     *ContainerSettings     `json:"containerSettings,omitempty"`
	CntkSettings          *CNTKsettings          `json:"cntkSettings,omitempty"`
	TensorFlowSettings    *TensorFlowSettings    `json:"tensorFlowSettings,omitempty"`
	CaffeSettings         *CaffeSettings         `json:"caffeSettings,omitempty"`
	Caffe2Settings        *Caffe2Settings        `json:"caffe2Settings,omitempty"`
	ChainerSettings       *ChainerSettings       `json:"chainerSettings,omitempty"`
	CustomToolkitSettings *CustomToolkitSettings `json:"customToolkitSettings,omitempty"`
	// JobPreparation - The specified actions will run on all the nodes that are part of the job
	JobPreparation *JobPreparation `json:"jobPreparation,omitempty"`
	// StdOutErrPathPrefix - The path where the Batch AI service will upload stdout and stderror of the job.
	StdOutErrPathPrefix *string            `json:"stdOutErrPathPrefix,omitempty"`
	InputDirectories    *[]InputDirectory  `json:"inputDirectories,omitempty"`
	OutputDirectories   *[]OutputDirectory `json:"outputDirectories,omitempty"`
	// EnvironmentVariables - Batch AI service sets the following environment variables for all jobs: AZ_BATCHAI_INPUT_id, AZ_BATCHAI_OUTPUT_id, AZ_BATCHAI_NUM_GPUS_PER_NODE. For distributed TensorFlow jobs, following additional environment variables are set by the Batch AI Service: AZ_BATCHAI_PS_HOSTS, AZ_BATCHAI_WORKER_HOSTS
	EnvironmentVariables *[]EnvironmentSetting `json:"environmentVariables,omitempty"`
	// Constraints - Constraints associated with the Job.
	Constraints *JobBasePropertiesConstraints `json:"constraints,omitempty"`
}

// JobBasePropertiesConstraints constraints associated with the Job.
type JobBasePropertiesConstraints struct {
	// MaxWallClockTime - Default Value = 1 week.
	MaxWallClockTime *string `json:"maxWallClockTime,omitempty"`
}

// JobCreateParameters parameters supplied to the Create operation.
type JobCreateParameters struct {
	// Location - The region in which to create the job.
	Location *string `json:"location,omitempty"`
	// Tags - The user specified tags associated with the job.
	Tags map[string]*string `json:"tags"`
	// JobBaseProperties - The properties of the Job.
	*JobBaseProperties `json:"properties,omitempty"`
}

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

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

	return nil
}

// JobListResult values returned by the List operation.
type JobListResult struct {
	autorest.Response `json:"-"`
	// Value - The collection of jobs.
	Value *[]Job `json:"value,omitempty"`
	// NextLink - The continuation token.
	NextLink *string `json:"nextLink,omitempty"`
}

// JobListResultIterator provides access to a complete listing of Job values.
type JobListResultIterator struct {
	i    int
	page JobListResultPage
}

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

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

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

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

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

// Creates a new instance of the JobListResultIterator type.
func NewJobListResultIterator(page JobListResultPage) JobListResultIterator {
	return JobListResultIterator{page: page}
}

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

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

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

// JobListResultPage contains a page of Job values.
type JobListResultPage struct {
	fn  func(context.Context, JobListResult) (JobListResult, error)
	jlr JobListResult
}

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

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

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

// Response returns the raw server response from the last page request.
func (page JobListResultPage) Response() JobListResult {
	return page.jlr
}

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

// Creates a new instance of the JobListResultPage type.
func NewJobListResultPage(cur JobListResult, getNextPage func(context.Context, JobListResult) (JobListResult, error)) JobListResultPage {
	return JobListResultPage{
		fn:  getNextPage,
		jlr: cur,
	}
}

// JobPreparation specifies the settings for job preparation.
type JobPreparation struct {
	// CommandLine - If containerSettings is specified on the job, this commandLine will be executed in the same container as job. Otherwise it will be executed on the node.
	CommandLine *string `json:"commandLine,omitempty"`
}

// JobProperties job specific properties.
type JobProperties struct {
	// ExperimentName - Describe the experiment information of the job
	ExperimentName *string `json:"experimentName,omitempty"`
	// Priority - Priority associated with the job. Priority values can range from -1000 to 1000, with -1000 being the lowest priority and 1000 being the highest priority. The default value is 0.
	Priority *int32      `json:"priority,omitempty"`
	Cluster  *ResourceID `json:"cluster,omitempty"`
	// NodeCount - The job will be gang scheduled on that many compute nodes
	NodeCount *int32 `json:"nodeCount,omitempty"`
	// ContainerSettings - If the container was downloaded as part of cluster setup then the same container image will be used. If not provided, the job will run on the VM.
	ContainerSettings *ContainerSettings `json:"containerSettings,omitempty"`
	// ToolType - Possible values are: cntk, tensorflow, caffe, caffe2, chainer, custom. Possible values include: 'ToolTypeCntk', 'ToolTypeTensorflow', 'ToolTypeCaffe', 'ToolTypeCaffe2', 'ToolTypeChainer', 'ToolTypeCustom'
	ToolType              ToolType               `json:"toolType,omitempty"`
	CntkSettings          *CNTKsettings          `json:"cntkSettings,omitempty"`
	TensorFlowSettings    *TensorFlowSettings    `json:"tensorFlowSettings,omitempty"`
	CaffeSettings         *CaffeSettings         `json:"caffeSettings,omitempty"`
	ChainerSettings       *ChainerSettings       `json:"chainerSettings,omitempty"`
	CustomToolkitSettings *CustomToolkitSettings `json:"customToolkitSettings,omitempty"`
	// JobPreparation - The specified actions will run on all the nodes that are part of the job
	JobPreparation *JobPreparation `json:"jobPreparation,omitempty"`
	// StdOutErrPathPrefix - The path where the Batch AI service will upload stdout and stderror of the job.
	StdOutErrPathPrefix *string            `json:"stdOutErrPathPrefix,omitempty"`
	InputDirectories    *[]InputDirectory  `json:"inputDirectories,omitempty"`
	OutputDirectories   *[]OutputDirectory `json:"outputDirectories,omitempty"`
	// EnvironmentVariables - Batch AI services sets the following environment variables for all jobs: AZ_BATCHAI_INPUT_id, AZ_BATCHAI_OUTPUT_id, AZ_BATCHAI_NUM_GPUS_PER_NODE, For distributed TensorFlow jobs, following additional environment variables are set by the Batch AI Service: AZ_BATCHAI_PS_HOSTS, AZ_BATCHAI_WORKER_HOSTS.
	EnvironmentVariables *[]EnvironmentSetting `json:"environmentVariables,omitempty"`
	// Constraints - Constraints associated with the Job.
	Constraints *JobPropertiesConstraints `json:"constraints,omitempty"`
	// CreationTime - READ-ONLY; The creation time of the job.
	CreationTime *date.Time `json:"creationTime,omitempty"`
	// ProvisioningState - READ-ONLY; The provisioned state of the Batch AI job. Possible values include: 'ProvisioningStateCreating', 'ProvisioningStateSucceeded', 'ProvisioningStateFailed', 'ProvisioningStateDeleting'
	ProvisioningState ProvisioningState `json:"provisioningState,omitempty"`
	// ProvisioningStateTransitionTime - READ-ONLY; The time at which the job entered its current provisioning state.
	ProvisioningStateTransitionTime *date.Time `json:"provisioningStateTransitionTime,omitempty"`
	// ExecutionState - The current state of the job. Possible values are: queued - The job is queued and able to run. A job enters this state when it is created, or when it is awaiting a retry after a failed run. running - The job is running on a compute cluster. This includes job-level preparation such as downloading resource files or set up container specified on the job - it does not necessarily mean that the job command line has started executing. terminating - The job is terminated by the user, the terminate operation is in progress. succeeded - The job has completed running successfully and exited with exit code 0. failed - The job has finished unsuccessfully (failed with a non-zero exit code) and has exhausted its retry limit. A job is also marked as failed if an error occurred launching the job. Possible values include: 'Queued', 'Running', 'Terminating', 'Succeeded', 'Failed'
	ExecutionState ExecutionState `json:"executionState,omitempty"`
	// ExecutionStateTransitionTime - READ-ONLY; The time at which the job entered its current execution state.
	ExecutionStateTransitionTime *date.Time `json:"executionStateTransitionTime,omitempty"`
	// ExecutionInfo - Contains information about the execution of a job in the Azure Batch service.
	ExecutionInfo *JobPropertiesExecutionInfo `json:"executionInfo,omitempty"`
}

// MarshalJSON is the custom marshaler for JobProperties.
func (jp JobProperties) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]interface{})
	if jp.ExperimentName != nil {
		objectMap["experimentName"] = jp.ExperimentName
	}
	if jp.Priority != nil {
		objectMap["priority"] = jp.Priority
	}
	if jp.Cluster != nil {
		objectMap["cluster"] = jp.Cluster
	}
	if jp.NodeCount != nil {
		objectMap["nodeCount"] = jp.NodeCount
	}
	if jp.ContainerSettings != nil {
		objectMap["containerSettings"] = jp.ContainerSettings
	}
	if jp.ToolType != "" {
		objectMap["toolType"] = jp.ToolType
	}
	if jp.CntkSettings != nil {
		objectMap["cntkSettings"] = jp.CntkSettings
	}
	if jp.TensorFlowSettings != nil {
		objectMap["tensorFlowSettings"] = jp.TensorFlowSettings
	}
	if jp.CaffeSettings != nil {
		objectMap["caffeSettings"] = jp.CaffeSettings
	}
	if jp.ChainerSettings != nil {
		objectMap["chainerSettings"] = jp.ChainerSettings
	}
	if jp.CustomToolkitSettings != nil {
		objectMap["customToolkitSettings"] = jp.CustomToolkitSettings
	}
	if jp.JobPreparation != nil {
		objectMap["jobPreparation"] = jp.JobPreparation
	}
	if jp.StdOutErrPathPrefix != nil {
		objectMap["stdOutErrPathPrefix"] = jp.StdOutErrPathPrefix
	}
	if jp.InputDirectories != nil {
		objectMap["inputDirectories"] = jp.InputDirectories
	}
	if jp.OutputDirectories != nil {
		objectMap["outputDirectories"] = jp.OutputDirectories
	}
	if jp.EnvironmentVariables != nil {
		objectMap["environmentVariables"] = jp.EnvironmentVariables
	}
	if jp.Constraints != nil {
		objectMap["constraints"] = jp.Constraints
	}
	if jp.ExecutionState != "" {
		objectMap["executionState"] = jp.ExecutionState
	}
	if jp.ExecutionInfo != nil {
		objectMap["executionInfo"] = jp.ExecutionInfo
	}
	return json.Marshal(objectMap)
}

// JobPropertiesConstraints constraints associated with the Job.
type JobPropertiesConstraints struct {
	// MaxWallClockTime - Default Value = 1 week.
	MaxWallClockTime *string `json:"maxWallClockTime,omitempty"`
}

// JobPropertiesExecutionInfo contains information about the execution of a job in the Azure Batch service.
type JobPropertiesExecutionInfo struct {
	// StartTime - 'Running' corresponds to the running state. If the job has been restarted or retried, this is the most recent time at which the job started running. This property is present only for job that are in the running or completed state.
	StartTime *date.Time `json:"startTime,omitempty"`
	// EndTime - This property is only returned if the job is in completed state.
	EndTime *date.Time `json:"endTime,omitempty"`
	// ExitCode - This property is only returned if the job is in completed state.
	ExitCode *int32   `json:"exitCode,omitempty"`
	Errors   *[]Error `json:"errors,omitempty"`
}

// JobsCreateFuture an abstraction for monitoring and retrieving the results of a long-running operation.
type JobsCreateFuture struct {
	azure.FutureAPI
	// Result returns the result of the asynchronous operation.
	// If the operation has not completed it will return an error.
	Result func(JobsClient) (Job, error)
}

// UnmarshalJSON is the custom unmarshaller for CreateFuture.
func (future *JobsCreateFuture) UnmarshalJSON(body []byte) error {
	var azFuture azure.Future
	if err := json.Unmarshal(body, &azFuture); err != nil {
		return err
	}
	future.FutureAPI = &azFuture
	future.Result = future.result
	return nil
}

// result is the default implementation for JobsCreateFuture.Result.
func (future *JobsCreateFuture) result(client JobsClient) (j Job, err error) {
	var done bool
	done, err = future.DoneWithContext(context.Background(), client)
	if err != nil {
		err = autorest.NewErrorWithError(err, "batchai.JobsCreateFuture", "Result", future.Response(), "Polling failure")
		return
	}
	if !done {
		j.Response.Response = future.Response()
		err = azure.NewAsyncOpIncompleteError("batchai.JobsCreateFuture")
		return
	}
	sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...))
	if j.Response.Response, err = future.GetResult(sender); err == nil && j.Response.Response.StatusCode != http.StatusNoContent {
		j, err = client.CreateResponder(j.Response.Response)
		if err != nil {
			err = autorest.NewErrorWithError(err, "batchai.JobsCreateFuture", "Result", j.Response.Response, "Failure responding to request")
		}
	}
	return
}

// JobsDeleteFuture an abstraction for monitoring and retrieving the results of a long-running operation.
type JobsDeleteFuture struct {
	azure.FutureAPI
	// Result returns the result of the asynchronous operation.
	// If the operation has not completed it will return an error.
	Result func(JobsClient) (autorest.Response, error)
}

// UnmarshalJSON is the custom unmarshaller for CreateFuture.
func (future *JobsDeleteFuture) UnmarshalJSON(body []byte) error {
	var azFuture azure.Future
	if err := json.Unmarshal(body, &azFuture); err != nil {
		return err
	}
	future.FutureAPI = &azFuture
	future.Result = future.result
	return nil
}

// result is the default implementation for JobsDeleteFuture.Result.
func (future *JobsDeleteFuture) result(client JobsClient) (ar autorest.Response, err error) {
	var done bool
	done, err = future.DoneWithContext(context.Background(), client)
	if err != nil {
		err = autorest.NewErrorWithError(err, "batchai.JobsDeleteFuture", "Result", future.Response(), "Polling failure")
		return
	}
	if !done {
		ar.Response = future.Response()
		err = azure.NewAsyncOpIncompleteError("batchai.JobsDeleteFuture")
		return
	}
	ar.Response = future.Response()
	return
}

// JobsTerminateFuture an abstraction for monitoring and retrieving the results of a long-running
// operation.
type JobsTerminateFuture struct {
	azure.FutureAPI
	// Result returns the result of the asynchronous operation.
	// If the operation has not completed it will return an error.
	Result func(JobsClient) (autorest.Response, error)
}

// UnmarshalJSON is the custom unmarshaller for CreateFuture.
func (future *JobsTerminateFuture) UnmarshalJSON(body []byte) error {
	var azFuture azure.Future
	if err := json.Unmarshal(body, &azFuture); err != nil {
		return err
	}
	future.FutureAPI = &azFuture
	future.Result = future.result
	return nil
}

// result is the default implementation for JobsTerminateFuture.Result.
func (future *JobsTerminateFuture) result(client JobsClient) (ar autorest.Response, err error) {
	var done bool
	done, err = future.DoneWithContext(context.Background(), client)
	if err != nil {
		err = autorest.NewErrorWithError(err, "batchai.JobsTerminateFuture", "Result", future.Response(), "Polling failure")
		return
	}
	if !done {
		ar.Response = future.Response()
		err = azure.NewAsyncOpIncompleteError("batchai.JobsTerminateFuture")
		return
	}
	ar.Response = future.Response()
	return
}

// KeyVaultKeyReference describes a reference to Key Vault Key.
type KeyVaultKeyReference struct {
	SourceVault *ResourceID `json:"sourceVault,omitempty"`
	KeyURL      *string     `json:"keyUrl,omitempty"`
}

// KeyVaultSecretReference describes a reference to Key Vault Secret.
type KeyVaultSecretReference struct {
	SourceVault *ResourceID `json:"sourceVault,omitempty"`
	SecretURL   *string     `json:"secretUrl,omitempty"`
}

// LocalDataVolume represents mapping of host directories to directories in the container.
type LocalDataVolume struct {
	HostPath  *string `json:"hostPath,omitempty"`
	LocalPath *string `json:"localPath,omitempty"`
}

// ManualScaleSettings manual scale settings for the cluster.
type ManualScaleSettings struct {
	// TargetNodeCount - Default is 0. If autoScaleSettings are not specified, then the Cluster starts with this target.
	TargetNodeCount *int32 `json:"targetNodeCount,omitempty"`
	// NodeDeallocationOption - The default value is requeue. Possible values include: 'Requeue', 'Terminate', 'Waitforjobcompletion', 'Unknown'
	NodeDeallocationOption DeallocationOption `json:"nodeDeallocationOption,omitempty"`
}

// MountSettings details of the File Server.
type MountSettings struct {
	MountPoint           *string `json:"mountPoint,omitempty"`
	FileServerPublicIP   *string `json:"fileServerPublicIP,omitempty"`
	FileServerInternalIP *string `json:"fileServerInternalIP,omitempty"`
	// FileServerType - Possible values include: 'Nfs', 'Glusterfs'
	FileServerType FileServerType `json:"fileServerType,omitempty"`
}

// MountVolumes details of volumes to mount on the cluster.
type MountVolumes struct {
	// AzureFileShares - References to Azure File Shares that are to be mounted to the cluster nodes.
	AzureFileShares *[]AzureFileShareReference `json:"azureFileShares,omitempty"`
	// AzureBlobFileSystems - References to Azure Blob FUSE that are to be mounted to the cluster nodes.
	AzureBlobFileSystems *[]AzureBlobFileSystemReference `json:"azureBlobFileSystems,omitempty"`
	FileServers          *[]FileServerReference          `json:"fileServers,omitempty"`
	UnmanagedFileSystems *[]UnmanagedFileSystemReference `json:"unmanagedFileSystems,omitempty"`
}

// NameValuePair represents a name-value pair.
type NameValuePair struct {
	Name  *string `json:"name,omitempty"`
	Value *string `json:"value,omitempty"`
}

// NodeSetup use this to prepare the VM. NOTE: The volumes specified in mountVolumes are mounted first and
// then the setupTask is run. Therefore the setup task can use local mountPaths in its execution.
type NodeSetup struct {
	SetupTask    *SetupTask    `json:"setupTask,omitempty"`
	MountVolumes *MountVolumes `json:"mountVolumes,omitempty"`
}

// NodeStateCounts counts of various compute node states on the cluster.
type NodeStateCounts struct {
	IdleNodeCount      *int32 `json:"idleNodeCount,omitempty"`
	RunningNodeCount   *int32 `json:"runningNodeCount,omitempty"`
	PreparingNodeCount *int32 `json:"preparingNodeCount,omitempty"`
	UnusableNodeCount  *int32 `json:"unusableNodeCount,omitempty"`
	LeavingNodeCount   *int32 `json:"leavingNodeCount,omitempty"`
}

// Operation details of a REST API operation
type Operation struct {
	// Name - This is of the format {provider}/{resource}/{operation}
	Name *string `json:"name,omitempty"`
	// Display - The object that describes the operation.
	Display    *OperationDisplay `json:"display,omitempty"`
	Origin     *string           `json:"origin,omitempty"`
	Properties interface{}       `json:"properties,omitempty"`
}

// OperationDisplay the object that describes the operation.
type OperationDisplay struct {
	Provider *string `json:"provider,omitempty"`
	// Operation - For example: read, write, delete, or listKeys/action
	Operation   *string `json:"operation,omitempty"`
	Resource    *string `json:"resource,omitempty"`
	Description *string `json:"description,omitempty"`
}

// OperationListResult contains the list of all operations supported by BatchAI resource provider
type OperationListResult struct {
	autorest.Response `json:"-"`
	Value             *[]Operation `json:"value,omitempty"`
	NextLink          *string      `json:"nextLink,omitempty"`
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

// OutputDirectory output directory for the job.
type OutputDirectory struct {
	// ID - It will be available for the job as an environment variable under AZ_BATCHAI_OUTPUT_id.
	ID *string `json:"id,omitempty"`
	// PathPrefix - NOTE: This is an absolute path to prefix. E.g. $AZ_BATCHAI_MOUNT_ROOT/MyNFS/MyLogs.
	PathPrefix *string `json:"pathPrefix,omitempty"`
	// PathSuffix - The suffix path where the output directory will be created.
	PathSuffix *string `json:"pathSuffix,omitempty"`
	// Type - Default value is Custom. The possible values are Model, Logs, Summary, and Custom. Users can use multiple enums for a single directory. Eg. outPutType='Model,Logs, Summary'. Possible values include: 'Model', 'Logs', 'Summary', 'Custom'
	Type OutputType `json:"type,omitempty"`
	// CreateNew - Default is true. If false, then the directory is not created and can be any directory path that the user specifies.
	CreateNew *bool `json:"createNew,omitempty"`
}

// PrivateRegistryCredentials credentials to access a container image in a private repository.
type PrivateRegistryCredentials struct {
	Username *string `json:"username,omitempty"`
	// Password - One of password or passwordSecretReference must be specified.
	Password *string `json:"password,omitempty"`
	// PasswordSecretReference - Users can store their secrets in Azure KeyVault and pass it to the Batch AI Service to integrate with KeyVault. One of password or passwordSecretReference must be specified.
	PasswordSecretReference *KeyVaultSecretReference `json:"passwordSecretReference,omitempty"`
}

// RemoteLoginInformation contains remote login details to SSH/RDP to a compute node in cluster.
type RemoteLoginInformation struct {
	// NodeID - Id of the compute node
	NodeID *string `json:"nodeId,omitempty"`
	// IPAddress - ip address
	IPAddress *string  `json:"ipAddress,omitempty"`
	Port      *float64 `json:"port,omitempty"`
}

// RemoteLoginInformationListResult values returned by the List operation.
type RemoteLoginInformationListResult struct {
	autorest.Response `json:"-"`
	// Value - The collection of returned remote login details.
	Value *[]RemoteLoginInformation `json:"value,omitempty"`
	// NextLink - The continuation token.
	NextLink *string `json:"nextLink,omitempty"`
}

// RemoteLoginInformationListResultIterator provides access to a complete listing of RemoteLoginInformation
// values.
type RemoteLoginInformationListResultIterator struct {
	i    int
	page RemoteLoginInformationListResultPage
}

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

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

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

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

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

// Creates a new instance of the RemoteLoginInformationListResultIterator type.
func NewRemoteLoginInformationListResultIterator(page RemoteLoginInformationListResultPage) RemoteLoginInformationListResultIterator {
	return RemoteLoginInformationListResultIterator{page: page}
}

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

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

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

// RemoteLoginInformationListResultPage contains a page of RemoteLoginInformation values.
type RemoteLoginInformationListResultPage struct {
	fn    func(context.Context, RemoteLoginInformationListResult) (RemoteLoginInformationListResult, error)
	rlilr RemoteLoginInformationListResult
}

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

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

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

// Response returns the raw server response from the last page request.
func (page RemoteLoginInformationListResultPage) Response() RemoteLoginInformationListResult {
	return page.rlilr
}

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

// Creates a new instance of the RemoteLoginInformationListResultPage type.
func NewRemoteLoginInformationListResultPage(cur RemoteLoginInformationListResult, getNextPage func(context.Context, RemoteLoginInformationListResult) (RemoteLoginInformationListResult, error)) RemoteLoginInformationListResultPage {
	return RemoteLoginInformationListResultPage{
		fn:    getNextPage,
		rlilr: cur,
	}
}

// Resource a definition of an Azure resource.
type Resource struct {
	// ID - READ-ONLY; The ID of the resource
	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
	Type *string `json:"type,omitempty"`
	// Location - READ-ONLY; The location of the resource
	Location *string `json:"location,omitempty"`
	// Tags - READ-ONLY; The tags of the resource
	Tags map[string]*string `json:"tags"`
}

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

// ResourceID represents a resource ID. For example, for a subnet, it is the resource URL for the subnet.
type ResourceID struct {
	// ID - The ID of the resource
	ID *string `json:"id,omitempty"`
}

// ScaleSettings at least one of manual or autoScale settings must be specified. Only one of manual or
// autoScale settings can be specified. If autoScale settings are specified, the system automatically
// scales the cluster up and down (within the supplied limits) based on the pending jobs on the cluster.
type ScaleSettings struct {
	Manual    *ManualScaleSettings `json:"manual,omitempty"`
	AutoScale *AutoScaleSettings   `json:"autoScale,omitempty"`
}

// SetupTask specifies a setup task which can be used to customize the compute nodes of the cluster.
type SetupTask struct {
	CommandLine          *string               `json:"commandLine,omitempty"`
	EnvironmentVariables *[]EnvironmentSetting `json:"environmentVariables,omitempty"`
	RunElevated          *bool                 `json:"runElevated,omitempty"`
	// StdOutErrPathPrefix - The path where the Batch AI service will upload the stdout and stderror of setup task.
	StdOutErrPathPrefix *string `json:"stdOutErrPathPrefix,omitempty"`
}

// SSHConfiguration SSH configuration settings for the VM
type SSHConfiguration struct {
	// PublicIPsToAllow - Default value is '*' can be used to match all source IPs. Maximum number of publicIPs that can be specified are 400.
	PublicIPsToAllow    *[]string            `json:"publicIPsToAllow,omitempty"`
	UserAccountSettings *UserAccountSettings `json:"userAccountSettings,omitempty"`
}

// TensorFlowSettings specifies the settings for TensorFlow job.
type TensorFlowSettings struct {
	PythonScriptFilePath  *string `json:"pythonScriptFilePath,omitempty"`
	PythonInterpreterPath *string `json:"pythonInterpreterPath,omitempty"`
	MasterCommandLineArgs *string `json:"masterCommandLineArgs,omitempty"`
	// WorkerCommandLineArgs - This property is optional for single machine training.
	WorkerCommandLineArgs *string `json:"workerCommandLineArgs,omitempty"`
	// ParameterServerCommandLineArgs - This property is optional for single machine training.
	ParameterServerCommandLineArgs *string `json:"parameterServerCommandLineArgs,omitempty"`
	// WorkerCount - If specified, the value must be less than or equal to (nodeCount * numberOfGPUs per VM). If not specified, the default value is equal to nodeCount. This property can be specified only for distributed TensorFlow training
	WorkerCount *int32 `json:"workerCount,omitempty"`
	// ParameterServerCount - If specified, the value must be less than or equal to nodeCount. If not specified, the default value is equal to 1 for distributed TensorFlow training (This property is not applicable for single machine training). This property can be specified only for distributed TensorFlow training.
	ParameterServerCount *int32 `json:"parameterServerCount,omitempty"`
}

// UnmanagedFileSystemReference details of the file system to mount on the compute cluster nodes.
type UnmanagedFileSystemReference struct {
	MountCommand *string `json:"mountCommand,omitempty"`
	// RelativeMountPath - Note that all file shares will be mounted under $AZ_BATCHAI_MOUNT_ROOT location.
	RelativeMountPath *string `json:"relativeMountPath,omitempty"`
}

// UserAccountSettings settings for user account that gets created on each on the nodes of a cluster.
type UserAccountSettings struct {
	AdminUserName         *string `json:"adminUserName,omitempty"`
	AdminUserSSHPublicKey *string `json:"adminUserSshPublicKey,omitempty"`
	AdminUserPassword     *string `json:"adminUserPassword,omitempty"`
}

// VirtualMachineConfiguration settings for OS image.
type VirtualMachineConfiguration struct {
	ImageReference *ImageReference `json:"imageReference,omitempty"`
}
