package postgresql

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

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

// CreateMode enumerates the values for create mode.
type CreateMode string

const (
	// CreateModeDefault ...
	CreateModeDefault CreateMode = "Default"
	// CreateModePointInTimeRestore ...
	CreateModePointInTimeRestore CreateMode = "PointInTimeRestore"
	// CreateModeServerPropertiesForCreate ...
	CreateModeServerPropertiesForCreate CreateMode = "ServerPropertiesForCreate"
)

// PossibleCreateModeValues returns an array of possible values for the CreateMode const type.
func PossibleCreateModeValues() []CreateMode {
	return []CreateMode{CreateModeDefault, CreateModePointInTimeRestore, CreateModeServerPropertiesForCreate}
}

// GeoRedundantBackup enumerates the values for geo redundant backup.
type GeoRedundantBackup string

const (
	// Disabled ...
	Disabled GeoRedundantBackup = "Disabled"
	// Enabled ...
	Enabled GeoRedundantBackup = "Enabled"
)

// PossibleGeoRedundantBackupValues returns an array of possible values for the GeoRedundantBackup const type.
func PossibleGeoRedundantBackupValues() []GeoRedundantBackup {
	return []GeoRedundantBackup{Disabled, Enabled}
}

// OperationOrigin enumerates the values for operation origin.
type OperationOrigin string

const (
	// NotSpecified ...
	NotSpecified OperationOrigin = "NotSpecified"
	// System ...
	System OperationOrigin = "system"
	// User ...
	User OperationOrigin = "user"
)

// PossibleOperationOriginValues returns an array of possible values for the OperationOrigin const type.
func PossibleOperationOriginValues() []OperationOrigin {
	return []OperationOrigin{NotSpecified, System, User}
}

// ServerState enumerates the values for server state.
type ServerState string

const (
	// ServerStateDisabled ...
	ServerStateDisabled ServerState = "Disabled"
	// ServerStateDropping ...
	ServerStateDropping ServerState = "Dropping"
	// ServerStateReady ...
	ServerStateReady ServerState = "Ready"
)

// PossibleServerStateValues returns an array of possible values for the ServerState const type.
func PossibleServerStateValues() []ServerState {
	return []ServerState{ServerStateDisabled, ServerStateDropping, ServerStateReady}
}

// ServerVersion enumerates the values for server version.
type ServerVersion string

const (
	// NineFullStopFive ...
	NineFullStopFive ServerVersion = "9.5"
	// NineFullStopSix ...
	NineFullStopSix ServerVersion = "9.6"
)

// PossibleServerVersionValues returns an array of possible values for the ServerVersion const type.
func PossibleServerVersionValues() []ServerVersion {
	return []ServerVersion{NineFullStopFive, NineFullStopSix}
}

// SkuTier enumerates the values for sku tier.
type SkuTier string

const (
	// Basic ...
	Basic SkuTier = "Basic"
	// GeneralPurpose ...
	GeneralPurpose SkuTier = "GeneralPurpose"
	// MemoryOptimized ...
	MemoryOptimized SkuTier = "MemoryOptimized"
)

// PossibleSkuTierValues returns an array of possible values for the SkuTier const type.
func PossibleSkuTierValues() []SkuTier {
	return []SkuTier{Basic, GeneralPurpose, MemoryOptimized}
}

// SslEnforcementEnum enumerates the values for ssl enforcement enum.
type SslEnforcementEnum string

const (
	// SslEnforcementEnumDisabled ...
	SslEnforcementEnumDisabled SslEnforcementEnum = "Disabled"
	// SslEnforcementEnumEnabled ...
	SslEnforcementEnumEnabled SslEnforcementEnum = "Enabled"
)

// PossibleSslEnforcementEnumValues returns an array of possible values for the SslEnforcementEnum const type.
func PossibleSslEnforcementEnumValues() []SslEnforcementEnum {
	return []SslEnforcementEnum{SslEnforcementEnumDisabled, SslEnforcementEnumEnabled}
}

// Configuration represents a Configuration.
type Configuration struct {
	autorest.Response `json:"-"`
	// ConfigurationProperties - The properties of a configuration.
	*ConfigurationProperties `json:"properties,omitempty"`
	// ID - Resource ID
	ID *string `json:"id,omitempty"`
	// Name - Resource name.
	Name *string `json:"name,omitempty"`
	// Type - Resource type.
	Type *string `json:"type,omitempty"`
}

// MarshalJSON is the custom marshaler for Configuration.
func (c Configuration) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]interface{})
	if c.ConfigurationProperties != nil {
		objectMap["properties"] = c.ConfigurationProperties
	}
	if c.ID != nil {
		objectMap["id"] = c.ID
	}
	if c.Name != nil {
		objectMap["name"] = c.Name
	}
	if c.Type != nil {
		objectMap["type"] = c.Type
	}
	return json.Marshal(objectMap)
}

// UnmarshalJSON is the custom unmarshaler for Configuration struct.
func (c *Configuration) 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 configurationProperties ConfigurationProperties
				err = json.Unmarshal(*v, &configurationProperties)
				if err != nil {
					return err
				}
				c.ConfigurationProperties = &configurationProperties
			}
		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
			}
		}
	}

	return nil
}

// ConfigurationListResult a list of server configurations.
type ConfigurationListResult struct {
	autorest.Response `json:"-"`
	// Value - The list of server configurations.
	Value *[]Configuration `json:"value,omitempty"`
}

// ConfigurationProperties the properties of a configuration.
type ConfigurationProperties struct {
	// Value - Value of the configuration.
	Value *string `json:"value,omitempty"`
	// Description - Description of the configuration.
	Description *string `json:"description,omitempty"`
	// DefaultValue - Default value of the configuration.
	DefaultValue *string `json:"defaultValue,omitempty"`
	// DataType - Data type of the configuration.
	DataType *string `json:"dataType,omitempty"`
	// AllowedValues - Allowed values of the configuration.
	AllowedValues *string `json:"allowedValues,omitempty"`
	// Source - Source of the configuration.
	Source *string `json:"source,omitempty"`
}

