// 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 armdatafactory.ClientFactory type.
type ServerFactory struct {
	// ActivityRunsServer contains the fakes for client ActivityRunsClient
	ActivityRunsServer ActivityRunsServer

	// ChangeDataCaptureServer contains the fakes for client ChangeDataCaptureClient
	ChangeDataCaptureServer ChangeDataCaptureServer

	// CredentialOperationsServer contains the fakes for client CredentialOperationsClient
	CredentialOperationsServer CredentialOperationsServer

	// DataFlowDebugSessionServer contains the fakes for client DataFlowDebugSessionClient
	DataFlowDebugSessionServer DataFlowDebugSessionServer

	// DataFlowsServer contains the fakes for client DataFlowsClient
	DataFlowsServer DataFlowsServer

	// DatasetsServer contains the fakes for client DatasetsClient
	DatasetsServer DatasetsServer

	// ExposureControlServer contains the fakes for client ExposureControlClient
	ExposureControlServer ExposureControlServer

	// FactoriesServer contains the fakes for client FactoriesClient
	FactoriesServer FactoriesServer

	// GlobalParametersServer contains the fakes for client GlobalParametersClient
	GlobalParametersServer GlobalParametersServer

	// IntegrationRuntimeNodesServer contains the fakes for client IntegrationRuntimeNodesClient
	IntegrationRuntimeNodesServer IntegrationRuntimeNodesServer

	// IntegrationRuntimeObjectMetadataServer contains the fakes for client IntegrationRuntimeObjectMetadataClient
	IntegrationRuntimeObjectMetadataServer IntegrationRuntimeObjectMetadataServer

	// IntegrationRuntimesServer contains the fakes for client IntegrationRuntimesClient
	IntegrationRuntimesServer IntegrationRuntimesServer

	// LinkedServicesServer contains the fakes for client LinkedServicesClient
	LinkedServicesServer LinkedServicesServer

	// ManagedPrivateEndpointsServer contains the fakes for client ManagedPrivateEndpointsClient
	ManagedPrivateEndpointsServer ManagedPrivateEndpointsServer

	// ManagedVirtualNetworksServer contains the fakes for client ManagedVirtualNetworksClient
	ManagedVirtualNetworksServer ManagedVirtualNetworksServer

	// OperationsServer contains the fakes for client OperationsClient
	OperationsServer OperationsServer

	// PipelineRunsServer contains the fakes for client PipelineRunsClient
	PipelineRunsServer PipelineRunsServer

	// PipelinesServer contains the fakes for client PipelinesClient
	PipelinesServer PipelinesServer

	// PrivateEndPointConnectionsServer contains the fakes for client PrivateEndPointConnectionsClient
	PrivateEndPointConnectionsServer PrivateEndPointConnectionsServer

	// PrivateEndpointConnectionServer contains the fakes for client PrivateEndpointConnectionClient
	PrivateEndpointConnectionServer PrivateEndpointConnectionServer

	// PrivateLinkResourcesServer contains the fakes for client PrivateLinkResourcesClient
	PrivateLinkResourcesServer PrivateLinkResourcesServer

	// TriggerRunsServer contains the fakes for client TriggerRunsClient
	TriggerRunsServer TriggerRunsServer

	// TriggersServer contains the fakes for client TriggersClient
	TriggersServer TriggersServer
}

