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

	// Server contains the fakes for client Client
	Server Server

	// IdentityBindingsServer contains the fakes for client IdentityBindingsClient
	IdentityBindingsServer IdentityBindingsServer

	// JWTAuthenticatorsServer contains the fakes for client JWTAuthenticatorsClient
	JWTAuthenticatorsServer JWTAuthenticatorsServer

	// LoadBalancersServer contains the fakes for client LoadBalancersClient
	LoadBalancersServer LoadBalancersServer

	// MachinesServer contains the fakes for client MachinesClient
	MachinesServer MachinesServer

	// MaintenanceConfigurationsServer contains the fakes for client MaintenanceConfigurationsClient
	MaintenanceConfigurationsServer MaintenanceConfigurationsServer

	// ManagedClusterSnapshotsServer contains the fakes for client ManagedClusterSnapshotsClient
	ManagedClusterSnapshotsServer ManagedClusterSnapshotsServer

	// ManagedClustersServer contains the fakes for client ManagedClustersClient
	ManagedClustersServer ManagedClustersServer

	// ManagedNamespacesServer contains the fakes for client ManagedNamespacesClient
	ManagedNamespacesServer ManagedNamespacesServer

	// OperationStatusResultServer contains the fakes for client OperationStatusResultClient
	OperationStatusResultServer OperationStatusResultServer

	// OperationsServer contains the fakes for client OperationsClient
	OperationsServer OperationsServer

	// PrivateEndpointConnectionsServer contains the fakes for client PrivateEndpointConnectionsClient
	PrivateEndpointConnectionsServer PrivateEndpointConnectionsServer

	// PrivateLinkResourcesServer contains the fakes for client PrivateLinkResourcesClient
	PrivateLinkResourcesServer PrivateLinkResourcesServer

	// ResolvePrivateLinkServiceIDServer contains the fakes for client ResolvePrivateLinkServiceIDClient
	ResolvePrivateLinkServiceIDServer ResolvePrivateLinkServiceIDServer

	// SnapshotsServer contains the fakes for client SnapshotsClient
	SnapshotsServer SnapshotsServer

	// TrustedAccessRoleBindingsServer contains the fakes for client TrustedAccessRoleBindingsClient
	TrustedAccessRoleBindingsServer TrustedAccessRoleBindingsServer

	// TrustedAccessRolesServer contains the fakes for client TrustedAccessRolesClient
	TrustedAccessRolesServer TrustedAccessRolesServer
}

// NewServerFactoryTransport creates a new instance of ServerFactoryTransport with the provided implementation.
// The returned ServerFactoryTransport instance is connected to an instance of armcontainerservice.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 armcontainerservice.ClientFactory to instances of ServerFactory.
// Don't use this type directly, use NewServerFactoryTransport instead.
type ServerFactoryTransport struct {
	srv                                 *ServerFactory
	trMu                                sync.Mutex
	trAgentPoolsServer                  *AgentPoolsServerTransport
	trServer                            *ServerTransport
	trIdentityBindingsServer            *IdentityBindingsServerTransport
	trJWTAuthenticatorsServer           *JWTAuthenticatorsServerTransport
	trLoadBalancersServer               *LoadBalancersServerTransport
	trMachinesServer                    *MachinesServerTransport
	trMaintenanceConfigurationsServer   *MaintenanceConfigurationsServerTransport
	trManagedClusterSnapshotsServer     *ManagedClusterSnapshotsServerTransport
	trManagedClustersServer             *ManagedClustersServerTransport
	trManagedNamespacesServer           *ManagedNamespacesServerTransport
	trOperationStatusResultServer       *OperationStatusResultServerTransport
	trOperationsServer                  *OperationsServerTransport
	trPrivateEndpointConnectionsServer  *PrivateEndpointConnectionsServerTransport
	trPrivateLinkResourcesServer        *PrivateLinkResourcesServerTransport
	trResolvePrivateLinkServiceIDServer *ResolvePrivateLinkServiceIDServerTransport
	trSnapshotsServer                   *SnapshotsServerTransport
	trTrustedAccessRoleBindingsServer   *TrustedAccessRoleBindingsServerTransport
	trTrustedAccessRolesServer          *TrustedAccessRolesServerTransport
}