// ConfigurationsCreateOrUpdateFuture an abstraction for monitoring and retrieving the results of a long-running
// operation.
type ConfigurationsCreateOrUpdateFuture struct {
	azure.Future
	req *http.Request
}

// Result returns the result of the asynchronous operation.
// If the operation has not completed it will return an error.
func (future ConfigurationsCreateOrUpdateFuture) Result(client ConfigurationsClient) (c Configuration, err error) {
	var done bool
	done, err = future.Done(client)
	if err != nil {
		err = autorest.NewErrorWithError(err, "postgresql.ConfigurationsCreateOrUpdateFuture", "Result", future.Response(), "Polling failure")
		return
	}
	if !done {
		return c, azure.NewAsyncOpIncompleteError("postgresql.ConfigurationsCreateOrUpdateFuture")
	}
	if future.PollingMethod() == azure.PollingLocation {
		c, err = client.CreateOrUpdateResponder(future.Response())
		if err != nil {
			err = autorest.NewErrorWithError(err, "postgresql.ConfigurationsCreateOrUpdateFuture", "Result", future.Response(), "Failure responding to request")
		}
		return
	}
	var req *http.Request
	var resp *http.Response
	if future.PollingURL() != "" {
		req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil)
		if err != nil {
			return
		}
	} else {
		req = autorest.ChangeToGet(future.req)
	}
	resp, err = autorest.SendWithSender(client, req,
		autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...))
	if err != nil {
		err = autorest.NewErrorWithError(err, "postgresql.ConfigurationsCreateOrUpdateFuture", "Result", resp, "Failure sending request")
		return
	}
	c, err = client.CreateOrUpdateResponder(resp)
	if err != nil {
		err = autorest.NewErrorWithError(err, "postgresql.ConfigurationsCreateOrUpdateFuture", "Result", resp, "Failure responding to request")
	}
	return
}

// Database represents a Database.
type Database struct {
	autorest.Response `json:"-"`
	// DatabaseProperties - The properties of a database.
	*DatabaseProperties `json:"properties,omitempty"`
	// ID - Resource ID
	ID *string `json:"id,omitempty"`
	// Name - Resource name.
	Name *string `json:"name,omitempty"`
	// Type - Resource type.
	Type *string `json:"type,omitempty"`
}

// MarshalJSON is the custom marshaler for Database.
func (d Database) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]interface{})
	if d.DatabaseProperties != nil {
		objectMap["properties"] = d.DatabaseProperties
	}
	if d.ID != nil {
		objectMap["id"] = d.ID
	}
	if d.Name != nil {
		objectMap["name"] = d.Name
	}
	if d.Type != nil {
		objectMap["type"] = d.Type
	}
	return json.Marshal(objectMap)
}

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

	return nil
}

// DatabaseListResult a List of databases.
type DatabaseListResult struct {
	autorest.Response `json:"-"`
	// Value - The list of databases housed in a server
	Value *[]Database `json:"value,omitempty"`
}

// DatabaseProperties the properties of a database.
type DatabaseProperties struct {
	// Charset - The charset of the database.
	Charset *string `json:"charset,omitempty"`
	// Collation - The collation of the database.
	Collation *string `json:"collation,omitempty"`
}

// DatabasesCreateOrUpdateFuture an abstraction for monitoring and retrieving the results of a long-running
// operation.
type DatabasesCreateOrUpdateFuture struct {
	azure.Future
	req *http.Request
}

// Result returns the result of the asynchronous operation.
// If the operation has not completed it will return an error.
func (future DatabasesCreateOrUpdateFuture) Result(client DatabasesClient) (d Database, err error) {
	var done bool
	done, err = future.Done(client)
	if err != nil {
		err = autorest.NewErrorWithError(err, "postgresql.DatabasesCreateOrUpdateFuture", "Result", future.Response(), "Polling failure")
		return
	}
	if !done {
		return d, azure.NewAsyncOpIncompleteError("postgresql.DatabasesCreateOrUpdateFuture")
	}
	if future.PollingMethod() == azure.PollingLocation {
		d, err = client.CreateOrUpdateResponder(future.Response())
		if err != nil {
			err = autorest.NewErrorWithError(err, "postgresql.DatabasesCreateOrUpdateFuture", "Result", future.Response(), "Failure responding to request")
		}
		return
	}
	var req *http.Request
	var resp *http.Response
	if future.PollingURL() != "" {
		req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil)
		if err != nil {
			return
		}
	} else {
		req = autorest.ChangeToGet(future.req)
	}
	resp, err = autorest.SendWithSender(client, req,
		autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...))
	if err != nil {
		err = autorest.NewErrorWithError(err, "postgresql.DatabasesCreateOrUpdateFuture", "Result", resp, "Failure sending request")
		return
	}
	d, err = client.CreateOrUpdateResponder(resp)
	if err != nil {
		err = autorest.NewErrorWithError(err, "postgresql.DatabasesCreateOrUpdateFuture", "Result", resp, "Failure responding to request")
	}
	return
}

// DatabasesDeleteFuture an abstraction for monitoring and retrieving the results of a long-running operation.
type DatabasesDeleteFuture struct {
	azure.Future
	req *http.Request
}

