// 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 armdevtestlabs.ClientFactory type.
type ServerFactory struct {
	ArmTemplatesServer            ArmTemplatesServer
	ArtifactSourcesServer         ArtifactSourcesServer
	ArtifactsServer               ArtifactsServer
	CostsServer                   CostsServer
	CustomImagesServer            CustomImagesServer
	DisksServer                   DisksServer
	EnvironmentsServer            EnvironmentsServer
	FormulasServer                FormulasServer
	GalleryImagesServer           GalleryImagesServer
	GlobalSchedulesServer         GlobalSchedulesServer
	LabsServer                    LabsServer
	NotificationChannelsServer    NotificationChannelsServer
	OperationsServer              OperationsServer
	PoliciesServer                PoliciesServer
	PolicySetsServer              PolicySetsServer
	ProviderOperationsServer      ProviderOperationsServer
	SchedulesServer               SchedulesServer
	SecretsServer                 SecretsServer
	ServiceFabricSchedulesServer  ServiceFabricSchedulesServer
	ServiceFabricsServer          ServiceFabricsServer
	ServiceRunnersServer          ServiceRunnersServer
	UsersServer                   UsersServer
	VirtualMachineSchedulesServer VirtualMachineSchedulesServer
	VirtualMachinesServer         VirtualMachinesServer
	VirtualNetworksServer         VirtualNetworksServer
}

// NewServerFactoryTransport creates a new instance of ServerFactoryTransport with the provided implementation.
// The returned ServerFactoryTransport instance is connected to an instance of armdevtestlabs.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 armdevtestlabs.ClientFactory to instances of ServerFactory.
// Don't use this type directly, use NewServerFactoryTransport instead.
type ServerFactoryTransport struct {
	srv                             *ServerFactory
	trMu                            sync.Mutex
	trArmTemplatesServer            *ArmTemplatesServerTransport
	trArtifactSourcesServer         *ArtifactSourcesServerTransport
	trArtifactsServer               *ArtifactsServerTransport
	trCostsServer                   *CostsServerTransport
	trCustomImagesServer            *CustomImagesServerTransport
	trDisksServer                   *DisksServerTransport
	trEnvironmentsServer            *EnvironmentsServerTransport
	trFormulasServer                *FormulasServerTransport
	trGalleryImagesServer           *GalleryImagesServerTransport
	trGlobalSchedulesServer         *GlobalSchedulesServerTransport
	trLabsServer                    *LabsServerTransport
	trNotificationChannelsServer    *NotificationChannelsServerTransport
	trOperationsServer              *OperationsServerTransport
	trPoliciesServer                *PoliciesServerTransport
	trPolicySetsServer              *PolicySetsServerTransport
	trProviderOperationsServer      *ProviderOperationsServerTransport
	trSchedulesServer               *SchedulesServerTransport
	trSecretsServer                 *SecretsServerTransport
	trServiceFabricSchedulesServer  *ServiceFabricSchedulesServerTransport
	trServiceFabricsServer          *ServiceFabricsServerTransport
	trServiceRunnersServer          *ServiceRunnersServerTransport
	trUsersServer                   *UsersServerTransport
	trVirtualMachineSchedulesServer *VirtualMachineSchedulesServerTransport
	trVirtualMachinesServer         *VirtualMachinesServerTransport
	trVirtualNetworksServer         *VirtualNetworksServerTransport
}

