package mysql

// 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"
	"errors"
	"github.com/Azure/go-autorest/autorest"
	"github.com/Azure/go-autorest/autorest/date"
)

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

const (
	// CreateModeDefault specifies the create mode default state for create mode.
	CreateModeDefault CreateMode = "Default"
	// CreateModePointInTimeRestore specifies the create mode point in time restore state for create mode.
	CreateModePointInTimeRestore CreateMode = "PointInTimeRestore"
)

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

const (
	// NotSpecified specifies the not specified state for operation origin.
	NotSpecified OperationOrigin = "NotSpecified"
	// System specifies the system state for operation origin.
	System OperationOrigin = "system"
	// User specifies the user state for operation origin.
	User OperationOrigin = "user"
)

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

const (
	// Disabled specifies the disabled state for server state.
	Disabled ServerState = "Disabled"
	// Dropping specifies the dropping state for server state.
	Dropping ServerState = "Dropping"
	// Ready specifies the ready state for server state.
	Ready ServerState = "Ready"
)

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

const (
	// FiveFullStopSeven specifies the five full stop seven state for server version.
	FiveFullStopSeven ServerVersion = "5.7"
	// FiveFullStopSix specifies the five full stop six state for server version.
	FiveFullStopSix ServerVersion = "5.6"
)

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

const (
	// Basic specifies the basic state for sku tier.
	Basic SkuTier = "Basic"
	// Standard specifies the standard state for sku tier.
	Standard SkuTier = "Standard"
)

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

const (
	// SslEnforcementEnumDisabled specifies the ssl enforcement enum disabled state for ssl enforcement enum.
	SslEnforcementEnumDisabled SslEnforcementEnum = "Disabled"
	// SslEnforcementEnumEnabled specifies the ssl enforcement enum enabled state for ssl enforcement enum.
	SslEnforcementEnumEnabled SslEnforcementEnum = "Enabled"
)

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

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

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

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

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

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

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

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

// FirewallRuleProperties is the properties of a server firewall rule.
type FirewallRuleProperties struct {
	StartIPAddress *string `json:"startIpAddress,omitempty"`
	EndIPAddress   *string `json:"endIpAddress,omitempty"`
}

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

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

// LogFileProperties is the properties of a log file.
type LogFileProperties struct {
	Name             *string    `json:"name,omitempty"`
	SizeInKB         *int64     `json:"sizeInKB,omitempty"`
	CreatedTime      *date.Time `json:"createdTime,omitempty"`
	LastModifiedTime *date.Time `json:"lastModifiedTime,omitempty"`
	Type             *string    `json:"type,omitempty"`
	URL              *string    `json:"url,omitempty"`
}

// Operation is REST API operation definition.
type Operation struct {
	Name       *string                             `json:"name,omitempty"`
	Display    *OperationDisplay                   `json:"display,omitempty"`
	Origin     OperationOrigin                     `json:"origin,omitempty"`
	Properties *map[string]*map[string]interface{} `json:"properties,omitempty"`
}

// OperationDisplay is display metadata associated with the operation.
type OperationDisplay struct {
	Provider    *string `json:"provider,omitempty"`
	Resource    *string `json:"resource,omitempty"`
	Operation   *string `json:"operation,omitempty"`
	Description *string `json:"description,omitempty"`
}

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

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

// Server is represents a server.
type Server struct {
	autorest.Response `json:"-"`
	ID                *string             `json:"id,omitempty"`
	Name              *string             `json:"name,omitempty"`
	Type              *string             `json:"type,omitempty"`
	Location          *string             `json:"location,omitempty"`
	Tags              *map[string]*string `json:"tags,omitempty"`
	Sku               *Sku                `json:"sku,omitempty"`
	*ServerProperties `json:"properties,omitempty"`
}

// ServerForCreate is represents a server to be created.
type ServerForCreate struct {
	Sku        *Sku                      `json:"sku,omitempty"`
	Properties ServerPropertiesForCreate `json:"properties,omitempty"`
	Location   *string                   `json:"location,omitempty"`
	Tags       *map[string]*string       `json:"tags,omitempty"`
}

// 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
	}
	var v *json.RawMessage

	v = m["sku"]
	if v != nil {
		var sku Sku
		err = json.Unmarshal(*m["sku"], &sku)
		if err != nil {
			return err
		}
		sfc.Sku = &sku
	}

	v = m["properties"]
	if v != nil {
		properties, err := unmarshalServerPropertiesForCreate(*m["properties"])
		if err != nil {
			return err
		}
		sfc.Properties = properties
	}

	v = m["location"]
	if v != nil {
		var location string
		err = json.Unmarshal(*m["location"], &location)
		if err != nil {
			return err
		}
		sfc.Location = &location
	}

	v = m["tags"]
	if v != nil {
		var tags map[string]*string
		err = json.Unmarshal(*m["tags"], &tags)
		if err != nil {
			return err
		}
		sfc.Tags = &tags
	}

	return nil
}

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