// Result returns the result of the asynchronous operation.
// If the operation has not completed it will return an error.
func (future DatabasesDeleteFuture) Result(client DatabasesClient) (ar autorest.Response, err error) {
	var done bool
	done, err = future.Done(client)
	if err != nil {
		err = autorest.NewErrorWithError(err, "postgresql.DatabasesDeleteFuture", "Result", future.Response(), "Polling failure")
		return
	}
	if !done {
		return ar, azure.NewAsyncOpIncompleteError("postgresql.DatabasesDeleteFuture")
	}
	if future.PollingMethod() == azure.PollingLocation {
		ar, err = client.DeleteResponder(future.Response())
		if err != nil {
			err = autorest.NewErrorWithError(err, "postgresql.DatabasesDeleteFuture", "Result", future.Response(), "Failure responding to request")
		}
		return
	}
	var req *http.Request
	var resp *http.Response
	if future.PollingURL() != "" {
		req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil)
		if err != nil {
			return
		}
	} else {
		req = autorest.ChangeToGet(future.req)
	}
	resp, err = autorest.SendWithSender(client, req,
		autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...))
	if err != nil {
		err = autorest.NewErrorWithError(err, "postgresql.DatabasesDeleteFuture", "Result", resp, "Failure sending request")
		return
	}
	ar, err = client.DeleteResponder(resp)
	if err != nil {
		err = autorest.NewErrorWithError(err, "postgresql.DatabasesDeleteFuture", "Result", resp, "Failure responding to request")
	}
	return
}

// FirewallRule represents a server firewall rule.
type FirewallRule struct {
	autorest.Response `json:"-"`
	// FirewallRuleProperties - The properties of a firewall rule.
	*FirewallRuleProperties `json:"properties,omitempty"`
	// ID - Resource ID
	ID *string `json:"id,omitempty"`
	// Name - Resource name.
	Name *string `json:"name,omitempty"`
	// Type - Resource type.
	Type *string `json:"type,omitempty"`
}

// MarshalJSON is the custom marshaler for FirewallRule.
func (fr FirewallRule) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]interface{})
	if fr.FirewallRuleProperties != nil {
		objectMap["properties"] = fr.FirewallRuleProperties
	}
	if fr.ID != nil {
		objectMap["id"] = fr.ID
	}
	if fr.Name != nil {
		objectMap["name"] = fr.Name
	}
	if fr.Type != nil {
		objectMap["type"] = fr.Type
	}
	return json.Marshal(objectMap)
}

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

	return nil
}

// FirewallRuleListResult a list of firewall rules.
type FirewallRuleListResult struct {
	autorest.Response `json:"-"`
	// Value - The list of firewall rules in a server.
	Value *[]FirewallRule `json:"value,omitempty"`
}

// FirewallRuleProperties the properties of a server firewall rule.
type FirewallRuleProperties struct {
	// StartIPAddress - The start IP address of the server firewall rule. Must be IPv4 format.
	StartIPAddress *string `json:"startIpAddress,omitempty"`
	// EndIPAddress - The end IP address of the server firewall rule. Must be IPv4 format.
	EndIPAddress *string `json:"endIpAddress,omitempty"`
}

// FirewallRulesCreateOrUpdateFuture an abstraction for monitoring and retrieving the results of a long-running
// operation.
type FirewallRulesCreateOrUpdateFuture struct {
	azure.Future
	req *http.Request
}

// Result returns the result of the asynchronous operation.
// If the operation has not completed it will return an error.
func (future FirewallRulesCreateOrUpdateFuture) Result(client FirewallRulesClient) (fr FirewallRule, err error) {
	var done bool
	done, err = future.Done(client)
	if err != nil {
		err = autorest.NewErrorWithError(err, "postgresql.FirewallRulesCreateOrUpdateFuture", "Result", future.Response(), "Polling failure")
		return
	}
	if !done {
		return fr, azure.NewAsyncOpIncompleteError("postgresql.FirewallRulesCreateOrUpdateFuture")
	}
	if future.PollingMethod() == azure.PollingLocation {
		fr, err = client.CreateOrUpdateResponder(future.Response())
		if err != nil {
			err = autorest.NewErrorWithError(err, "postgresql.FirewallRulesCreateOrUpdateFuture", "Result", future.Response(), "Failure responding to request")
		}
		return
	}
	var req *http.Request
	var resp *http.Response
	if future.PollingURL() != "" {
		req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil)
		if err != nil {
			return
		}
	} else {
		req = autorest.ChangeToGet(future.req)
	}
	resp, err = autorest.SendWithSender(client, req,
		autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...))
	if err != nil {
		err = autorest.NewErrorWithError(err, "postgresql.FirewallRulesCreateOrUpdateFuture", "Result", resp, "Failure sending request")
		return
	}
	fr, err = client.CreateOrUpdateResponder(resp)
	if err != nil {
		err = autorest.NewErrorWithError(err, "postgresql.FirewallRulesCreateOrUpdateFuture", "Result", resp, "Failure responding to request")
	}
	return
}

// FirewallRulesDeleteFuture an abstraction for monitoring and retrieving the results of a long-running operation.
type FirewallRulesDeleteFuture struct {
	azure.Future
	req *http.Request
}

// Result returns the result of the asynchronous operation.
// If the operation has not completed it will return an error.
func (future FirewallRulesDeleteFuture) Result(client FirewallRulesClient) (ar autorest.Response, err error) {
	var done bool
	done, err = future.Done(client)
	if err != nil {
		err = autorest.NewErrorWithError(err, "postgresql.FirewallRulesDeleteFuture", "Result", future.Response(), "Polling failure")
		return
	}
	if !done {
		return ar, azure.NewAsyncOpIncompleteError("postgresql.FirewallRulesDeleteFuture")
	}
	if future.PollingMethod() == azure.PollingLocation {
		ar, err = client.DeleteResponder(future.Response())
		if err != nil {
			err = autorest.NewErrorWithError(err, "postgresql.FirewallRulesDeleteFuture", "Result", future.Response(), "Failure responding to request")
		}
		return
	}
	var req *http.Request
	var resp *http.Response
	if future.PollingURL() != "" {
		req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil)
		if err != nil {
			return
		}
	} else {
		req = autorest.ChangeToGet(future.req)
	}
	resp, err = autorest.SendWithSender(client, req,
		autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...))
	if err != nil {
		err = autorest.NewErrorWithError(err, "postgresql.FirewallRulesDeleteFuture", "Result", resp, "Failure sending request")
		return
	}
	ar, err = client.DeleteResponder(resp)
	if err != nil {
		err = autorest.NewErrorWithError(err, "postgresql.FirewallRulesDeleteFuture", "Result", resp, "Failure responding to request")
	}
	return
}