// 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 "ArmTemplatesClient":
		initServer(s, &s.trArmTemplatesServer, func() *ArmTemplatesServerTransport { return NewArmTemplatesServerTransport(&s.srv.ArmTemplatesServer) })
		resp, err = s.trArmTemplatesServer.Do(req)
	case "ArtifactSourcesClient":
		initServer(s, &s.trArtifactSourcesServer, func() *ArtifactSourcesServerTransport {
			return NewArtifactSourcesServerTransport(&s.srv.ArtifactSourcesServer)
		})
		resp, err = s.trArtifactSourcesServer.Do(req)
	case "ArtifactsClient":
		initServer(s, &s.trArtifactsServer, func() *ArtifactsServerTransport { return NewArtifactsServerTransport(&s.srv.ArtifactsServer) })
		resp, err = s.trArtifactsServer.Do(req)
	case "CostsClient":
		initServer(s, &s.trCostsServer, func() *CostsServerTransport { return NewCostsServerTransport(&s.srv.CostsServer) })
		resp, err = s.trCostsServer.Do(req)
	case "CustomImagesClient":
		initServer(s, &s.trCustomImagesServer, func() *CustomImagesServerTransport { return NewCustomImagesServerTransport(&s.srv.CustomImagesServer) })
		resp, err = s.trCustomImagesServer.Do(req)
	case "DisksClient":
		initServer(s, &s.trDisksServer, func() *DisksServerTransport { return NewDisksServerTransport(&s.srv.DisksServer) })
		resp, err = s.trDisksServer.Do(req)
	case "EnvironmentsClient":
		initServer(s, &s.trEnvironmentsServer, func() *EnvironmentsServerTransport { return NewEnvironmentsServerTransport(&s.srv.EnvironmentsServer) })
		resp, err = s.trEnvironmentsServer.Do(req)
	case "FormulasClient":
		initServer(s, &s.trFormulasServer, func() *FormulasServerTransport { return NewFormulasServerTransport(&s.srv.FormulasServer) })
		resp, err = s.trFormulasServer.Do(req)
	case "GalleryImagesClient":
		initServer(s, &s.trGalleryImagesServer, func() *GalleryImagesServerTransport {
			return NewGalleryImagesServerTransport(&s.srv.GalleryImagesServer)
		})
		resp, err = s.trGalleryImagesServer.Do(req)
	case "GlobalSchedulesClient":
		initServer(s, &s.trGlobalSchedulesServer, func() *GlobalSchedulesServerTransport {
			return NewGlobalSchedulesServerTransport(&s.srv.GlobalSchedulesServer)
		})
		resp, err = s.trGlobalSchedulesServer.Do(req)
	case "LabsClient":
		initServer(s, &s.trLabsServer, func() *LabsServerTransport { return NewLabsServerTransport(&s.srv.LabsServer) })
		resp, err = s.trLabsServer.Do(req)
	case "NotificationChannelsClient":
		initServer(s, &s.trNotificationChannelsServer, func() *NotificationChannelsServerTransport {
			return NewNotificationChannelsServerTransport(&s.srv.NotificationChannelsServer)
		})
		resp, err = s.trNotificationChannelsServer.Do(req)
	case "OperationsClient":
		initServer(s, &s.trOperationsServer, func() *OperationsServerTransport { return NewOperationsServerTransport(&s.srv.OperationsServer) })
		resp, err = s.trOperationsServer.Do(req)
	case "PoliciesClient":
		initServer(s, &s.trPoliciesServer, func() *PoliciesServerTransport { return NewPoliciesServerTransport(&s.srv.PoliciesServer) })
		resp, err = s.trPoliciesServer.Do(req)
	case "PolicySetsClient":
		initServer(s, &s.trPolicySetsServer, func() *PolicySetsServerTransport { return NewPolicySetsServerTransport(&s.srv.PolicySetsServer) })
		resp, err = s.trPolicySetsServer.Do(req)
	case "ProviderOperationsClient":
		initServer(s, &s.trProviderOperationsServer, func() *ProviderOperationsServerTransport {
			return NewProviderOperationsServerTransport(&s.srv.ProviderOperationsServer)
		})
		resp, err = s.trProviderOperationsServer.Do(req)
	case "SchedulesClient":
		initServer(s, &s.trSchedulesServer, func() *SchedulesServerTransport { return NewSchedulesServerTransport(&s.srv.SchedulesServer) })
		resp, err = s.trSchedulesServer.Do(req)
	case "SecretsClient":
		initServer(s, &s.trSecretsServer, func() *SecretsServerTransport { return NewSecretsServerTransport(&s.srv.SecretsServer) })
		resp, err = s.trSecretsServer.Do(req)
	case "ServiceFabricSchedulesClient":
		initServer(s, &s.trServiceFabricSchedulesServer, func() *ServiceFabricSchedulesServerTransport {
			return NewServiceFabricSchedulesServerTransport(&s.srv.ServiceFabricSchedulesServer)
		})
		resp, err = s.trServiceFabricSchedulesServer.Do(req)
	case "ServiceFabricsClient":
		initServer(s, &s.trServiceFabricsServer, func() *ServiceFabricsServerTransport {
			return NewServiceFabricsServerTransport(&s.srv.ServiceFabricsServer)
		})
		resp, err = s.trServiceFabricsServer.Do(req)
	case "ServiceRunnersClient":
		initServer(s, &s.trServiceRunnersServer, func() *ServiceRunnersServerTransport {
			return NewServiceRunnersServerTransport(&s.srv.ServiceRunnersServer)
		})
		resp, err = s.trServiceRunnersServer.Do(req)
	case "UsersClient":
		initServer(s, &s.trUsersServer, func() *UsersServerTransport { return NewUsersServerTransport(&s.srv.UsersServer) })
		resp, err = s.trUsersServer.Do(req)
	case "VirtualMachineSchedulesClient":
		initServer(s, &s.trVirtualMachineSchedulesServer, func() *VirtualMachineSchedulesServerTransport {
			return NewVirtualMachineSchedulesServerTransport(&s.srv.VirtualMachineSchedulesServer)
		})
		resp, err = s.trVirtualMachineSchedulesServer.Do(req)
	case "VirtualMachinesClient":
		initServer(s, &s.trVirtualMachinesServer, func() *VirtualMachinesServerTransport {
			return NewVirtualMachinesServerTransport(&s.srv.VirtualMachinesServer)
		})
		resp, err = s.trVirtualMachinesServer.Do(req)
	case "VirtualNetworksClient":
		initServer(s, &s.trVirtualNetworksServer, func() *VirtualNetworksServerTransport {
			return NewVirtualNetworksServerTransport(&s.srv.VirtualNetworksServer)
		})
		resp, err = s.trVirtualNetworksServer.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()
}