// NewServerFactoryTransport creates a new instance of ServerFactoryTransport with the provided implementation.
// The returned ServerFactoryTransport instance is connected to an instance of armdatafactory.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 armdatafactory.ClientFactory to instances of ServerFactory.
// Don't use this type directly, use NewServerFactoryTransport instead.
type ServerFactoryTransport struct {
	srv                                      *ServerFactory
	trMu                                     sync.Mutex
	trActivityRunsServer                     *ActivityRunsServerTransport
	trChangeDataCaptureServer                *ChangeDataCaptureServerTransport
	trCredentialOperationsServer             *CredentialOperationsServerTransport
	trDataFlowDebugSessionServer             *DataFlowDebugSessionServerTransport
	trDataFlowsServer                        *DataFlowsServerTransport
	trDatasetsServer                         *DatasetsServerTransport
	trExposureControlServer                  *ExposureControlServerTransport
	trFactoriesServer                        *FactoriesServerTransport
	trGlobalParametersServer                 *GlobalParametersServerTransport
	trIntegrationRuntimeNodesServer          *IntegrationRuntimeNodesServerTransport
	trIntegrationRuntimeObjectMetadataServer *IntegrationRuntimeObjectMetadataServerTransport
	trIntegrationRuntimesServer              *IntegrationRuntimesServerTransport
	trLinkedServicesServer                   *LinkedServicesServerTransport
	trManagedPrivateEndpointsServer          *ManagedPrivateEndpointsServerTransport
	trManagedVirtualNetworksServer           *ManagedVirtualNetworksServerTransport
	trOperationsServer                       *OperationsServerTransport
	trPipelineRunsServer                     *PipelineRunsServerTransport
	trPipelinesServer                        *PipelinesServerTransport
	trPrivateEndPointConnectionsServer       *PrivateEndPointConnectionsServerTransport
	trPrivateEndpointConnectionServer        *PrivateEndpointConnectionServerTransport
	trPrivateLinkResourcesServer             *PrivateLinkResourcesServerTransport
	trTriggerRunsServer                      *TriggerRunsServerTransport
	trTriggersServer                         *TriggersServerTransport
}