// LogFile represents a log file.
type LogFile struct {
	// LogFileProperties - The properties of the log file.
	*LogFileProperties `json:"properties,omitempty"`
	// ID - Resource ID
	ID *string `json:"id,omitempty"`
	// Name - Resource name.
	Name *string `json:"name,omitempty"`
	// Type - Resource type.
	Type *string `json:"type,omitempty"`
}

// MarshalJSON is the custom marshaler for LogFile.
func (lf LogFile) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]interface{})
	if lf.LogFileProperties != nil {
		objectMap["properties"] = lf.LogFileProperties
	}
	if lf.ID != nil {
		objectMap["id"] = lf.ID
	}
	if lf.Name != nil {
		objectMap["name"] = lf.Name
	}
	if lf.Type != nil {
		objectMap["type"] = lf.Type
	}
	return json.Marshal(objectMap)
}

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

	return nil
}

// LogFileListResult a list of log files.
type LogFileListResult struct {
	autorest.Response `json:"-"`
	// Value - The list of log files.
	Value *[]LogFile `json:"value,omitempty"`
}

// LogFileProperties the properties of a log file.
type LogFileProperties struct {
	// Name - Log file name.
	Name *string `json:"name,omitempty"`
	// SizeInKB - Size of the log file.
	SizeInKB *int64 `json:"sizeInKB,omitempty"`
	// CreatedTime - Creation timestamp of the log file.
	CreatedTime *date.Time `json:"createdTime,omitempty"`
	// LastModifiedTime - Last modified timestamp of the log file.
	LastModifiedTime *date.Time `json:"lastModifiedTime,omitempty"`
	// Type - Type of the log file.
	Type *string `json:"type,omitempty"`
	// URL - The url to download the log file from.
	URL *string `json:"url,omitempty"`
}

// NameAvailability represents a resource name availability.
type NameAvailability struct {
	autorest.Response `json:"-"`
	// Message - Error Message.
	Message *string `json:"message,omitempty"`
	// NameAvailable - Indicates whether the resource name is available.
	NameAvailable *bool `json:"nameAvailable,omitempty"`
	// Reason - Reason for name being unavailable.
	Reason *string `json:"reason,omitempty"`
}

// NameAvailabilityRequest request from client to check resource name availability.
type NameAvailabilityRequest struct {
	// Name - Resource name to verify.
	Name *string `json:"name,omitempty"`
	// Type - Resource type used for verification.
	Type *string `json:"type,omitempty"`
}

// Operation REST API operation definition.
type Operation struct {
	// Name - The name of the operation being performed on this particular object.
	Name *string `json:"name,omitempty"`
	// Display - The localized display information for this particular operation or action.
	Display *OperationDisplay `json:"display,omitempty"`
	// Origin - The intended executor of the operation. Possible values include: 'NotSpecified', 'User', 'System'
	Origin OperationOrigin `json:"origin,omitempty"`
	// Properties - Additional descriptions for the operation.
	Properties map[string]interface{} `json:"properties"`
}

// MarshalJSON is the custom marshaler for Operation.
func (o Operation) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]interface{})
	if o.Name != nil {
		objectMap["name"] = o.Name
	}
	if o.Display != nil {
		objectMap["display"] = o.Display
	}
	if o.Origin != "" {
		objectMap["origin"] = o.Origin
	}
	if o.Properties != nil {
		objectMap["properties"] = o.Properties
	}
	return json.Marshal(objectMap)
}

// OperationDisplay display metadata associated with the operation.
type OperationDisplay struct {
	// Provider - Operation resource provider name.
	Provider *string `json:"provider,omitempty"`
	// Resource - Resource on which the operation is performed.
	Resource *string `json:"resource,omitempty"`
	// Operation - Localized friendly name for the operation.
	Operation *string `json:"operation,omitempty"`
	// Description - Operation description.
	Description *string `json:"description,omitempty"`
}

// OperationListResult a list of resource provider operations.
type OperationListResult struct {
	autorest.Response `json:"-"`
	// Value - The list of resource provider operations.
	Value *[]Operation `json:"value,omitempty"`
}

// PerformanceTierListResult a list of performance tiers.
type PerformanceTierListResult struct {
	autorest.Response `json:"-"`
	// Value - The list of performance tiers
	Value *[]PerformanceTierProperties `json:"value,omitempty"`
}

// PerformanceTierProperties performance tier properties
type PerformanceTierProperties struct {
	// ID - ID of the performance tier.
	ID *string `json:"id,omitempty"`
	// MaxBackupRetentionDays - Maximum Backup retention in days for the performance tier edition
	MaxBackupRetentionDays *int32 `json:"maxBackupRetentionDays,omitempty"`
	// MinBackupRetentionDays - Minimum Backup retention in days for the performance tier edition
	MinBackupRetentionDays *int32 `json:"minBackupRetentionDays,omitempty"`
	// MaxStorageMB - Max storage allowed for a server.
	MaxStorageMB *int32 `json:"maxStorageMB,omitempty"`
	// MinStorageMB - Max storage allowed for a server.
	MinStorageMB *int32 `json:"minStorageMB,omitempty"`
	// ServiceLevelObjectives - Service level objectives associated with the performance tier
	ServiceLevelObjectives *[]PerformanceTierServiceLevelObjectives `json:"serviceLevelObjectives,omitempty"`
}

