//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 armautomation.ClientFactory type.
type ServerFactory struct {
	AccountServer                                AccountServer
	ActivityServer                               ActivityServer
	AgentRegistrationInformationServer           AgentRegistrationInformationServer
	CertificateServer                            CertificateServer
	Server                                       Server
	ConnectionServer                             ConnectionServer
	ConnectionTypeServer                         ConnectionTypeServer
	CredentialServer                             CredentialServer
	DeletedAutomationAccountsServer              DeletedAutomationAccountsServer
	DscCompilationJobServer                      DscCompilationJobServer
	DscCompilationJobStreamServer                DscCompilationJobStreamServer
	DscConfigurationServer                       DscConfigurationServer
	DscNodeServer                                DscNodeServer
	DscNodeConfigurationServer                   DscNodeConfigurationServer
	FieldsServer                                 FieldsServer
	HybridRunbookWorkerGroupServer               HybridRunbookWorkerGroupServer
	HybridRunbookWorkersServer                   HybridRunbookWorkersServer
	JobServer                                    JobServer
	JobScheduleServer                            JobScheduleServer
	JobStreamServer                              JobStreamServer
	KeysServer                                   KeysServer
	LinkedWorkspaceServer                        LinkedWorkspaceServer
	ModuleServer                                 ModuleServer
	NodeCountInformationServer                   NodeCountInformationServer
	NodeReportsServer                            NodeReportsServer
	ObjectDataTypesServer                        ObjectDataTypesServer
	OperationsServer                             OperationsServer
	PrivateEndpointConnectionsServer             PrivateEndpointConnectionsServer
	PrivateLinkResourcesServer                   PrivateLinkResourcesServer
	Python2PackageServer                         Python2PackageServer
	RunbookServer                                RunbookServer
	RunbookDraftServer                           RunbookDraftServer
	ScheduleServer                               ScheduleServer
	SoftwareUpdateConfigurationMachineRunsServer SoftwareUpdateConfigurationMachineRunsServer
	SoftwareUpdateConfigurationRunsServer        SoftwareUpdateConfigurationRunsServer
	SoftwareUpdateConfigurationsServer           SoftwareUpdateConfigurationsServer
	SourceControlServer                          SourceControlServer
	SourceControlSyncJobServer                   SourceControlSyncJobServer
	SourceControlSyncJobStreamsServer            SourceControlSyncJobStreamsServer
	StatisticsServer                             StatisticsServer
	TestJobServer                                TestJobServer
	TestJobStreamsServer                         TestJobStreamsServer
	UsagesServer                                 UsagesServer
	VariableServer                               VariableServer
	WatcherServer                                WatcherServer
	WebhookServer                                WebhookServer
}

// NewServerFactoryTransport creates a new instance of ServerFactoryTransport with the provided implementation.
// The returned ServerFactoryTransport instance is connected to an instance of armautomation.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 armautomation.ClientFactory to instances of ServerFactory.
// Don't use this type directly, use NewServerFactoryTransport instead.
type ServerFactoryTransport struct {
	srv                                            *ServerFactory
	trMu                                           sync.Mutex
	trAccountServer                                *AccountServerTransport
	trActivityServer                               *ActivityServerTransport
	trAgentRegistrationInformationServer           *AgentRegistrationInformationServerTransport
	trCertificateServer                            *CertificateServerTransport
	trServer                                       *ServerTransport
	trConnectionServer                             *ConnectionServerTransport
	trConnectionTypeServer                         *ConnectionTypeServerTransport
	trCredentialServer                             *CredentialServerTransport
	trDeletedAutomationAccountsServer              *DeletedAutomationAccountsServerTransport
	trDscCompilationJobServer                      *DscCompilationJobServerTransport
	trDscCompilationJobStreamServer                *DscCompilationJobStreamServerTransport
	trDscConfigurationServer                       *DscConfigurationServerTransport
	trDscNodeServer                                *DscNodeServerTransport
	trDscNodeConfigurationServer                   *DscNodeConfigurationServerTransport
	trFieldsServer                                 *FieldsServerTransport
	trHybridRunbookWorkerGroupServer               *HybridRunbookWorkerGroupServerTransport
	trHybridRunbookWorkersServer                   *HybridRunbookWorkersServerTransport
	trJobServer                                    *JobServerTransport
	trJobScheduleServer                            *JobScheduleServerTransport
	trJobStreamServer                              *JobStreamServerTransport
	trKeysServer                                   *KeysServerTransport
	trLinkedWorkspaceServer                        *LinkedWorkspaceServerTransport
	trModuleServer                                 *ModuleServerTransport
	trNodeCountInformationServer                   *NodeCountInformationServerTransport
	trNodeReportsServer                            *NodeReportsServerTransport
	trObjectDataTypesServer                        *ObjectDataTypesServerTransport
	trOperationsServer                             *OperationsServerTransport
	trPrivateEndpointConnectionsServer             *PrivateEndpointConnectionsServerTransport
	trPrivateLinkResourcesServer                   *PrivateLinkResourcesServerTransport
	trPython2PackageServer                         *Python2PackageServerTransport
	trRunbookServer                                *RunbookServerTransport
	trRunbookDraftServer                           *RunbookDraftServerTransport
	trScheduleServer                               *ScheduleServerTransport
	trSoftwareUpdateConfigurationMachineRunsServer *SoftwareUpdateConfigurationMachineRunsServerTransport
	trSoftwareUpdateConfigurationRunsServer        *SoftwareUpdateConfigurationRunsServerTransport
	trSoftwareUpdateConfigurationsServer           *SoftwareUpdateConfigurationsServerTransport
	trSourceControlServer                          *SourceControlServerTransport
	trSourceControlSyncJobServer                   *SourceControlSyncJobServerTransport
	trSourceControlSyncJobStreamsServer            *SourceControlSyncJobStreamsServerTransport
	trStatisticsServer                             *StatisticsServerTransport
	trTestJobServer                                *TestJobServerTransport
	trTestJobStreamsServer                         *TestJobStreamsServerTransport
	trUsagesServer                                 *UsagesServerTransport
	trVariableServer                               *VariableServerTransport
	trWatcherServer                                *WatcherServerTransport
	trWebhookServer                                *WebhookServerTransport
}