// 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 "ActivityRunsClient":
		initServer(s, &s.trActivityRunsServer, func() *ActivityRunsServerTransport { return NewActivityRunsServerTransport(&s.srv.ActivityRunsServer) })
		resp, err = s.trActivityRunsServer.Do(req)
	case "ChangeDataCaptureClient":
		initServer(s, &s.trChangeDataCaptureServer, func() *ChangeDataCaptureServerTransport {
			return NewChangeDataCaptureServerTransport(&s.srv.ChangeDataCaptureServer)
		})
		resp, err = s.trChangeDataCaptureServer.Do(req)
	case "CredentialOperationsClient":
		initServer(s, &s.trCredentialOperationsServer, func() *CredentialOperationsServerTransport {
			return NewCredentialOperationsServerTransport(&s.srv.CredentialOperationsServer)
		})
		resp, err = s.trCredentialOperationsServer.Do(req)
	case "DataFlowDebugSessionClient":
		initServer(s, &s.trDataFlowDebugSessionServer, func() *DataFlowDebugSessionServerTransport {
			return NewDataFlowDebugSessionServerTransport(&s.srv.DataFlowDebugSessionServer)
		})
		resp, err = s.trDataFlowDebugSessionServer.Do(req)
	case "DataFlowsClient":
		initServer(s, &s.trDataFlowsServer, func() *DataFlowsServerTransport { return NewDataFlowsServerTransport(&s.srv.DataFlowsServer) })
		resp, err = s.trDataFlowsServer.Do(req)
	case "DatasetsClient":
		initServer(s, &s.trDatasetsServer, func() *DatasetsServerTransport { return NewDatasetsServerTransport(&s.srv.DatasetsServer) })
		resp, err = s.trDatasetsServer.Do(req)
	case "ExposureControlClient":
		initServer(s, &s.trExposureControlServer, func() *ExposureControlServerTransport {
			return NewExposureControlServerTransport(&s.srv.ExposureControlServer)
		})
		resp, err = s.trExposureControlServer.Do(req)
	case "FactoriesClient":
		initServer(s, &s.trFactoriesServer, func() *FactoriesServerTransport { return NewFactoriesServerTransport(&s.srv.FactoriesServer) })
		resp, err = s.trFactoriesServer.Do(req)
	case "GlobalParametersClient":
		initServer(s, &s.trGlobalParametersServer, func() *GlobalParametersServerTransport {
			return NewGlobalParametersServerTransport(&s.srv.GlobalParametersServer)
		})
		resp, err = s.trGlobalParametersServer.Do(req)
	case "IntegrationRuntimeNodesClient":
		initServer(s, &s.trIntegrationRuntimeNodesServer, func() *IntegrationRuntimeNodesServerTransport {
			return NewIntegrationRuntimeNodesServerTransport(&s.srv.IntegrationRuntimeNodesServer)
		})
		resp, err = s.trIntegrationRuntimeNodesServer.Do(req)
	case "IntegrationRuntimeObjectMetadataClient":
		initServer(s, &s.trIntegrationRuntimeObjectMetadataServer, func() *IntegrationRuntimeObjectMetadataServerTransport {
			return NewIntegrationRuntimeObjectMetadataServerTransport(&s.srv.IntegrationRuntimeObjectMetadataServer)
		})
		resp, err = s.trIntegrationRuntimeObjectMetadataServer.Do(req)
	case "IntegrationRuntimesClient":
		initServer(s, &s.trIntegrationRuntimesServer, func() *IntegrationRuntimesServerTransport {
			return NewIntegrationRuntimesServerTransport(&s.srv.IntegrationRuntimesServer)
		})
		resp, err = s.trIntegrationRuntimesServer.Do(req)
	case "LinkedServicesClient":
		initServer(s, &s.trLinkedServicesServer, func() *LinkedServicesServerTransport {
			return NewLinkedServicesServerTransport(&s.srv.LinkedServicesServer)
		})
		resp, err = s.trLinkedServicesServer.Do(req)
	case "ManagedPrivateEndpointsClient":
		initServer(s, &s.trManagedPrivateEndpointsServer, func() *ManagedPrivateEndpointsServerTransport {
			return NewManagedPrivateEndpointsServerTransport(&s.srv.ManagedPrivateEndpointsServer)
		})
		resp, err = s.trManagedPrivateEndpointsServer.Do(req)
	case "ManagedVirtualNetworksClient":
		initServer(s, &s.trManagedVirtualNetworksServer, func() *ManagedVirtualNetworksServerTransport {
			return NewManagedVirtualNetworksServerTransport(&s.srv.ManagedVirtualNetworksServer)
		})
		resp, err = s.trManagedVirtualNetworksServer.Do(req)
	case "OperationsClient":
		initServer(s, &s.trOperationsServer, func() *OperationsServerTransport { return NewOperationsServerTransport(&s.srv.OperationsServer) })
		resp, err = s.trOperationsServer.Do(req)
	case "PipelineRunsClient":
		initServer(s, &s.trPipelineRunsServer, func() *PipelineRunsServerTransport { return NewPipelineRunsServerTransport(&s.srv.PipelineRunsServer) })
		resp, err = s.trPipelineRunsServer.Do(req)
	case "PipelinesClient":
		initServer(s, &s.trPipelinesServer, func() *PipelinesServerTransport { return NewPipelinesServerTransport(&s.srv.PipelinesServer) })
		resp, err = s.trPipelinesServer.Do(req)
	case "PrivateEndPointConnectionsClient":
		initServer(s, &s.trPrivateEndPointConnectionsServer, func() *PrivateEndPointConnectionsServerTransport {
			return NewPrivateEndPointConnectionsServerTransport(&s.srv.PrivateEndPointConnectionsServer)
		})
		resp, err = s.trPrivateEndPointConnectionsServer.Do(req)
	case "PrivateEndpointConnectionClient":
		initServer(s, &s.trPrivateEndpointConnectionServer, func() *PrivateEndpointConnectionServerTransport {
			return NewPrivateEndpointConnectionServerTransport(&s.srv.PrivateEndpointConnectionServer)
		})
		resp, err = s.trPrivateEndpointConnectionServer.Do(req)
	case "PrivateLinkResourcesClient":
		initServer(s, &s.trPrivateLinkResourcesServer, func() *PrivateLinkResourcesServerTransport {
			return NewPrivateLinkResourcesServerTransport(&s.srv.PrivateLinkResourcesServer)
		})
		resp, err = s.trPrivateLinkResourcesServer.Do(req)
	case "TriggerRunsClient":
		initServer(s, &s.trTriggerRunsServer, func() *TriggerRunsServerTransport { return NewTriggerRunsServerTransport(&s.srv.TriggerRunsServer) })
		resp, err = s.trTriggerRunsServer.Do(req)
	case "TriggersClient":
		initServer(s, &s.trTriggersServer, func() *TriggersServerTransport { return NewTriggersServerTransport(&s.srv.TriggersServer) })
		resp, err = s.trTriggersServer.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()
}