// PerformanceTierServiceLevelObjectives service level objectives for performance tier.
type PerformanceTierServiceLevelObjectives struct {
	// ID - ID for the service level objective.
	ID *string `json:"id,omitempty"`
	// Edition - Edition of the performance tier.
	Edition *string `json:"edition,omitempty"`
	// VCore - vCore associated with the service level objective
	VCore *int32 `json:"vCore,omitempty"`
	// HardwareGeneration - Hardware generation associated with the service level objective
	HardwareGeneration *string `json:"hardwareGeneration,omitempty"`
}

// ProxyResource resource properties.
type ProxyResource struct {
	// ID - Resource ID
	ID *string `json:"id,omitempty"`
	// Name - Resource name.
	Name *string `json:"name,omitempty"`
	// Type - Resource type.
	Type *string `json:"type,omitempty"`
}

// Server represents a server.
type Server struct {
	autorest.Response `json:"-"`
	// Sku - The SKU (pricing tier) of the server.
	Sku *Sku `json:"sku,omitempty"`
	// ServerProperties - Properties of the server.
	*ServerProperties `json:"properties,omitempty"`
	// Location - The location the resource resides in.
	Location *string `json:"location,omitempty"`
	// Tags - Application-specific metadata in the form of key-value pairs.
	Tags map[string]*string `json:"tags"`
	// ID - Resource ID
	ID *string `json:"id,omitempty"`
	// Name - Resource name.
	Name *string `json:"name,omitempty"`
	// Type - Resource type.
	Type *string `json:"type,omitempty"`
}

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

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

	return nil
}

// ServerForCreate represents a server to be created.
type ServerForCreate struct {
	// Sku - The SKU (pricing tier) of the server.
	Sku *Sku `json:"sku,omitempty"`
	// Properties - Properties of the server.
	Properties BasicServerPropertiesForCreate `json:"properties,omitempty"`
	// Location - The location the resource resides in.
	Location *string `json:"location,omitempty"`
	// Tags - Application-specific metadata in the form of key-value pairs.
	Tags map[string]*string `json:"tags"`
}

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

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

	return nil
}

// ServerListResult a list of servers.
type ServerListResult struct {
	autorest.Response `json:"-"`
	// Value - The list of servers
	Value *[]Server `json:"value,omitempty"`
}

// ServerProperties the properties of a server.
type ServerProperties struct {
	// AdministratorLogin - The administrator's login name of a server. Can only be specified when the server is being created (and is required for creation).
	AdministratorLogin *string `json:"administratorLogin,omitempty"`
	// Version - Server version. Possible values include: 'NineFullStopFive', 'NineFullStopSix'
	Version ServerVersion `json:"version,omitempty"`
	// SslEnforcement - Enable ssl enforcement or not when connect to server. Possible values include: 'SslEnforcementEnumEnabled', 'SslEnforcementEnumDisabled'
	SslEnforcement SslEnforcementEnum `json:"sslEnforcement,omitempty"`
	// UserVisibleState - A state of a server that is visible to user. Possible values include: 'ServerStateReady', 'ServerStateDropping', 'ServerStateDisabled'
	UserVisibleState ServerState `json:"userVisibleState,omitempty"`
	// FullyQualifiedDomainName - The fully qualified domain name of a server.
	FullyQualifiedDomainName *string `json:"fullyQualifiedDomainName,omitempty"`
	// EarliestRestoreDate - Earliest restore point creation time (ISO8601 format)
	EarliestRestoreDate *date.Time `json:"earliestRestoreDate,omitempty"`
	// StorageProfile - Storage profile of a server.
	StorageProfile *StorageProfile `json:"storageProfile,omitempty"`
}

// BasicServerPropertiesForCreate the properties used to create a new server.
type BasicServerPropertiesForCreate interface {
	AsServerPropertiesForDefaultCreate() (*ServerPropertiesForDefaultCreate, bool)
	AsServerPropertiesForRestore() (*ServerPropertiesForRestore, bool)
	AsServerPropertiesForCreate() (*ServerPropertiesForCreate, bool)
}

// ServerPropertiesForCreate the properties used to create a new server.
type ServerPropertiesForCreate struct {
	// Version - Server version. Possible values include: 'NineFullStopFive', 'NineFullStopSix'
	Version ServerVersion `json:"version,omitempty"`
	// SslEnforcement - Enable ssl enforcement or not when connect to server. Possible values include: 'SslEnforcementEnumEnabled', 'SslEnforcementEnumDisabled'
	SslEnforcement SslEnforcementEnum `json:"sslEnforcement,omitempty"`
	// StorageProfile - Storage profile of a server.
	StorageProfile *StorageProfile `json:"storageProfile,omitempty"`
	// CreateMode - Possible values include: 'CreateModeServerPropertiesForCreate', 'CreateModeDefault', 'CreateModePointInTimeRestore'
	CreateMode CreateMode `json:"createMode,omitempty"`
}

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

	switch m["createMode"] {
	case string(CreateModeDefault):
		var spfdc ServerPropertiesForDefaultCreate
		err := json.Unmarshal(body, &spfdc)
		return spfdc, err
	case string(CreateModePointInTimeRestore):
		var spfr ServerPropertiesForRestore
		err := json.Unmarshal(body, &spfr)
		return spfr, err
	default:
		var spfc ServerPropertiesForCreate
		err := json.Unmarshal(body, &spfc)
		return spfc, err
	}
}
func unmarshalBasicServerPropertiesForCreateArray(body []byte) ([]BasicServerPropertiesForCreate, error) {
	var rawMessages []*json.RawMessage
	err := json.Unmarshal(body, &rawMessages)
	if err != nil {
		return nil, err
	}

	spfcArray := make([]BasicServerPropertiesForCreate, len(rawMessages))

	for index, rawMessage := range rawMessages {
		spfc, err := unmarshalBasicServerPropertiesForCreate(*rawMessage)
		if err != nil {
			return nil, err
		}
		spfcArray[index] = spfc
	}
	return spfcArray, nil
}