// 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 "AccountClient":
		initServer(s, &s.trAccountServer, func() *AccountServerTransport { return NewAccountServerTransport(&s.srv.AccountServer) })
		resp, err = s.trAccountServer.Do(req)
	case "ActivityClient":
		initServer(s, &s.trActivityServer, func() *ActivityServerTransport { return NewActivityServerTransport(&s.srv.ActivityServer) })
		resp, err = s.trActivityServer.Do(req)
	case "AgentRegistrationInformationClient":
		initServer(s, &s.trAgentRegistrationInformationServer, func() *AgentRegistrationInformationServerTransport {
			return NewAgentRegistrationInformationServerTransport(&s.srv.AgentRegistrationInformationServer)
		})
		resp, err = s.trAgentRegistrationInformationServer.Do(req)
	case "CertificateClient":
		initServer(s, &s.trCertificateServer, func() *CertificateServerTransport { return NewCertificateServerTransport(&s.srv.CertificateServer) })
		resp, err = s.trCertificateServer.Do(req)
	case "Client":
		initServer(s, &s.trServer, func() *ServerTransport { return NewServerTransport(&s.srv.Server) })
		resp, err = s.trServer.Do(req)
	case "ConnectionClient":
		initServer(s, &s.trConnectionServer, func() *ConnectionServerTransport { return NewConnectionServerTransport(&s.srv.ConnectionServer) })
		resp, err = s.trConnectionServer.Do(req)
	case "ConnectionTypeClient":
		initServer(s, &s.trConnectionTypeServer, func() *ConnectionTypeServerTransport {
			return NewConnectionTypeServerTransport(&s.srv.ConnectionTypeServer)
		})
		resp, err = s.trConnectionTypeServer.Do(req)
	case "CredentialClient":
		initServer(s, &s.trCredentialServer, func() *CredentialServerTransport { return NewCredentialServerTransport(&s.srv.CredentialServer) })
		resp, err = s.trCredentialServer.Do(req)
	case "DeletedAutomationAccountsClient":
		initServer(s, &s.trDeletedAutomationAccountsServer, func() *DeletedAutomationAccountsServerTransport {
			return NewDeletedAutomationAccountsServerTransport(&s.srv.DeletedAutomationAccountsServer)
		})
		resp, err = s.trDeletedAutomationAccountsServer.Do(req)
	case "DscCompilationJobClient":
		initServer(s, &s.trDscCompilationJobServer, func() *DscCompilationJobServerTransport {
			return NewDscCompilationJobServerTransport(&s.srv.DscCompilationJobServer)
		})
		resp, err = s.trDscCompilationJobServer.Do(req)
	case "DscCompilationJobStreamClient":
		initServer(s, &s.trDscCompilationJobStreamServer, func() *DscCompilationJobStreamServerTransport {
			return NewDscCompilationJobStreamServerTransport(&s.srv.DscCompilationJobStreamServer)
		})
		resp, err = s.trDscCompilationJobStreamServer.Do(req)
	case "DscConfigurationClient":
		initServer(s, &s.trDscConfigurationServer, func() *DscConfigurationServerTransport {
			return NewDscConfigurationServerTransport(&s.srv.DscConfigurationServer)
		})
		resp, err = s.trDscConfigurationServer.Do(req)
	case "DscNodeClient":
		initServer(s, &s.trDscNodeServer, func() *DscNodeServerTransport { return NewDscNodeServerTransport(&s.srv.DscNodeServer) })
		resp, err = s.trDscNodeServer.Do(req)
	case "DscNodeConfigurationClient":
		initServer(s, &s.trDscNodeConfigurationServer, func() *DscNodeConfigurationServerTransport {
			return NewDscNodeConfigurationServerTransport(&s.srv.DscNodeConfigurationServer)
		})
		resp, err = s.trDscNodeConfigurationServer.Do(req)
	case "FieldsClient":
		initServer(s, &s.trFieldsServer, func() *FieldsServerTransport { return NewFieldsServerTransport(&s.srv.FieldsServer) })
		resp, err = s.trFieldsServer.Do(req)
	case "HybridRunbookWorkerGroupClient":
		initServer(s, &s.trHybridRunbookWorkerGroupServer, func() *HybridRunbookWorkerGroupServerTransport {
			return NewHybridRunbookWorkerGroupServerTransport(&s.srv.HybridRunbookWorkerGroupServer)
		})
		resp, err = s.trHybridRunbookWorkerGroupServer.Do(req)
	case "HybridRunbookWorkersClient":
		initServer(s, &s.trHybridRunbookWorkersServer, func() *HybridRunbookWorkersServerTransport {
			return NewHybridRunbookWorkersServerTransport(&s.srv.HybridRunbookWorkersServer)
		})
		resp, err = s.trHybridRunbookWorkersServer.Do(req)
	case "JobClient":
		initServer(s, &s.trJobServer, func() *JobServerTransport { return NewJobServerTransport(&s.srv.JobServer) })
		resp, err = s.trJobServer.Do(req)
	case "JobScheduleClient":
		initServer(s, &s.trJobScheduleServer, func() *JobScheduleServerTransport { return NewJobScheduleServerTransport(&s.srv.JobScheduleServer) })
		resp, err = s.trJobScheduleServer.Do(req)
	case "JobStreamClient":
		initServer(s, &s.trJobStreamServer, func() *JobStreamServerTransport { return NewJobStreamServerTransport(&s.srv.JobStreamServer) })
		resp, err = s.trJobStreamServer.Do(req)
	case "KeysClient":
		initServer(s, &s.trKeysServer, func() *KeysServerTransport { return NewKeysServerTransport(&s.srv.KeysServer) })
		resp, err = s.trKeysServer.Do(req)
	case "LinkedWorkspaceClient":
		initServer(s, &s.trLinkedWorkspaceServer, func() *LinkedWorkspaceServerTransport {
			return NewLinkedWorkspaceServerTransport(&s.srv.LinkedWorkspaceServer)
		})
		resp, err = s.trLinkedWorkspaceServer.Do(req)
	case "ModuleClient":
		initServer(s, &s.trModuleServer, func() *ModuleServerTransport { return NewModuleServerTransport(&s.srv.ModuleServer) })
		resp, err = s.trModuleServer.Do(req)
	case "NodeCountInformationClient":
		initServer(s, &s.trNodeCountInformationServer, func() *NodeCountInformationServerTransport {
			return NewNodeCountInformationServerTransport(&s.srv.NodeCountInformationServer)
		})
		resp, err = s.trNodeCountInformationServer.Do(req)
	case "NodeReportsClient":
		initServer(s, &s.trNodeReportsServer, func() *NodeReportsServerTransport { return NewNodeReportsServerTransport(&s.srv.NodeReportsServer) })
		resp, err = s.trNodeReportsServer.Do(req)
	case "ObjectDataTypesClient":
		initServer(s, &s.trObjectDataTypesServer, func() *ObjectDataTypesServerTransport {
			return NewObjectDataTypesServerTransport(&s.srv.ObjectDataTypesServer)
		})
		resp, err = s.trObjectDataTypesServer.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 "Python2PackageClient":
		initServer(s, &s.trPython2PackageServer, func() *Python2PackageServerTransport {
			return NewPython2PackageServerTransport(&s.srv.Python2PackageServer)
		})
		resp, err = s.trPython2PackageServer.Do(req)
	case "RunbookClient":
		initServer(s, &s.trRunbookServer, func() *RunbookServerTransport { return NewRunbookServerTransport(&s.srv.RunbookServer) })
		resp, err = s.trRunbookServer.Do(req)
	case "RunbookDraftClient":
		initServer(s, &s.trRunbookDraftServer, func() *RunbookDraftServerTransport { return NewRunbookDraftServerTransport(&s.srv.RunbookDraftServer) })
		resp, err = s.trRunbookDraftServer.Do(req)
	case "ScheduleClient":
		initServer(s, &s.trScheduleServer, func() *ScheduleServerTransport { return NewScheduleServerTransport(&s.srv.ScheduleServer) })
		resp, err = s.trScheduleServer.Do(req)
	case "SoftwareUpdateConfigurationMachineRunsClient":
		initServer(s, &s.trSoftwareUpdateConfigurationMachineRunsServer, func() *SoftwareUpdateConfigurationMachineRunsServerTransport {
			return NewSoftwareUpdateConfigurationMachineRunsServerTransport(&s.srv.SoftwareUpdateConfigurationMachineRunsServer)
		})
		resp, err = s.trSoftwareUpdateConfigurationMachineRunsServer.Do(req)
	case "SoftwareUpdateConfigurationRunsClient":
		initServer(s, &s.trSoftwareUpdateConfigurationRunsServer, func() *SoftwareUpdateConfigurationRunsServerTransport {
			return NewSoftwareUpdateConfigurationRunsServerTransport(&s.srv.SoftwareUpdateConfigurationRunsServer)
		})
		resp, err = s.trSoftwareUpdateConfigurationRunsServer.Do(req)
	case "SoftwareUpdateConfigurationsClient":
		initServer(s, &s.trSoftwareUpdateConfigurationsServer, func() *SoftwareUpdateConfigurationsServerTransport {
			return NewSoftwareUpdateConfigurationsServerTransport(&s.srv.SoftwareUpdateConfigurationsServer)
		})
		resp, err = s.trSoftwareUpdateConfigurationsServer.Do(req)
	case "SourceControlClient":
		initServer(s, &s.trSourceControlServer, func() *SourceControlServerTransport {
			return NewSourceControlServerTransport(&s.srv.SourceControlServer)
		})
		resp, err = s.trSourceControlServer.Do(req)
	case "SourceControlSyncJobClient":
		initServer(s, &s.trSourceControlSyncJobServer, func() *SourceControlSyncJobServerTransport {
			return NewSourceControlSyncJobServerTransport(&s.srv.SourceControlSyncJobServer)
		})
		resp, err = s.trSourceControlSyncJobServer.Do(req)
	case "SourceControlSyncJobStreamsClient":
		initServer(s, &s.trSourceControlSyncJobStreamsServer, func() *SourceControlSyncJobStreamsServerTransport {
			return NewSourceControlSyncJobStreamsServerTransport(&s.srv.SourceControlSyncJobStreamsServer)
		})
		resp, err = s.trSourceControlSyncJobStreamsServer.Do(req)
	case "StatisticsClient":
		initServer(s, &s.trStatisticsServer, func() *StatisticsServerTransport { return NewStatisticsServerTransport(&s.srv.StatisticsServer) })
		resp, err = s.trStatisticsServer.Do(req)
	case "TestJobClient":
		initServer(s, &s.trTestJobServer, func() *TestJobServerTransport { return NewTestJobServerTransport(&s.srv.TestJobServer) })
		resp, err = s.trTestJobServer.Do(req)
	case "TestJobStreamsClient":
		initServer(s, &s.trTestJobStreamsServer, func() *TestJobStreamsServerTransport {
			return NewTestJobStreamsServerTransport(&s.srv.TestJobStreamsServer)
		})
		resp, err = s.trTestJobStreamsServer.Do(req)
	case "UsagesClient":
		initServer(s, &s.trUsagesServer, func() *UsagesServerTransport { return NewUsagesServerTransport(&s.srv.UsagesServer) })
		resp, err = s.trUsagesServer.Do(req)
	case "VariableClient":
		initServer(s, &s.trVariableServer, func() *VariableServerTransport { return NewVariableServerTransport(&s.srv.VariableServer) })
		resp, err = s.trVariableServer.Do(req)
	case "WatcherClient":
		initServer(s, &s.trWatcherServer, func() *WatcherServerTransport { return NewWatcherServerTransport(&s.srv.WatcherServer) })
		resp, err = s.trWatcherServer.Do(req)
	case "WebhookClient":
		initServer(s, &s.trWebhookServer, func() *WebhookServerTransport { return NewWebhookServerTransport(&s.srv.WebhookServer) })
		resp, err = s.trWebhookServer.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()
}