// 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 "Client":
		initServer(s, &s.trServer, func() *ServerTransport { return NewServerTransport(&s.srv.Server) })
		resp, err = s.trServer.Do(req)
	case "IdentityBindingsClient":
		initServer(s, &s.trIdentityBindingsServer, func() *IdentityBindingsServerTransport {
			return NewIdentityBindingsServerTransport(&s.srv.IdentityBindingsServer)
		})
		resp, err = s.trIdentityBindingsServer.Do(req)
	case "JWTAuthenticatorsClient":
		initServer(s, &s.trJWTAuthenticatorsServer, func() *JWTAuthenticatorsServerTransport {
			return NewJWTAuthenticatorsServerTransport(&s.srv.JWTAuthenticatorsServer)
		})
		resp, err = s.trJWTAuthenticatorsServer.Do(req)
	case "LoadBalancersClient":
		initServer(s, &s.trLoadBalancersServer, func() *LoadBalancersServerTransport {
			return NewLoadBalancersServerTransport(&s.srv.LoadBalancersServer)
		})
		resp, err = s.trLoadBalancersServer.Do(req)
	case "MachinesClient":
		initServer(s, &s.trMachinesServer, func() *MachinesServerTransport { return NewMachinesServerTransport(&s.srv.MachinesServer) })
		resp, err = s.trMachinesServer.Do(req)
	case "MaintenanceConfigurationsClient":
		initServer(s, &s.trMaintenanceConfigurationsServer, func() *MaintenanceConfigurationsServerTransport {
			return NewMaintenanceConfigurationsServerTransport(&s.srv.MaintenanceConfigurationsServer)
		})
		resp, err = s.trMaintenanceConfigurationsServer.Do(req)
	case "ManagedClusterSnapshotsClient":
		initServer(s, &s.trManagedClusterSnapshotsServer, func() *ManagedClusterSnapshotsServerTransport {
			return NewManagedClusterSnapshotsServerTransport(&s.srv.ManagedClusterSnapshotsServer)
		})
		resp, err = s.trManagedClusterSnapshotsServer.Do(req)
	case "ManagedClustersClient":
		initServer(s, &s.trManagedClustersServer, func() *ManagedClustersServerTransport {
			return NewManagedClustersServerTransport(&s.srv.ManagedClustersServer)
		})
		resp, err = s.trManagedClustersServer.Do(req)
	case "ManagedNamespacesClient":
		initServer(s, &s.trManagedNamespacesServer, func() *ManagedNamespacesServerTransport {
			return NewManagedNamespacesServerTransport(&s.srv.ManagedNamespacesServer)
		})
		resp, err = s.trManagedNamespacesServer.Do(req)
	case "OperationStatusResultClient":
		initServer(s, &s.trOperationStatusResultServer, func() *OperationStatusResultServerTransport {
			return NewOperationStatusResultServerTransport(&s.srv.OperationStatusResultServer)
		})
		resp, err = s.trOperationStatusResultServer.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 "ResolvePrivateLinkServiceIDClient":
		initServer(s, &s.trResolvePrivateLinkServiceIDServer, func() *ResolvePrivateLinkServiceIDServerTransport {
			return NewResolvePrivateLinkServiceIDServerTransport(&s.srv.ResolvePrivateLinkServiceIDServer)
		})
		resp, err = s.trResolvePrivateLinkServiceIDServer.Do(req)
	case "SnapshotsClient":
		initServer(s, &s.trSnapshotsServer, func() *SnapshotsServerTransport { return NewSnapshotsServerTransport(&s.srv.SnapshotsServer) })
		resp, err = s.trSnapshotsServer.Do(req)
	case "TrustedAccessRoleBindingsClient":
		initServer(s, &s.trTrustedAccessRoleBindingsServer, func() *TrustedAccessRoleBindingsServerTransport {
			return NewTrustedAccessRoleBindingsServerTransport(&s.srv.TrustedAccessRoleBindingsServer)
		})
		resp, err = s.trTrustedAccessRoleBindingsServer.Do(req)
	case "TrustedAccessRolesClient":
		initServer(s, &s.trTrustedAccessRolesServer, func() *TrustedAccessRolesServerTransport {
			return NewTrustedAccessRolesServerTransport(&s.srv.TrustedAccessRolesServer)
		})
		resp, err = s.trTrustedAccessRolesServer.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()
}
