//go:build go1.18
// +build go1.18

// 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. DO NOT EDIT.
// Changes may cause incorrect behavior and will be lost if the code is regenerated.

package fake

import (
	"errors"
	"fmt"
	"github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime"
	"net/http"
	"strings"
	"sync"
)

// ServerFactory is a fake server for instances of the armmariadb.ClientFactory type.
type ServerFactory struct {
	AdvisorsServer                                              AdvisorsServer
	CheckNameAvailabilityServer                                 CheckNameAvailabilityServer
	ConfigurationsServer                                        ConfigurationsServer
	DatabasesServer                                             DatabasesServer
	FirewallRulesServer                                         FirewallRulesServer
	LocationBasedPerformanceTierServer                          LocationBasedPerformanceTierServer
	LocationBasedRecommendedActionSessionsOperationStatusServer LocationBasedRecommendedActionSessionsOperationStatusServer
	LocationBasedRecommendedActionSessionsResultServer          LocationBasedRecommendedActionSessionsResultServer
	LogFilesServer                                              LogFilesServer
	ManagementServer                                            ManagementServer
	OperationsServer                                            OperationsServer
	PrivateEndpointConnectionsServer                            PrivateEndpointConnectionsServer
	PrivateLinkResourcesServer                                  PrivateLinkResourcesServer
	QueryTextsServer                                            QueryTextsServer
	RecommendedActionsServer                                    RecommendedActionsServer
	RecoverableServersServer                                    RecoverableServersServer
	ReplicasServer                                              ReplicasServer
	ServerBasedPerformanceTierServer                            ServerBasedPerformanceTierServer
	ServerParametersServer                                      ServerParametersServer
	ServerSecurityAlertPoliciesServer                           ServerSecurityAlertPoliciesServer
	ServersServer                                               ServersServer
	TopQueryStatisticsServer                                    TopQueryStatisticsServer
	VirtualNetworkRulesServer                                   VirtualNetworkRulesServer
	WaitStatisticsServer                                        WaitStatisticsServer
}

// NewServerFactoryTransport creates a new instance of ServerFactoryTransport with the provided implementation.
// The returned ServerFactoryTransport instance is connected to an instance of armmariadb.ClientFactory via the
// azcore.ClientOptions.Transporter field in the client's constructor parameters.
func NewServerFactoryTransport(srv *ServerFactory) *ServerFactoryTransport {
	return &ServerFactoryTransport{
		srv: srv,
	}
}

// ServerFactoryTransport connects instances of armmariadb.ClientFactory to instances of ServerFactory.
// Don't use this type directly, use NewServerFactoryTransport instead.
type ServerFactoryTransport struct {
	srv                                                           *ServerFactory
	trMu                                                          sync.Mutex
	trAdvisorsServer                                              *AdvisorsServerTransport
	trCheckNameAvailabilityServer                                 *CheckNameAvailabilityServerTransport
	trConfigurationsServer                                        *ConfigurationsServerTransport
	trDatabasesServer                                             *DatabasesServerTransport
	trFirewallRulesServer                                         *FirewallRulesServerTransport
	trLocationBasedPerformanceTierServer                          *LocationBasedPerformanceTierServerTransport
	trLocationBasedRecommendedActionSessionsOperationStatusServer *LocationBasedRecommendedActionSessionsOperationStatusServerTransport
	trLocationBasedRecommendedActionSessionsResultServer          *LocationBasedRecommendedActionSessionsResultServerTransport
	trLogFilesServer                                              *LogFilesServerTransport
	trManagementServer                                            *ManagementServerTransport
	trOperationsServer                                            *OperationsServerTransport
	trPrivateEndpointConnectionsServer                            *PrivateEndpointConnectionsServerTransport
	trPrivateLinkResourcesServer                                  *PrivateLinkResourcesServerTransport
	trQueryTextsServer                                            *QueryTextsServerTransport
	trRecommendedActionsServer                                    *RecommendedActionsServerTransport
	trRecoverableServersServer                                    *RecoverableServersServerTransport
	trReplicasServer                                              *ReplicasServerTransport
	trServerBasedPerformanceTierServer                            *ServerBasedPerformanceTierServerTransport
	trServerParametersServer                                      *ServerParametersServerTransport
	trServerSecurityAlertPoliciesServer                           *ServerSecurityAlertPoliciesServerTransport
	trServersServer                                               *ServersServerTransport
	trTopQueryStatisticsServer                                    *TopQueryStatisticsServerTransport
	trVirtualNetworkRulesServer                                   *VirtualNetworkRulesServerTransport
	trWaitStatisticsServer                                        *WaitStatisticsServerTransport
}

