func LateInitializePostgreSQL(p *azuredbv1beta1.SQLServerParameters, in postgresql.Server) {
	if in.Sku != nil {
		p.SKU.Size = azure.LateInitializeStringPtrFromPtr(p.SKU.Size, in.Sku.Size)
	}
	p.Tags = azure.LateInitializeStringMap(p.Tags, in.Tags)
	if in.StorageProfile != nil {
		p.StorageProfile.BackupRetentionDays = azure.LateInitializeIntPtrFromInt32Ptr(p.StorageProfile.BackupRetentionDays, in.StorageProfile.BackupRetentionDays)
		p.StorageProfile.GeoRedundantBackup = azure.LateInitializeStringPtrFromVal(p.StorageProfile.GeoRedundantBackup, string(in.StorageProfile.GeoRedundantBackup))
		p.StorageProfile.StorageAutogrow = azure.LateInitializeStringPtrFromVal(p.StorageProfile.StorageAutogrow, string(in.StorageProfile.StorageAutogrow))
	}
	if p.MinimalTLSVersion == "" {
		p.MinimalTLSVersion = string(in.MinimalTLSVersion)
	}
	if p.SSLEnforcement == "" {
		p.SSLEnforcement = string(in.SslEnforcement)
	}
	if p.PublicNetworkAccess == nil {
		p.PublicNetworkAccess = azure.ToStringPtr(string(in.PublicNetworkAccess))
	}
}
LateInitializePostgreSQL fills the empty values of SQLServerParameters with the
ones that are retrieved from the Azure API.
package database
import (
	"context"
	"fmt"
	"net/http"
	"reflect"
	"strconv"
	"github.com/Azure/azure-sdk-for-go/services/mysql/mgmt/2017-12-01/mysql"
	"github.com/Azure/azure-sdk-for-go/services/postgresql/mgmt/2017-12-01/postgresql"
	"github.com/Azure/go-autorest/autorest"
	"github.com/google/go-cmp/cmp"
	"github.com/crossplane/crossplane-runtime/pkg/meta"
	azuredbv1alpha3 "github.com/crossplane/provider-azure/apis/database/v1alpha3"
	"github.com/crossplane/provider-azure/apis/database/v1beta1"
	azuredbv1beta1 "github.com/crossplane/provider-azure/apis/database/v1beta1"
	"github.com/crossplane/provider-azure/apis/v1alpha3"
	azure "github.com/crossplane/provider-azure/pkg/clients"
)
type PostgreSQLServerAPI interface {
	GetServer(ctx context.Context, s *azuredbv1beta1.PostgreSQLServer) (postgresql.Server, error)
	CreateServer(ctx context.Context, s *azuredbv1beta1.PostgreSQLServer, adminPassword string) error
	DeleteServer(ctx context.Context, s *azuredbv1beta1.PostgreSQLServer) error
	UpdateServer(ctx context.Context, s *azuredbv1beta1.PostgreSQLServer) error
	GetRESTClient() autorest.Sender
}
type PostgreSQLServerClient struct {
	postgresql.ServersClient
}
func NewPostgreSQLServerClient(cl postgresql.ServersClient) *PostgreSQLServerClient {
	return &PostgreSQLServerClient{
		ServersClient: cl,
	}
}
func (c *PostgreSQLServerClient) GetRESTClient() autorest.Sender {
	return c.ServersClient.Client
}
func (c *PostgreSQLServerClient) GetServer(ctx context.Context, cr *azuredbv1beta1.PostgreSQLServer) (postgresql.Server, error) {
	return c.ServersClient.Get(ctx, cr.Spec.ForProvider.ResourceGroupName, meta.GetExternalName(cr))
}
func toPGSQLProperties(s v1beta1.SQLServerParameters, adminPassword string) postgresql.BasicServerPropertiesForCreate {
	createMode := pointerToCreateMode(s.CreateMode)
	switch createMode {
	case azuredbv1beta1.CreateModePointInTimeRestore:
		return &postgresql.ServerPropertiesForRestore{
			MinimalTLSVersion:   postgresql.MinimalTLSVersionEnum(s.MinimalTLSVersion),
			Version:             postgresql.ServerVersion(s.Version),
			SslEnforcement:      postgresql.SslEnforcementEnum(s.SSLEnforcement),
			PublicNetworkAccess: postgresql.PublicNetworkAccessEnum(azure.ToString(s.PublicNetworkAccess)),
			CreateMode:          postgresql.CreateModePointInTimeRestore,
			RestorePointInTime:  safeDate(s.RestorePointInTime),
			SourceServerID:      s.SourceServerID,
			StorageProfile: &postgresql.StorageProfile{
				BackupRetentionDays: azure.ToInt32PtrFromIntPtr(s.StorageProfile.BackupRetentionDays),
				GeoRedundantBackup:  postgresql.GeoRedundantBackup(azure.ToString(s.StorageProfile.GeoRedundantBackup)),
				StorageMB:           azure.ToInt32Ptr(s.StorageProfile.StorageMB),
				StorageAutogrow:     postgresql.StorageAutogrow(azure.ToString(s.StorageProfile.StorageAutogrow)),
			},
		}
	case azuredbv1beta1.CreateModeGeoRestore:
		return &postgresql.ServerPropertiesForGeoRestore{
			MinimalTLSVersion:   postgresql.MinimalTLSVersionEnum(s.MinimalTLSVersion),
			Version:             postgresql.ServerVersion(s.Version),
			SslEnforcement:      postgresql.SslEnforcementEnum(s.SSLEnforcement),
			SourceServerID:      s.SourceServerID,
			PublicNetworkAccess: postgresql.PublicNetworkAccessEnum(azure.ToString(s.PublicNetworkAccess)),
			CreateMode:          postgresql.CreateModeGeoRestore,
			StorageProfile: &postgresql.StorageProfile{
				BackupRetentionDays: azure.ToInt32PtrFromIntPtr(s.StorageProfile.BackupRetentionDays),
				GeoRedundantBackup:  postgresql.GeoRedundantBackup(azure.ToString(s.StorageProfile.GeoRedundantBackup)),
				StorageMB:           azure.ToInt32Ptr(s.StorageProfile.StorageMB),
				StorageAutogrow:     postgresql.StorageAutogrow(azure.ToString(s.StorageProfile.StorageAutogrow)),
			},
		}
	case azuredbv1beta1.CreateModeReplica:
		return &postgresql.ServerPropertiesForReplica{
			MinimalTLSVersion:   postgresql.MinimalTLSVersionEnum(s.MinimalTLSVersion),
			Version:             postgresql.ServerVersion(s.Version),
			SslEnforcement:      postgresql.SslEnforcementEnum(s.SSLEnforcement),
			PublicNetworkAccess: postgresql.PublicNetworkAccessEnum(azure.ToString(s.PublicNetworkAccess)),
			CreateMode:          postgresql.CreateModeReplica,
			SourceServerID:      s.SourceServerID,
			StorageProfile: &postgresql.StorageProfile{
				BackupRetentionDays: azure.ToInt32PtrFromIntPtr(s.StorageProfile.BackupRetentionDays),
				GeoRedundantBackup:  postgresql.GeoRedundantBackup(azure.ToString(s.StorageProfile.GeoRedundantBackup)),
				StorageMB:           azure.ToInt32Ptr(s.StorageProfile.StorageMB),
				StorageAutogrow:     postgresql.StorageAutogrow(azure.ToString(s.StorageProfile.StorageAutogrow)),
			},
		}
	case azuredbv1beta1.CreateModeDefault:
		fallthrough
	default:
		return &postgresql.ServerPropertiesForDefaultCreate{
			MinimalTLSVersion:          postgresql.MinimalTLSVersionEnum(s.MinimalTLSVersion),
			AdministratorLogin:         azure.ToStringPtr(s.AdministratorLogin),
			AdministratorLoginPassword: &adminPassword,
			Version:                    postgresql.ServerVersion(s.Version),
			SslEnforcement:             postgresql.SslEnforcementEnum(s.SSLEnforcement),
			PublicNetworkAccess:        postgresql.PublicNetworkAccessEnum(azure.ToString(s.PublicNetworkAccess)),
			CreateMode:                 postgresql.CreateModeDefault,
			StorageProfile: &postgresql.StorageProfile{
				BackupRetentionDays: azure.ToInt32PtrFromIntPtr(s.StorageProfile.BackupRetentionDays),
				GeoRedundantBackup:  postgresql.GeoRedundantBackup(azure.ToString(s.StorageProfile.GeoRedundantBackup)),
				StorageMB:           azure.ToInt32Ptr(s.StorageProfile.StorageMB),
				StorageAutogrow:     postgresql.StorageAutogrow(azure.ToString(s.StorageProfile.StorageAutogrow)),
			},
		}
	}
}
func (c *PostgreSQLServerClient) CreateServer(ctx context.Context, cr *azuredbv1beta1.PostgreSQLServer, adminPassword string) error {
	s := cr.Spec.ForProvider
	sku, err := ToPostgreSQLSKU(s.SKU)
	if err != nil {
		return err
	}
	createParams := postgresql.ServerForCreate{
		Sku:        sku,
		Properties: toPGSQLProperties(s, adminPassword),
		Location:   &s.Location,
		Tags:       azure.ToStringPtrMap(s.Tags),
	}
	op, err := c.Create(ctx, s.ResourceGroupName, meta.GetExternalName(cr), createParams)
	if err != nil {
		return err
	}
	cr.Status.AtProvider.LastOperation = v1alpha3.AsyncOperation{
		PollingURL: op.PollingURL(),
		Method:     http.MethodPut,
	}
	return nil
}
func (c *PostgreSQLServerClient) UpdateServer(ctx context.Context, cr *azuredbv1beta1.PostgreSQLServer) error {
	s := cr.Spec.ForProvider
	properties := &postgresql.ServerUpdateParametersProperties{
		Version:             postgresql.ServerVersion(s.Version),
		MinimalTLSVersion:   postgresql.MinimalTLSVersionEnum(s.MinimalTLSVersion),
		SslEnforcement:      postgresql.SslEnforcementEnum(s.SSLEnforcement),
		PublicNetworkAccess: postgresql.PublicNetworkAccessEnum(azure.ToString(s.PublicNetworkAccess)),
		StorageProfile: &postgresql.StorageProfile{
			BackupRetentionDays: azure.ToInt32PtrFromIntPtr(s.StorageProfile.BackupRetentionDays),
			GeoRedundantBackup:  postgresql.GeoRedundantBackup(azure.ToString(s.StorageProfile.GeoRedundantBackup)),
			StorageMB:           azure.ToInt32Ptr(s.StorageProfile.StorageMB),
			StorageAutogrow:     postgresql.StorageAutogrow(azure.ToString(s.StorageProfile.StorageAutogrow)),
		},
	}
	sku, err := ToPostgreSQLSKU(s.SKU)
	if err != nil {
		return err
	}
	updateParams := postgresql.ServerUpdateParameters{
		Sku:                              sku,
		ServerUpdateParametersProperties: properties,
		Tags:                             azure.ToStringPtrMap(s.Tags),
	}
	op, err := c.Update(ctx, s.ResourceGroupName, meta.GetExternalName(cr), updateParams)
	if err != nil {
		return err
	}
	cr.Status.AtProvider.LastOperation = v1alpha3.AsyncOperation{
		PollingURL: op.PollingURL(),
		Method:     http.MethodPatch,
	}
	return nil
}
func (c *PostgreSQLServerClient) DeleteServer(ctx context.Context, cr *azuredbv1beta1.PostgreSQLServer) error {
	op, err := c.ServersClient.Delete(ctx, cr.Spec.ForProvider.ResourceGroupName, meta.GetExternalName(cr))
	if err != nil {
		return err
	}
	cr.Status.AtProvider.LastOperation = v1alpha3.AsyncOperation{
		PollingURL: op.PollingURL(),
		Method:     http.MethodDelete,
	}
	return nil
}
func NewPostgreSQLVirtualNetworkRuleParameters(v *azuredbv1alpha3.PostgreSQLServerVirtualNetworkRule) postgresql.VirtualNetworkRule {
	return postgresql.VirtualNetworkRule{
		Name: azure.ToStringPtr(meta.GetExternalName(v)),
		VirtualNetworkRuleProperties: &postgresql.VirtualNetworkRuleProperties{
			VirtualNetworkSubnetID:           azure.ToStringPtr(v.Spec.VirtualNetworkRuleProperties.VirtualNetworkSubnetID),
			IgnoreMissingVnetServiceEndpoint: azure.ToBoolPtr(v.Spec.VirtualNetworkRuleProperties.IgnoreMissingVnetServiceEndpoint, azure.FieldRequired),
		},
	}
}
func PostgreSQLServerVirtualNetworkRuleNeedsUpdate(kube *azuredbv1alpha3.PostgreSQLServerVirtualNetworkRule, az postgresql.VirtualNetworkRule) bool {
	up := NewPostgreSQLVirtualNetworkRuleParameters(kube)
	switch {
	case !reflect.DeepEqual(up.VirtualNetworkRuleProperties.VirtualNetworkSubnetID, az.VirtualNetworkRuleProperties.VirtualNetworkSubnetID):
		return true
	case !reflect.DeepEqual(up.VirtualNetworkRuleProperties.IgnoreMissingVnetServiceEndpoint, az.VirtualNetworkRuleProperties.IgnoreMissingVnetServiceEndpoint):
		return true
	}
	return false
}
func UpdatePostgreSQLVirtualNetworkRuleStatusFromAzure(v *azuredbv1alpha3.PostgreSQLServerVirtualNetworkRule, az postgresql.VirtualNetworkRule) {
	v.Status.State = string(az.VirtualNetworkRuleProperties.State)
	v.Status.ID = azure.ToString(az.ID)
	v.Status.Type = azure.ToString(az.Type)
}
func NewPostgreSQLFirewallRuleParameters(r *azuredbv1alpha3.PostgreSQLServerFirewallRule) postgresql.FirewallRule {
	return postgresql.FirewallRule{
		Name: azure.ToStringPtr(meta.GetExternalName(r)),
		FirewallRuleProperties: &postgresql.FirewallRuleProperties{
			StartIPAddress: azure.ToStringPtr(r.Spec.ForProvider.StartIPAddress),
			EndIPAddress:   azure.ToStringPtr(r.Spec.ForProvider.EndIPAddress),
		},
	}
}
func PostgreSQLServerFirewallRuleIsUpToDate(kube *azuredbv1alpha3.PostgreSQLServerFirewallRule, az postgresql.FirewallRule) bool {
	up := NewPostgreSQLFirewallRuleParameters(kube)
	return cmp.Equal(up.FirewallRuleProperties, az.FirewallRuleProperties)
}
func ToPostgreSQLSKU(skuSpec azuredbv1beta1.SKU) (*postgresql.Sku, error) {
	t, ok := skuShortTiers[mysql.SkuTier(skuSpec.Tier)]
	if !ok {
		return nil, fmt.Errorf("tier '%s' is not one of the supported values: %+v", skuSpec.Tier, mysql.PossibleSkuTierValues())
	}
	return &postgresql.Sku{
		Name:     azure.ToStringPtr(fmt.Sprintf("%s_%s_%s", t, skuSpec.Family, strconv.Itoa(skuSpec.Capacity))),
		Tier:     postgresql.SkuTier(skuSpec.Tier),
		Capacity: azure.ToInt32Ptr(skuSpec.Capacity),
		Family:   azure.ToStringPtr(skuSpec.Family),
		Size:     skuSpec.Size,
	}, nil
}
func UpdatePostgreSQLObservation(o *azuredbv1beta1.SQLServerObservation, in postgresql.Server) {
	o.ID = azure.ToString(in.ID)
	o.Name = azure.ToString(in.Name)
	o.Type = azure.ToString(in.Type)
	o.UserVisibleState = string(in.UserVisibleState)
	o.FullyQualifiedDomainName = azure.ToString(in.FullyQualifiedDomainName)
	o.MasterServerID = azure.ToString(in.MasterServerID)
}