// 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) Go Code Generator. DO NOT EDIT.

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 armazurestackhcivm.ClientFactory type.
type ServerFactory struct {
	// AttestationStatusesServer contains the fakes for client AttestationStatusesClient
	AttestationStatusesServer AttestationStatusesServer

	// GalleryImagesServer contains the fakes for client GalleryImagesClient
	GalleryImagesServer GalleryImagesServer

	// GuestAgentsServer contains the fakes for client GuestAgentsClient
	GuestAgentsServer GuestAgentsServer

	// HybridIdentityMetadataServer contains the fakes for client HybridIdentityMetadataClient
	HybridIdentityMetadataServer HybridIdentityMetadataServer

	// LogicalNetworksServer contains the fakes for client LogicalNetworksClient
	LogicalNetworksServer LogicalNetworksServer

	// MarketplaceGalleryImagesServer contains the fakes for client MarketplaceGalleryImagesClient
	MarketplaceGalleryImagesServer MarketplaceGalleryImagesServer

	// NetworkInterfacesServer contains the fakes for client NetworkInterfacesClient
	NetworkInterfacesServer NetworkInterfacesServer

	// NetworkSecurityGroupsServer contains the fakes for client NetworkSecurityGroupsClient
	NetworkSecurityGroupsServer NetworkSecurityGroupsServer

	// SecurityRulesServer contains the fakes for client SecurityRulesClient
	SecurityRulesServer SecurityRulesServer

	// StorageContainersServer contains the fakes for client StorageContainersClient
	StorageContainersServer StorageContainersServer

	// VirtualHardDisksServer contains the fakes for client VirtualHardDisksClient
	VirtualHardDisksServer VirtualHardDisksServer

	// VirtualMachineInstancesServer contains the fakes for client VirtualMachineInstancesClient
	VirtualMachineInstancesServer VirtualMachineInstancesServer
}

// NewServerFactoryTransport creates a new instance of ServerFactoryTransport with the provided implementation.
// The returned ServerFactoryTransport instance is connected to an instance of armazurestackhcivm.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 armazurestackhcivm.ClientFactory to instances of ServerFactory.
// Don't use this type directly, use NewServerFactoryTransport instead.
type ServerFactoryTransport struct {
	srv                              *ServerFactory
	trMu                             sync.Mutex
	trAttestationStatusesServer      *AttestationStatusesServerTransport
	trGalleryImagesServer            *GalleryImagesServerTransport
	trGuestAgentsServer              *GuestAgentsServerTransport
	trHybridIdentityMetadataServer   *HybridIdentityMetadataServerTransport
	trLogicalNetworksServer          *LogicalNetworksServerTransport
	trMarketplaceGalleryImagesServer *MarketplaceGalleryImagesServerTransport
	trNetworkInterfacesServer        *NetworkInterfacesServerTransport
	trNetworkSecurityGroupsServer    *NetworkSecurityGroupsServerTransport
	trSecurityRulesServer            *SecurityRulesServerTransport
	trStorageContainersServer        *StorageContainersServerTransport
	trVirtualHardDisksServer         *VirtualHardDisksServerTransport
	trVirtualMachineInstancesServer  *VirtualMachineInstancesServerTransport
}

// 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 "AttestationStatusesClient":
		initServer(s, &s.trAttestationStatusesServer, func() *AttestationStatusesServerTransport {
			return NewAttestationStatusesServerTransport(&s.srv.AttestationStatusesServer)
		})
		resp, err = s.trAttestationStatusesServer.Do(req)
	case "GalleryImagesClient":
		initServer(s, &s.trGalleryImagesServer, func() *GalleryImagesServerTransport {
			return NewGalleryImagesServerTransport(&s.srv.GalleryImagesServer)
		})
		resp, err = s.trGalleryImagesServer.Do(req)
	case "GuestAgentsClient":
		initServer(s, &s.trGuestAgentsServer, func() *GuestAgentsServerTransport { return NewGuestAgentsServerTransport(&s.srv.GuestAgentsServer) })
		resp, err = s.trGuestAgentsServer.Do(req)
	case "HybridIdentityMetadataClient":
		initServer(s, &s.trHybridIdentityMetadataServer, func() *HybridIdentityMetadataServerTransport {
			return NewHybridIdentityMetadataServerTransport(&s.srv.HybridIdentityMetadataServer)
		})
		resp, err = s.trHybridIdentityMetadataServer.Do(req)
	case "LogicalNetworksClient":
		initServer(s, &s.trLogicalNetworksServer, func() *LogicalNetworksServerTransport {
			return NewLogicalNetworksServerTransport(&s.srv.LogicalNetworksServer)
		})
		resp, err = s.trLogicalNetworksServer.Do(req)
	case "MarketplaceGalleryImagesClient":
		initServer(s, &s.trMarketplaceGalleryImagesServer, func() *MarketplaceGalleryImagesServerTransport {
			return NewMarketplaceGalleryImagesServerTransport(&s.srv.MarketplaceGalleryImagesServer)
		})
		resp, err = s.trMarketplaceGalleryImagesServer.Do(req)
	case "NetworkInterfacesClient":
		initServer(s, &s.trNetworkInterfacesServer, func() *NetworkInterfacesServerTransport {
			return NewNetworkInterfacesServerTransport(&s.srv.NetworkInterfacesServer)
		})
		resp, err = s.trNetworkInterfacesServer.Do(req)
	case "NetworkSecurityGroupsClient":
		initServer(s, &s.trNetworkSecurityGroupsServer, func() *NetworkSecurityGroupsServerTransport {
			return NewNetworkSecurityGroupsServerTransport(&s.srv.NetworkSecurityGroupsServer)
		})
		resp, err = s.trNetworkSecurityGroupsServer.Do(req)
	case "SecurityRulesClient":
		initServer(s, &s.trSecurityRulesServer, func() *SecurityRulesServerTransport {
			return NewSecurityRulesServerTransport(&s.srv.SecurityRulesServer)
		})
		resp, err = s.trSecurityRulesServer.Do(req)
	case "StorageContainersClient":
		initServer(s, &s.trStorageContainersServer, func() *StorageContainersServerTransport {
			return NewStorageContainersServerTransport(&s.srv.StorageContainersServer)
		})
		resp, err = s.trStorageContainersServer.Do(req)
	case "VirtualHardDisksClient":
		initServer(s, &s.trVirtualHardDisksServer, func() *VirtualHardDisksServerTransport {
			return NewVirtualHardDisksServerTransport(&s.srv.VirtualHardDisksServer)
		})
		resp, err = s.trVirtualHardDisksServer.Do(req)
	case "VirtualMachineInstancesClient":
		initServer(s, &s.trVirtualMachineInstancesServer, func() *VirtualMachineInstancesServerTransport {
			return NewVirtualMachineInstancesServerTransport(&s.srv.VirtualMachineInstancesServer)
		})
		resp, err = s.trVirtualMachineInstancesServer.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()
}