// Do implements the policy.Transporter interface for ServerFactoryTransport.
func (s *ServerFactoryTransport) Do(req *http.Request) (*http.Response, error) {
	rawMethod := req.Context().Value(runtime.CtxAPINameKey{})
	method, ok := rawMethod.(string)
	if !ok {
		return nil, nonRetriableError{errors.New("unable to dispatch request, missing value for CtxAPINameKey")}
	}

	client := method[:strings.Index(method, ".")]
	var resp *http.Response
	var err error

	switch client {
	case "AdvisorsClient":
		initServer(s, &s.trAdvisorsServer, func() *AdvisorsServerTransport { return NewAdvisorsServerTransport(&s.srv.AdvisorsServer) })
		resp, err = s.trAdvisorsServer.Do(req)
	case "CheckNameAvailabilityClient":
		initServer(s, &s.trCheckNameAvailabilityServer, func() *CheckNameAvailabilityServerTransport {
			return NewCheckNameAvailabilityServerTransport(&s.srv.CheckNameAvailabilityServer)
		})
		resp, err = s.trCheckNameAvailabilityServer.Do(req)
	case "ConfigurationsClient":
		initServer(s, &s.trConfigurationsServer, func() *ConfigurationsServerTransport {
			return NewConfigurationsServerTransport(&s.srv.ConfigurationsServer)
		})
		resp, err = s.trConfigurationsServer.Do(req)
	case "DatabasesClient":
		initServer(s, &s.trDatabasesServer, func() *DatabasesServerTransport { return NewDatabasesServerTransport(&s.srv.DatabasesServer) })
		resp, err = s.trDatabasesServer.Do(req)
	case "FirewallRulesClient":
		initServer(s, &s.trFirewallRulesServer, func() *FirewallRulesServerTransport {
			return NewFirewallRulesServerTransport(&s.srv.FirewallRulesServer)
		})
		resp, err = s.trFirewallRulesServer.Do(req)
	case "LocationBasedPerformanceTierClient":
		initServer(s, &s.trLocationBasedPerformanceTierServer, func() *LocationBasedPerformanceTierServerTransport {
			return NewLocationBasedPerformanceTierServerTransport(&s.srv.LocationBasedPerformanceTierServer)
		})
		resp, err = s.trLocationBasedPerformanceTierServer.Do(req)
	case "LocationBasedRecommendedActionSessionsOperationStatusClient":
		initServer(s, &s.trLocationBasedRecommendedActionSessionsOperationStatusServer, func() *LocationBasedRecommendedActionSessionsOperationStatusServerTransport {
			return NewLocationBasedRecommendedActionSessionsOperationStatusServerTransport(&s.srv.LocationBasedRecommendedActionSessionsOperationStatusServer)
		})
		resp, err = s.trLocationBasedRecommendedActionSessionsOperationStatusServer.Do(req)
	case "LocationBasedRecommendedActionSessionsResultClient":
		initServer(s, &s.trLocationBasedRecommendedActionSessionsResultServer, func() *LocationBasedRecommendedActionSessionsResultServerTransport {
			return NewLocationBasedRecommendedActionSessionsResultServerTransport(&s.srv.LocationBasedRecommendedActionSessionsResultServer)
		})
		resp, err = s.trLocationBasedRecommendedActionSessionsResultServer.Do(req)
	case "LogFilesClient":
		initServer(s, &s.trLogFilesServer, func() *LogFilesServerTransport { return NewLogFilesServerTransport(&s.srv.LogFilesServer) })
		resp, err = s.trLogFilesServer.Do(req)
	case "ManagementClient":
		initServer(s, &s.trManagementServer, func() *ManagementServerTransport { return NewManagementServerTransport(&s.srv.ManagementServer) })
		resp, err = s.trManagementServer.Do(req)
	case "OperationsClient":
		initServer(s, &s.trOperationsServer, func() *OperationsServerTransport { return NewOperationsServerTransport(&s.srv.OperationsServer) })
		resp, err = s.trOperationsServer.Do(req)
	case "PrivateEndpointConnectionsClient":
		initServer(s, &s.trPrivateEndpointConnectionsServer, func() *PrivateEndpointConnectionsServerTransport {
			return NewPrivateEndpointConnectionsServerTransport(&s.srv.PrivateEndpointConnectionsServer)
		})
		resp, err = s.trPrivateEndpointConnectionsServer.Do(req)
	case "PrivateLinkResourcesClient":
		initServer(s, &s.trPrivateLinkResourcesServer, func() *PrivateLinkResourcesServerTransport {
			return NewPrivateLinkResourcesServerTransport(&s.srv.PrivateLinkResourcesServer)
		})
		resp, err = s.trPrivateLinkResourcesServer.Do(req)
	case "QueryTextsClient":
		initServer(s, &s.trQueryTextsServer, func() *QueryTextsServerTransport { return NewQueryTextsServerTransport(&s.srv.QueryTextsServer) })
		resp, err = s.trQueryTextsServer.Do(req)
	case "RecommendedActionsClient":
		initServer(s, &s.trRecommendedActionsServer, func() *RecommendedActionsServerTransport {
			return NewRecommendedActionsServerTransport(&s.srv.RecommendedActionsServer)
		})
		resp, err = s.trRecommendedActionsServer.Do(req)
	case "RecoverableServersClient":
		initServer(s, &s.trRecoverableServersServer, func() *RecoverableServersServerTransport {
			return NewRecoverableServersServerTransport(&s.srv.RecoverableServersServer)
		})
		resp, err = s.trRecoverableServersServer.Do(req)
	case "ReplicasClient":
		initServer(s, &s.trReplicasServer, func() *ReplicasServerTransport { return NewReplicasServerTransport(&s.srv.ReplicasServer) })
		resp, err = s.trReplicasServer.Do(req)
	case "ServerBasedPerformanceTierClient":
		initServer(s, &s.trServerBasedPerformanceTierServer, func() *ServerBasedPerformanceTierServerTransport {
			return NewServerBasedPerformanceTierServerTransport(&s.srv.ServerBasedPerformanceTierServer)
		})
		resp, err = s.trServerBasedPerformanceTierServer.Do(req)
	case "ServerParametersClient":
		initServer(s, &s.trServerParametersServer, func() *ServerParametersServerTransport {
			return NewServerParametersServerTransport(&s.srv.ServerParametersServer)
		})
		resp, err = s.trServerParametersServer.Do(req)
	case "ServerSecurityAlertPoliciesClient":
		initServer(s, &s.trServerSecurityAlertPoliciesServer, func() *ServerSecurityAlertPoliciesServerTransport {
			return NewServerSecurityAlertPoliciesServerTransport(&s.srv.ServerSecurityAlertPoliciesServer)
		})
		resp, err = s.trServerSecurityAlertPoliciesServer.Do(req)
	case "ServersClient":
		initServer(s, &s.trServersServer, func() *ServersServerTransport { return NewServersServerTransport(&s.srv.ServersServer) })
		resp, err = s.trServersServer.Do(req)
	case "TopQueryStatisticsClient":
		initServer(s, &s.trTopQueryStatisticsServer, func() *TopQueryStatisticsServerTransport {
			return NewTopQueryStatisticsServerTransport(&s.srv.TopQueryStatisticsServer)
		})
		resp, err = s.trTopQueryStatisticsServer.Do(req)
	case "VirtualNetworkRulesClient":
		initServer(s, &s.trVirtualNetworkRulesServer, func() *VirtualNetworkRulesServerTransport {
			return NewVirtualNetworkRulesServerTransport(&s.srv.VirtualNetworkRulesServer)
		})
		resp, err = s.trVirtualNetworkRulesServer.Do(req)
	case "WaitStatisticsClient":
		initServer(s, &s.trWaitStatisticsServer, func() *WaitStatisticsServerTransport {
			return NewWaitStatisticsServerTransport(&s.srv.WaitStatisticsServer)
		})
		resp, err = s.trWaitStatisticsServer.Do(req)
	default:
		err = fmt.Errorf("unhandled client %s", client)
	}

	if err != nil {
		return nil, err
	}

	return resp, nil
}

func initServer[T any](s *ServerFactoryTransport, dst **T, src func() *T) {
	s.trMu.Lock()
	if *dst == nil {
		*dst = src()
	}
	s.trMu.Unlock()
}
