// 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 armnetworkcloud.ClientFactory type.
type ServerFactory struct {
	// AgentPoolsServer contains the fakes for client AgentPoolsClient
	AgentPoolsServer AgentPoolsServer

	// BareMetalMachineKeySetsServer contains the fakes for client BareMetalMachineKeySetsClient
	BareMetalMachineKeySetsServer BareMetalMachineKeySetsServer

	// BareMetalMachinesServer contains the fakes for client BareMetalMachinesClient
	BareMetalMachinesServer BareMetalMachinesServer

	// BmcKeySetsServer contains the fakes for client BmcKeySetsClient
	BmcKeySetsServer BmcKeySetsServer

	// CloudServicesNetworksServer contains the fakes for client CloudServicesNetworksClient
	CloudServicesNetworksServer CloudServicesNetworksServer

	// ClusterManagersServer contains the fakes for client ClusterManagersClient
	ClusterManagersServer ClusterManagersServer

	// ClustersServer contains the fakes for client ClustersClient
	ClustersServer ClustersServer

	// ConsolesServer contains the fakes for client ConsolesClient
	ConsolesServer ConsolesServer

	// KubernetesClusterFeaturesServer contains the fakes for client KubernetesClusterFeaturesClient
	KubernetesClusterFeaturesServer KubernetesClusterFeaturesServer

	// KubernetesClustersServer contains the fakes for client KubernetesClustersClient
	KubernetesClustersServer KubernetesClustersServer

	// L2NetworksServer contains the fakes for client L2NetworksClient
	L2NetworksServer L2NetworksServer

	// L3NetworksServer contains the fakes for client L3NetworksClient
	L3NetworksServer L3NetworksServer

	// MetricsConfigurationsServer contains the fakes for client MetricsConfigurationsClient
	MetricsConfigurationsServer MetricsConfigurationsServer

	// OperationsServer contains the fakes for client OperationsClient
	OperationsServer OperationsServer

	// RackSKUsServer contains the fakes for client RackSKUsClient
	RackSKUsServer RackSKUsServer

	// RacksServer contains the fakes for client RacksClient
	RacksServer RacksServer

	// StorageAppliancesServer contains the fakes for client StorageAppliancesClient
	StorageAppliancesServer StorageAppliancesServer

	// TrunkedNetworksServer contains the fakes for client TrunkedNetworksClient
	TrunkedNetworksServer TrunkedNetworksServer

	// VirtualMachinesServer contains the fakes for client VirtualMachinesClient
	VirtualMachinesServer VirtualMachinesServer

	// VolumesServer contains the fakes for client VolumesClient
	VolumesServer VolumesServer
}

// NewServerFactoryTransport creates a new instance of ServerFactoryTransport with the provided implementation.
// The returned ServerFactoryTransport instance is connected to an instance of armnetworkcloud.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 armnetworkcloud.ClientFactory to instances of ServerFactory.
// Don't use this type directly, use NewServerFactoryTransport instead.
type ServerFactoryTransport struct {
	srv                               *ServerFactory
	trMu                              sync.Mutex
	trAgentPoolsServer                *AgentPoolsServerTransport
	trBareMetalMachineKeySetsServer   *BareMetalMachineKeySetsServerTransport
	trBareMetalMachinesServer         *BareMetalMachinesServerTransport
	trBmcKeySetsServer                *BmcKeySetsServerTransport
	trCloudServicesNetworksServer     *CloudServicesNetworksServerTransport
	trClusterManagersServer           *ClusterManagersServerTransport
	trClustersServer                  *ClustersServerTransport
	trConsolesServer                  *ConsolesServerTransport
	trKubernetesClusterFeaturesServer *KubernetesClusterFeaturesServerTransport
	trKubernetesClustersServer        *KubernetesClustersServerTransport
	trL2NetworksServer                *L2NetworksServerTransport
	trL3NetworksServer                *L3NetworksServerTransport
	trMetricsConfigurationsServer     *MetricsConfigurationsServerTransport
	trOperationsServer                *OperationsServerTransport
	trRackSKUsServer                  *RackSKUsServerTransport
	trRacksServer                     *RacksServerTransport
	trStorageAppliancesServer         *StorageAppliancesServerTransport
	trTrunkedNetworksServer           *TrunkedNetworksServerTransport
	trVirtualMachinesServer           *VirtualMachinesServerTransport
	trVolumesServer                   *VolumesServerTransport
}