// MarshalJSON is the custom marshaler for ServerPropertiesForCreate.
func (spfc ServerPropertiesForCreate) MarshalJSON() ([]byte, error) {
	spfc.CreateMode = CreateModeServerPropertiesForCreate
	objectMap := make(map[string]interface{})
	if spfc.Version != "" {
		objectMap["version"] = spfc.Version
	}
	if spfc.SslEnforcement != "" {
		objectMap["sslEnforcement"] = spfc.SslEnforcement
	}
	if spfc.StorageProfile != nil {
		objectMap["storageProfile"] = spfc.StorageProfile
	}
	if spfc.CreateMode != "" {
		objectMap["createMode"] = spfc.CreateMode
	}
	return json.Marshal(objectMap)
}

// AsServerPropertiesForDefaultCreate is the BasicServerPropertiesForCreate implementation for ServerPropertiesForCreate.
func (spfc ServerPropertiesForCreate) AsServerPropertiesForDefaultCreate() (*ServerPropertiesForDefaultCreate, bool) {
	return nil, false
}

// AsServerPropertiesForRestore is the BasicServerPropertiesForCreate implementation for ServerPropertiesForCreate.
func (spfc ServerPropertiesForCreate) AsServerPropertiesForRestore() (*ServerPropertiesForRestore, bool) {
	return nil, false
}

// AsServerPropertiesForCreate is the BasicServerPropertiesForCreate implementation for ServerPropertiesForCreate.
func (spfc ServerPropertiesForCreate) AsServerPropertiesForCreate() (*ServerPropertiesForCreate, bool) {
	return &spfc, true
}

// AsBasicServerPropertiesForCreate is the BasicServerPropertiesForCreate implementation for ServerPropertiesForCreate.
func (spfc ServerPropertiesForCreate) AsBasicServerPropertiesForCreate() (BasicServerPropertiesForCreate, bool) {
	return &spfc, true
}

// ServerPropertiesForDefaultCreate the properties used to create a new server.
type ServerPropertiesForDefaultCreate struct {
	// AdministratorLogin - The administrator's login name of a server. Can only be specified when the server is being created (and is required for creation).
	AdministratorLogin *string `json:"administratorLogin,omitempty"`
	// AdministratorLoginPassword - The password of the administrator login.
	AdministratorLoginPassword *string `json:"administratorLoginPassword,omitempty"`
	// Version - Server version. Possible values include: 'NineFullStopFive', 'NineFullStopSix'
	Version ServerVersion `json:"version,omitempty"`
	// SslEnforcement - Enable ssl enforcement or not when connect to server. Possible values include: 'SslEnforcementEnumEnabled', 'SslEnforcementEnumDisabled'
	SslEnforcement SslEnforcementEnum `json:"sslEnforcement,omitempty"`
	// StorageProfile - Storage profile of a server.
	StorageProfile *StorageProfile `json:"storageProfile,omitempty"`
	// CreateMode - Possible values include: 'CreateModeServerPropertiesForCreate', 'CreateModeDefault', 'CreateModePointInTimeRestore'
	CreateMode CreateMode `json:"createMode,omitempty"`
}

// MarshalJSON is the custom marshaler for ServerPropertiesForDefaultCreate.
func (spfdc ServerPropertiesForDefaultCreate) MarshalJSON() ([]byte, error) {
	spfdc.CreateMode = CreateModeDefault
	objectMap := make(map[string]interface{})
	if spfdc.AdministratorLogin != nil {
		objectMap["administratorLogin"] = spfdc.AdministratorLogin
	}
	if spfdc.AdministratorLoginPassword != nil {
		objectMap["administratorLoginPassword"] = spfdc.AdministratorLoginPassword
	}
	if spfdc.Version != "" {
		objectMap["version"] = spfdc.Version
	}
	if spfdc.SslEnforcement != "" {
		objectMap["sslEnforcement"] = spfdc.SslEnforcement
	}
	if spfdc.StorageProfile != nil {
		objectMap["storageProfile"] = spfdc.StorageProfile
	}
	if spfdc.CreateMode != "" {
		objectMap["createMode"] = spfdc.CreateMode
	}
	return json.Marshal(objectMap)
}

// AsServerPropertiesForDefaultCreate is the BasicServerPropertiesForCreate implementation for ServerPropertiesForDefaultCreate.
func (spfdc ServerPropertiesForDefaultCreate) AsServerPropertiesForDefaultCreate() (*ServerPropertiesForDefaultCreate, bool) {
	return &spfdc, true
}

// AsServerPropertiesForRestore is the BasicServerPropertiesForCreate implementation for ServerPropertiesForDefaultCreate.
func (spfdc ServerPropertiesForDefaultCreate) AsServerPropertiesForRestore() (*ServerPropertiesForRestore, bool) {
	return nil, false
}

// AsServerPropertiesForCreate is the BasicServerPropertiesForCreate implementation for ServerPropertiesForDefaultCreate.
func (spfdc ServerPropertiesForDefaultCreate) AsServerPropertiesForCreate() (*ServerPropertiesForCreate, bool) {
	return nil, false
}

