//go:build go1.18
// +build go1.18

// 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 armcustomerinsights.ClientFactory type.
type ServerFactory struct {
	AuthorizationPoliciesServer AuthorizationPoliciesServer
	ConnectorMappingsServer     ConnectorMappingsServer
	ConnectorsServer            ConnectorsServer
	HubsServer                  HubsServer
	ImagesServer                ImagesServer
	InteractionsServer          InteractionsServer
	KpiServer                   KpiServer
	LinksServer                 LinksServer
	OperationsServer            OperationsServer
	PredictionsServer           PredictionsServer
	ProfilesServer              ProfilesServer
	RelationshipLinksServer     RelationshipLinksServer
	RelationshipsServer         RelationshipsServer
	RoleAssignmentsServer       RoleAssignmentsServer
	RolesServer                 RolesServer
	ViewsServer                 ViewsServer
	WidgetTypesServer           WidgetTypesServer
}

// NewServerFactoryTransport creates a new instance of ServerFactoryTransport with the provided implementation.
// The returned ServerFactoryTransport instance is connected to an instance of armcustomerinsights.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 armcustomerinsights.ClientFactory to instances of ServerFactory.
// Don't use this type directly, use NewServerFactoryTransport instead.
type ServerFactoryTransport struct {
	srv                           *ServerFactory
	trMu                          sync.Mutex
	trAuthorizationPoliciesServer *AuthorizationPoliciesServerTransport
	trConnectorMappingsServer     *ConnectorMappingsServerTransport
	trConnectorsServer            *ConnectorsServerTransport
	trHubsServer                  *HubsServerTransport
	trImagesServer                *ImagesServerTransport
	trInteractionsServer          *InteractionsServerTransport
	trKpiServer                   *KpiServerTransport
	trLinksServer                 *LinksServerTransport
	trOperationsServer            *OperationsServerTransport
	trPredictionsServer           *PredictionsServerTransport
	trProfilesServer              *ProfilesServerTransport
	trRelationshipLinksServer     *RelationshipLinksServerTransport
	trRelationshipsServer         *RelationshipsServerTransport
	trRoleAssignmentsServer       *RoleAssignmentsServerTransport
	trRolesServer                 *RolesServerTransport
	trViewsServer                 *ViewsServerTransport
	trWidgetTypesServer           *WidgetTypesServerTransport
}

// 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 "AuthorizationPoliciesClient":
		initServer(s, &s.trAuthorizationPoliciesServer, func() *AuthorizationPoliciesServerTransport {
			return NewAuthorizationPoliciesServerTransport(&s.srv.AuthorizationPoliciesServer)
		})
		resp, err = s.trAuthorizationPoliciesServer.Do(req)
	case "ConnectorMappingsClient":
		initServer(s, &s.trConnectorMappingsServer, func() *ConnectorMappingsServerTransport {
			return NewConnectorMappingsServerTransport(&s.srv.ConnectorMappingsServer)
		})
		resp, err = s.trConnectorMappingsServer.Do(req)
	case "ConnectorsClient":
		initServer(s, &s.trConnectorsServer, func() *ConnectorsServerTransport { return NewConnectorsServerTransport(&s.srv.ConnectorsServer) })
		resp, err = s.trConnectorsServer.Do(req)
	case "HubsClient":
		initServer(s, &s.trHubsServer, func() *HubsServerTransport { return NewHubsServerTransport(&s.srv.HubsServer) })
		resp, err = s.trHubsServer.Do(req)
	case "ImagesClient":
		initServer(s, &s.trImagesServer, func() *ImagesServerTransport { return NewImagesServerTransport(&s.srv.ImagesServer) })
		resp, err = s.trImagesServer.Do(req)
	case "InteractionsClient":
		initServer(s, &s.trInteractionsServer, func() *InteractionsServerTransport { return NewInteractionsServerTransport(&s.srv.InteractionsServer) })
		resp, err = s.trInteractionsServer.Do(req)
	case "KpiClient":
		initServer(s, &s.trKpiServer, func() *KpiServerTransport { return NewKpiServerTransport(&s.srv.KpiServer) })
		resp, err = s.trKpiServer.Do(req)
	case "LinksClient":
		initServer(s, &s.trLinksServer, func() *LinksServerTransport { return NewLinksServerTransport(&s.srv.LinksServer) })
		resp, err = s.trLinksServer.Do(req)
	case "OperationsClient":
		initServer(s, &s.trOperationsServer, func() *OperationsServerTransport { return NewOperationsServerTransport(&s.srv.OperationsServer) })
		resp, err = s.trOperationsServer.Do(req)
	case "PredictionsClient":
		initServer(s, &s.trPredictionsServer, func() *PredictionsServerTransport { return NewPredictionsServerTransport(&s.srv.PredictionsServer) })
		resp, err = s.trPredictionsServer.Do(req)
	case "ProfilesClient":
		initServer(s, &s.trProfilesServer, func() *ProfilesServerTransport { return NewProfilesServerTransport(&s.srv.ProfilesServer) })
		resp, err = s.trProfilesServer.Do(req)
	case "RelationshipLinksClient":
		initServer(s, &s.trRelationshipLinksServer, func() *RelationshipLinksServerTransport {
			return NewRelationshipLinksServerTransport(&s.srv.RelationshipLinksServer)
		})
		resp, err = s.trRelationshipLinksServer.Do(req)
	case "RelationshipsClient":
		initServer(s, &s.trRelationshipsServer, func() *RelationshipsServerTransport {
			return NewRelationshipsServerTransport(&s.srv.RelationshipsServer)
		})
		resp, err = s.trRelationshipsServer.Do(req)
	case "RoleAssignmentsClient":
		initServer(s, &s.trRoleAssignmentsServer, func() *RoleAssignmentsServerTransport {
			return NewRoleAssignmentsServerTransport(&s.srv.RoleAssignmentsServer)
		})
		resp, err = s.trRoleAssignmentsServer.Do(req)
	case "RolesClient":
		initServer(s, &s.trRolesServer, func() *RolesServerTransport { return NewRolesServerTransport(&s.srv.RolesServer) })
		resp, err = s.trRolesServer.Do(req)
	case "ViewsClient":
		initServer(s, &s.trViewsServer, func() *ViewsServerTransport { return NewViewsServerTransport(&s.srv.ViewsServer) })
		resp, err = s.trViewsServer.Do(req)
	case "WidgetTypesClient":
		initServer(s, &s.trWidgetTypesServer, func() *WidgetTypesServerTransport { return NewWidgetTypesServerTransport(&s.srv.WidgetTypesServer) })
		resp, err = s.trWidgetTypesServer.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()
}