// 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 "AgentPoolsClient":
		initServer(s, &s.trAgentPoolsServer, func() *AgentPoolsServerTransport { return NewAgentPoolsServerTransport(&s.srv.AgentPoolsServer) })
		resp, err = s.trAgentPoolsServer.Do(req)
	case "BareMetalMachineKeySetsClient":
		initServer(s, &s.trBareMetalMachineKeySetsServer, func() *BareMetalMachineKeySetsServerTransport {
			return NewBareMetalMachineKeySetsServerTransport(&s.srv.BareMetalMachineKeySetsServer)
		})
		resp, err = s.trBareMetalMachineKeySetsServer.Do(req)
	case "BareMetalMachinesClient":
		initServer(s, &s.trBareMetalMachinesServer, func() *BareMetalMachinesServerTransport {
			return NewBareMetalMachinesServerTransport(&s.srv.BareMetalMachinesServer)
		})
		resp, err = s.trBareMetalMachinesServer.Do(req)
	case "BmcKeySetsClient":
		initServer(s, &s.trBmcKeySetsServer, func() *BmcKeySetsServerTransport { return NewBmcKeySetsServerTransport(&s.srv.BmcKeySetsServer) })
		resp, err = s.trBmcKeySetsServer.Do(req)
	case "CloudServicesNetworksClient":
		initServer(s, &s.trCloudServicesNetworksServer, func() *CloudServicesNetworksServerTransport {
			return NewCloudServicesNetworksServerTransport(&s.srv.CloudServicesNetworksServer)
		})
		resp, err = s.trCloudServicesNetworksServer.Do(req)
	case "ClusterManagersClient":
		initServer(s, &s.trClusterManagersServer, func() *ClusterManagersServerTransport {
			return NewClusterManagersServerTransport(&s.srv.ClusterManagersServer)
		})
		resp, err = s.trClusterManagersServer.Do(req)
	case "ClustersClient":
		initServer(s, &s.trClustersServer, func() *ClustersServerTransport { return NewClustersServerTransport(&s.srv.ClustersServer) })
		resp, err = s.trClustersServer.Do(req)
	case "ConsolesClient":
		initServer(s, &s.trConsolesServer, func() *ConsolesServerTransport { return NewConsolesServerTransport(&s.srv.ConsolesServer) })
		resp, err = s.trConsolesServer.Do(req)
	case "KubernetesClusterFeaturesClient":
		initServer(s, &s.trKubernetesClusterFeaturesServer, func() *KubernetesClusterFeaturesServerTransport {
			return NewKubernetesClusterFeaturesServerTransport(&s.srv.KubernetesClusterFeaturesServer)
		})
		resp, err = s.trKubernetesClusterFeaturesServer.Do(req)
	case "KubernetesClustersClient":
		initServer(s, &s.trKubernetesClustersServer, func() *KubernetesClustersServerTransport {
			return NewKubernetesClustersServerTransport(&s.srv.KubernetesClustersServer)
		})
		resp, err = s.trKubernetesClustersServer.Do(req)
	case "L2NetworksClient":
		initServer(s, &s.trL2NetworksServer, func() *L2NetworksServerTransport { return NewL2NetworksServerTransport(&s.srv.L2NetworksServer) })
		resp, err = s.trL2NetworksServer.Do(req)
	case "L3NetworksClient":
		initServer(s, &s.trL3NetworksServer, func() *L3NetworksServerTransport { return NewL3NetworksServerTransport(&s.srv.L3NetworksServer) })
		resp, err = s.trL3NetworksServer.Do(req)
	case "MetricsConfigurationsClient":
		initServer(s, &s.trMetricsConfigurationsServer, func() *MetricsConfigurationsServerTransport {
			return NewMetricsConfigurationsServerTransport(&s.srv.MetricsConfigurationsServer)
		})
		resp, err = s.trMetricsConfigurationsServer.Do(req)
	case "OperationsClient":
		initServer(s, &s.trOperationsServer, func() *OperationsServerTransport { return NewOperationsServerTransport(&s.srv.OperationsServer) })
		resp, err = s.trOperationsServer.Do(req)
	case "RackSKUsClient":
		initServer(s, &s.trRackSKUsServer, func() *RackSKUsServerTransport { return NewRackSKUsServerTransport(&s.srv.RackSKUsServer) })
		resp, err = s.trRackSKUsServer.Do(req)
	case "RacksClient":
		initServer(s, &s.trRacksServer, func() *RacksServerTransport { return NewRacksServerTransport(&s.srv.RacksServer) })
		resp, err = s.trRacksServer.Do(req)
	case "StorageAppliancesClient":
		initServer(s, &s.trStorageAppliancesServer, func() *StorageAppliancesServerTransport {
			return NewStorageAppliancesServerTransport(&s.srv.StorageAppliancesServer)
		})
		resp, err = s.trStorageAppliancesServer.Do(req)
	case "TrunkedNetworksClient":
		initServer(s, &s.trTrunkedNetworksServer, func() *TrunkedNetworksServerTransport {
			return NewTrunkedNetworksServerTransport(&s.srv.TrunkedNetworksServer)
		})
		resp, err = s.trTrunkedNetworksServer.Do(req)
	case "VirtualMachinesClient":
		initServer(s, &s.trVirtualMachinesServer, func() *VirtualMachinesServerTransport {
			return NewVirtualMachinesServerTransport(&s.srv.VirtualMachinesServer)
		})
		resp, err = s.trVirtualMachinesServer.Do(req)
	case "VolumesClient":
		initServer(s, &s.trVolumesServer, func() *VolumesServerTransport { return NewVolumesServerTransport(&s.srv.VolumesServer) })
		resp, err = s.trVolumesServer.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()
}