// AsBasicServerPropertiesForCreate is the BasicServerPropertiesForCreate implementation for ServerPropertiesForDefaultCreate.
func (spfdc ServerPropertiesForDefaultCreate) AsBasicServerPropertiesForCreate() (BasicServerPropertiesForCreate, bool) {
	return &spfdc, true
}

// ServerPropertiesForRestore the properties to a new server by restoring from a backup.
type ServerPropertiesForRestore struct {
	// SourceServerID - The source server id to restore from.
	SourceServerID *string `json:"sourceServerId,omitempty"`
	// RestorePointInTime - Restore point creation time (ISO8601 format), specifying the time to restore from.
	RestorePointInTime *date.Time `json:"restorePointInTime,omitempty"`
	// Version - Server version. Possible values include: 'NineFullStopFive', 'NineFullStopSix'
	Version ServerVersion `json:"version,omitempty"`
	// SslEnforcement - Enable ssl enforcement or not when connect to server. Possible values include: 'SslEnforcementEnumEnabled', 'SslEnforcementEnumDisabled'
	SslEnforcement SslEnforcementEnum `json:"sslEnforcement,omitempty"`
	// StorageProfile - Storage profile of a server.
	StorageProfile *StorageProfile `json:"storageProfile,omitempty"`
	// CreateMode - Possible values include: 'CreateModeServerPropertiesForCreate', 'CreateModeDefault', 'CreateModePointInTimeRestore'
	CreateMode CreateMode `json:"createMode,omitempty"`
}

// MarshalJSON is the custom marshaler for ServerPropertiesForRestore.
func (spfr ServerPropertiesForRestore) MarshalJSON() ([]byte, error) {
	spfr.CreateMode = CreateModePointInTimeRestore
	objectMap := make(map[string]interface{})
	if spfr.SourceServerID != nil {
		objectMap["sourceServerId"] = spfr.SourceServerID
	}
	if spfr.RestorePointInTime != nil {
		objectMap["restorePointInTime"] = spfr.RestorePointInTime
	}
	if spfr.Version != "" {
		objectMap["version"] = spfr.Version
	}
	if spfr.SslEnforcement != "" {
		objectMap["sslEnforcement"] = spfr.SslEnforcement
	}
	if spfr.StorageProfile != nil {
		objectMap["storageProfile"] = spfr.StorageProfile
	}
	if spfr.CreateMode != "" {
		objectMap["createMode"] = spfr.CreateMode
	}
	return json.Marshal(objectMap)
}

// AsServerPropertiesForDefaultCreate is the BasicServerPropertiesForCreate implementation for ServerPropertiesForRestore.
func (spfr ServerPropertiesForRestore) AsServerPropertiesForDefaultCreate() (*ServerPropertiesForDefaultCreate, bool) {
	return nil, false
}

// AsServerPropertiesForRestore is the BasicServerPropertiesForCreate implementation for ServerPropertiesForRestore.
func (spfr ServerPropertiesForRestore) AsServerPropertiesForRestore() (*ServerPropertiesForRestore, bool) {
	return &spfr, true
}

// AsServerPropertiesForCreate is the BasicServerPropertiesForCreate implementation for ServerPropertiesForRestore.
func (spfr ServerPropertiesForRestore) AsServerPropertiesForCreate() (*ServerPropertiesForCreate, bool) {
	return nil, false
}

// AsBasicServerPropertiesForCreate is the BasicServerPropertiesForCreate implementation for ServerPropertiesForRestore.
func (spfr ServerPropertiesForRestore) AsBasicServerPropertiesForCreate() (BasicServerPropertiesForCreate, bool) {
	return &spfr, true
}

// ServersCreateFuture an abstraction for monitoring and retrieving the results of a long-running operation.
type ServersCreateFuture struct {
	azure.Future
	req *http.Request
}

// Result returns the result of the asynchronous operation.
// If the operation has not completed it will return an error.
func (future ServersCreateFuture) Result(client ServersClient) (s Server, err error) {
	var done bool
	done, err = future.Done(client)
	if err != nil {
		err = autorest.NewErrorWithError(err, "postgresql.ServersCreateFuture", "Result", future.Response(), "Polling failure")
		return
	}
	if !done {
		return s, azure.NewAsyncOpIncompleteError("postgresql.ServersCreateFuture")
	}
	if future.PollingMethod() == azure.PollingLocation {
		s, err = client.CreateResponder(future.Response())
		if err != nil {
			err = autorest.NewErrorWithError(err, "postgresql.ServersCreateFuture", "Result", future.Response(), "Failure responding to request")
		}
		return
	}
	var req *http.Request
	var resp *http.Response
	if future.PollingURL() != "" {
		req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil)
		if err != nil {
			return
		}
	} else {
		req = autorest.ChangeToGet(future.req)
	}
	resp, err = autorest.SendWithSender(client, req,
		autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...))
	if err != nil {
		err = autorest.NewErrorWithError(err, "postgresql.ServersCreateFuture", "Result", resp, "Failure sending request")
		return
	}
	s, err = client.CreateResponder(resp)
	if err != nil {
		err = autorest.NewErrorWithError(err, "postgresql.ServersCreateFuture", "Result", resp, "Failure responding to request")
	}
	return
}

// ServersDeleteFuture an abstraction for monitoring and retrieving the results of a long-running operation.
type ServersDeleteFuture struct {
	azure.Future
	req *http.Request
}