// ServerProperties is the properties of a server.
type ServerProperties struct {
	AdministratorLogin       *string            `json:"administratorLogin,omitempty"`
	StorageMB                *int64             `json:"storageMB,omitempty"`
	Version                  ServerVersion      `json:"version,omitempty"`
	SslEnforcement           SslEnforcementEnum `json:"sslEnforcement,omitempty"`
	UserVisibleState         ServerState        `json:"userVisibleState,omitempty"`
	FullyQualifiedDomainName *string            `json:"fullyQualifiedDomainName,omitempty"`
}

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

func unmarshalServerPropertiesForCreate(body []byte) (ServerPropertiesForCreate, 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:
		return nil, errors.New("Unsupported type")
	}
}
func unmarshalServerPropertiesForCreateArray(body []byte) ([]ServerPropertiesForCreate, error) {
	var rawMessages []*json.RawMessage
	err := json.Unmarshal(body, &rawMessages)
	if err != nil {
		return nil, err
	}

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

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

// ServerPropertiesForDefaultCreate is the properties used to create a new server.
type ServerPropertiesForDefaultCreate struct {
	StorageMB                  *int64             `json:"storageMB,omitempty"`
	Version                    ServerVersion      `json:"version,omitempty"`
	SslEnforcement             SslEnforcementEnum `json:"sslEnforcement,omitempty"`
	CreateMode                 CreateMode         `json:"createMode,omitempty"`
	AdministratorLogin         *string            `json:"administratorLogin,omitempty"`
	AdministratorLoginPassword *string            `json:"administratorLoginPassword,omitempty"`
}

// MarshalJSON is the custom marshaler for ServerPropertiesForDefaultCreate.
func (spfdc ServerPropertiesForDefaultCreate) MarshalJSON() ([]byte, error) {
	spfdc.CreateMode = CreateModeDefault
	type Alias ServerPropertiesForDefaultCreate
	return json.Marshal(&struct {
		Alias
	}{
		Alias: (Alias)(spfdc),
	})
}

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

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

// ServerPropertiesForRestore is the properties to a new server by restoring from a backup.
type ServerPropertiesForRestore struct {
	StorageMB          *int64             `json:"storageMB,omitempty"`
	Version            ServerVersion      `json:"version,omitempty"`
	SslEnforcement     SslEnforcementEnum `json:"sslEnforcement,omitempty"`
	CreateMode         CreateMode         `json:"createMode,omitempty"`
	SourceServerID     *string            `json:"sourceServerId,omitempty"`
	RestorePointInTime *date.Time         `json:"restorePointInTime,omitempty"`
}

// MarshalJSON is the custom marshaler for ServerPropertiesForRestore.
func (spfr ServerPropertiesForRestore) MarshalJSON() ([]byte, error) {
	spfr.CreateMode = CreateModePointInTimeRestore
	type Alias ServerPropertiesForRestore
	return json.Marshal(&struct {
		Alias
	}{
		Alias: (Alias)(spfr),
	})
}

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

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

// ServerUpdateParameters is parameters allowd to update for a server.
type ServerUpdateParameters struct {
	Sku                               *Sku `json:"sku,omitempty"`
	*ServerUpdateParametersProperties `json:"properties,omitempty"`
	Tags                              *map[string]*string `json:"tags,omitempty"`
}

// ServerUpdateParametersProperties is the properties that can be updated for a server.
type ServerUpdateParametersProperties struct {
	StorageMB                  *int64             `json:"storageMB,omitempty"`
	AdministratorLoginPassword *string            `json:"administratorLoginPassword,omitempty"`
	Version                    ServerVersion      `json:"version,omitempty"`
	SslEnforcement             SslEnforcementEnum `json:"sslEnforcement,omitempty"`
}

// Sku is billing information related properties of a server.
type Sku struct {
	Name     *string `json:"name,omitempty"`
	Tier     SkuTier `json:"tier,omitempty"`
	Capacity *int32  `json:"capacity,omitempty"`
	Size     *string `json:"size,omitempty"`
	Family   *string `json:"family,omitempty"`
}

// TrackedResource is resource properties including location and tags for track resources.
type TrackedResource struct {
	ID       *string             `json:"id,omitempty"`
	Name     *string             `json:"name,omitempty"`
	Type     *string             `json:"type,omitempty"`
	Location *string             `json:"location,omitempty"`
	Tags     *map[string]*string `json:"tags,omitempty"`
}