// Result returns the result of the asynchronous operation.
// If the operation has not completed it will return an error.
func (future ServersDeleteFuture) Result(client ServersClient) (ar autorest.Response, err error) {
	var done bool
	done, err = future.Done(client)
	if err != nil {
		err = autorest.NewErrorWithError(err, "postgresql.ServersDeleteFuture", "Result", future.Response(), "Polling failure")
		return
	}
	if !done {
		return ar, azure.NewAsyncOpIncompleteError("postgresql.ServersDeleteFuture")
	}
	if future.PollingMethod() == azure.PollingLocation {
		ar, err = client.DeleteResponder(future.Response())
		if err != nil {
			err = autorest.NewErrorWithError(err, "postgresql.ServersDeleteFuture", "Result", future.Response(), "Failure responding to request")
		}
		return
	}
	var req *http.Request
	var resp *http.Response
	if future.PollingURL() != "" {
		req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil)
		if err != nil {
			return
		}
	} else {
		req = autorest.ChangeToGet(future.req)
	}
	resp, err = autorest.SendWithSender(client, req,
		autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...))
	if err != nil {
		err = autorest.NewErrorWithError(err, "postgresql.ServersDeleteFuture", "Result", resp, "Failure sending request")
		return
	}
	ar, err = client.DeleteResponder(resp)
	if err != nil {
		err = autorest.NewErrorWithError(err, "postgresql.ServersDeleteFuture", "Result", resp, "Failure responding to request")
	}
	return
}

// ServersUpdateFuture an abstraction for monitoring and retrieving the results of a long-running operation.
type ServersUpdateFuture struct {
	azure.Future
	req *http.Request
}

// Result returns the result of the asynchronous operation.
// If the operation has not completed it will return an error.
func (future ServersUpdateFuture) Result(client ServersClient) (s Server, err error) {
	var done bool
	done, err = future.Done(client)
	if err != nil {
		err = autorest.NewErrorWithError(err, "postgresql.ServersUpdateFuture", "Result", future.Response(), "Polling failure")
		return
	}
	if !done {
		return s, azure.NewAsyncOpIncompleteError("postgresql.ServersUpdateFuture")
	}
	if future.PollingMethod() == azure.PollingLocation {
		s, err = client.UpdateResponder(future.Response())
		if err != nil {
			err = autorest.NewErrorWithError(err, "postgresql.ServersUpdateFuture", "Result", future.Response(), "Failure responding to request")
		}
		return
	}
	var req *http.Request
	var resp *http.Response
	if future.PollingURL() != "" {
		req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil)
		if err != nil {
			return
		}
	} else {
		req = autorest.ChangeToGet(future.req)
	}
	resp, err = autorest.SendWithSender(client, req,
		autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...))
	if err != nil {
		err = autorest.NewErrorWithError(err, "postgresql.ServersUpdateFuture", "Result", resp, "Failure sending request")
		return
	}
	s, err = client.UpdateResponder(resp)
	if err != nil {
		err = autorest.NewErrorWithError(err, "postgresql.ServersUpdateFuture", "Result", resp, "Failure responding to request")
	}
	return
}

// ServerUpdateParameters parameters allowd to update for a server.
type ServerUpdateParameters struct {
	// Sku - The SKU (pricing tier) of the server.
	Sku *Sku `json:"sku,omitempty"`
	// ServerUpdateParametersProperties - The properties that can be updated for a server.
	*ServerUpdateParametersProperties `json:"properties,omitempty"`
	// Tags - Application-specific metadata in the form of key-value pairs.
	Tags map[string]*string `json:"tags"`
}

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

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

	return nil
}

// ServerUpdateParametersProperties the properties that can be updated for a server.
type ServerUpdateParametersProperties struct {
	// StorageProfile - Storage profile of a server.
	StorageProfile *StorageProfile `json:"storageProfile,omitempty"`
	// AdministratorLoginPassword - The password of the administrator login.
	AdministratorLoginPassword *string `json:"administratorLoginPassword,omitempty"`
	// Version - The version of a server. Possible values include: 'NineFullStopFive', 'NineFullStopSix'
	Version ServerVersion `json:"version,omitempty"`
	// SslEnforcement - Enable ssl enforcement or not when connect to server. Possible values include: 'SslEnforcementEnumEnabled', 'SslEnforcementEnumDisabled'
	SslEnforcement SslEnforcementEnum `json:"sslEnforcement,omitempty"`
}

// Sku billing information related properties of a server.
type Sku struct {
	// Name - The name of the sku, typically, tier + family + cores, e.g. B_Gen4_1, GP_Gen5_8.
	Name *string `json:"name,omitempty"`
	// Tier - The tier of the particular SKU, e.g. Basic. Possible values include: 'Basic', 'GeneralPurpose', 'MemoryOptimized'
	Tier SkuTier `json:"tier,omitempty"`
	// Capacity - The scale up/out capacity, representing server's compute units.
	Capacity *int32 `json:"capacity,omitempty"`
	// Size - The size code, to be interpreted by resource as appropriate.
	Size *string `json:"size,omitempty"`
	// Family - The family of hardware.
	Family *string `json:"family,omitempty"`
}

// StorageProfile storage Profile properties of a server
type StorageProfile struct {
	// BackupRetentionDays - Backup retention days for the server.
	BackupRetentionDays *int32 `json:"backupRetentionDays,omitempty"`
	// GeoRedundantBackup - Enable Geo-redundant or not for server backup. Possible values include: 'Enabled', 'Disabled'
	GeoRedundantBackup GeoRedundantBackup `json:"geoRedundantBackup,omitempty"`
	// StorageMB - Max storage allowed for a server.
	StorageMB *int32 `json:"storageMB,omitempty"`
}

// TrackedResource resource properties including location and tags for track resources.
type TrackedResource struct {
	// Location - The location the resource resides in.
	Location *string `json:"location,omitempty"`
	// Tags - Application-specific metadata in the form of key-value pairs.
	Tags map[string]*string `json:"tags"`
	// ID - Resource ID
	ID *string `json:"id,omitempty"`
	// Name - Resource name.
	Name *string `json:"name,omitempty"`
	// Type - Resource type.
	Type *string `json:"type,omitempty"`
}

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