// 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 armapplicationinsights.ClientFactory type.
type ServerFactory struct {
	// APIKeysServer contains the fakes for client APIKeysClient
	APIKeysServer APIKeysServer

	// AnalyticsItemsServer contains the fakes for client AnalyticsItemsClient
	AnalyticsItemsServer AnalyticsItemsServer

	// AnnotationsServer contains the fakes for client AnnotationsClient
	AnnotationsServer AnnotationsServer

	// ComponentAvailableFeaturesServer contains the fakes for client ComponentAvailableFeaturesClient
	ComponentAvailableFeaturesServer ComponentAvailableFeaturesServer

	// ComponentCurrentBillingFeaturesServer contains the fakes for client ComponentCurrentBillingFeaturesClient
	ComponentCurrentBillingFeaturesServer ComponentCurrentBillingFeaturesServer

	// ComponentFeatureCapabilitiesServer contains the fakes for client ComponentFeatureCapabilitiesClient
	ComponentFeatureCapabilitiesServer ComponentFeatureCapabilitiesServer

	// ComponentLinkedStorageAccountsServer contains the fakes for client ComponentLinkedStorageAccountsClient
	ComponentLinkedStorageAccountsServer ComponentLinkedStorageAccountsServer

	// ComponentQuotaStatusServer contains the fakes for client ComponentQuotaStatusClient
	ComponentQuotaStatusServer ComponentQuotaStatusServer

	// ComponentsServer contains the fakes for client ComponentsClient
	ComponentsServer ComponentsServer

	// DeletedWorkbooksServer contains the fakes for client DeletedWorkbooksClient
	DeletedWorkbooksServer DeletedWorkbooksServer

	// ExportConfigurationsServer contains the fakes for client ExportConfigurationsClient
	ExportConfigurationsServer ExportConfigurationsServer

	// FavoritesServer contains the fakes for client FavoritesClient
	FavoritesServer FavoritesServer

	// LiveTokenServer contains the fakes for client LiveTokenClient
	LiveTokenServer LiveTokenServer

	// OperationsServer contains the fakes for client OperationsClient
	OperationsServer OperationsServer

	// ProactiveDetectionConfigurationsServer contains the fakes for client ProactiveDetectionConfigurationsClient
	ProactiveDetectionConfigurationsServer ProactiveDetectionConfigurationsServer

	// WebTestLocationsServer contains the fakes for client WebTestLocationsClient
	WebTestLocationsServer WebTestLocationsServer

	// WebTestsServer contains the fakes for client WebTestsClient
	WebTestsServer WebTestsServer

	// WorkItemConfigurationsServer contains the fakes for client WorkItemConfigurationsClient
	WorkItemConfigurationsServer WorkItemConfigurationsServer

	// WorkbookTemplatesServer contains the fakes for client WorkbookTemplatesClient
	WorkbookTemplatesServer WorkbookTemplatesServer

	// WorkbooksServer contains the fakes for client WorkbooksClient
	WorkbooksServer WorkbooksServer
}

// NewServerFactoryTransport creates a new instance of ServerFactoryTransport with the provided implementation.
// The returned ServerFactoryTransport instance is connected to an instance of armapplicationinsights.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 armapplicationinsights.ClientFactory to instances of ServerFactory.
// Don't use this type directly, use NewServerFactoryTransport instead.
type ServerFactoryTransport struct {
	srv                                      *ServerFactory
	trMu                                     sync.Mutex
	trAPIKeysServer                          *APIKeysServerTransport
	trAnalyticsItemsServer                   *AnalyticsItemsServerTransport
	trAnnotationsServer                      *AnnotationsServerTransport
	trComponentAvailableFeaturesServer       *ComponentAvailableFeaturesServerTransport
	trComponentCurrentBillingFeaturesServer  *ComponentCurrentBillingFeaturesServerTransport
	trComponentFeatureCapabilitiesServer     *ComponentFeatureCapabilitiesServerTransport
	trComponentLinkedStorageAccountsServer   *ComponentLinkedStorageAccountsServerTransport
	trComponentQuotaStatusServer             *ComponentQuotaStatusServerTransport
	trComponentsServer                       *ComponentsServerTransport
	trDeletedWorkbooksServer                 *DeletedWorkbooksServerTransport
	trExportConfigurationsServer             *ExportConfigurationsServerTransport
	trFavoritesServer                        *FavoritesServerTransport
	trLiveTokenServer                        *LiveTokenServerTransport
	trOperationsServer                       *OperationsServerTransport
	trProactiveDetectionConfigurationsServer *ProactiveDetectionConfigurationsServerTransport
	trWebTestLocationsServer                 *WebTestLocationsServerTransport
	trWebTestsServer                         *WebTestsServerTransport
	trWorkItemConfigurationsServer           *WorkItemConfigurationsServerTransport
	trWorkbookTemplatesServer                *WorkbookTemplatesServerTransport
	trWorkbooksServer                        *WorkbooksServerTransport
}

// 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 "APIKeysClient":
		initServer(s, &s.trAPIKeysServer, func() *APIKeysServerTransport { return NewAPIKeysServerTransport(&s.srv.APIKeysServer) })
		resp, err = s.trAPIKeysServer.Do(req)
	case "AnalyticsItemsClient":
		initServer(s, &s.trAnalyticsItemsServer, func() *AnalyticsItemsServerTransport {
			return NewAnalyticsItemsServerTransport(&s.srv.AnalyticsItemsServer)
		})
		resp, err = s.trAnalyticsItemsServer.Do(req)
	case "AnnotationsClient":
		initServer(s, &s.trAnnotationsServer, func() *AnnotationsServerTransport { return NewAnnotationsServerTransport(&s.srv.AnnotationsServer) })
		resp, err = s.trAnnotationsServer.Do(req)
	case "ComponentAvailableFeaturesClient":
		initServer(s, &s.trComponentAvailableFeaturesServer, func() *ComponentAvailableFeaturesServerTransport {
			return NewComponentAvailableFeaturesServerTransport(&s.srv.ComponentAvailableFeaturesServer)
		})
		resp, err = s.trComponentAvailableFeaturesServer.Do(req)
	case "ComponentCurrentBillingFeaturesClient":
		initServer(s, &s.trComponentCurrentBillingFeaturesServer, func() *ComponentCurrentBillingFeaturesServerTransport {
			return NewComponentCurrentBillingFeaturesServerTransport(&s.srv.ComponentCurrentBillingFeaturesServer)
		})
		resp, err = s.trComponentCurrentBillingFeaturesServer.Do(req)
	case "ComponentFeatureCapabilitiesClient":
		initServer(s, &s.trComponentFeatureCapabilitiesServer, func() *ComponentFeatureCapabilitiesServerTransport {
			return NewComponentFeatureCapabilitiesServerTransport(&s.srv.ComponentFeatureCapabilitiesServer)
		})
		resp, err = s.trComponentFeatureCapabilitiesServer.Do(req)
	case "ComponentLinkedStorageAccountsClient":
		initServer(s, &s.trComponentLinkedStorageAccountsServer, func() *ComponentLinkedStorageAccountsServerTransport {
			return NewComponentLinkedStorageAccountsServerTransport(&s.srv.ComponentLinkedStorageAccountsServer)
		})
		resp, err = s.trComponentLinkedStorageAccountsServer.Do(req)
	case "ComponentQuotaStatusClient":
		initServer(s, &s.trComponentQuotaStatusServer, func() *ComponentQuotaStatusServerTransport {
			return NewComponentQuotaStatusServerTransport(&s.srv.ComponentQuotaStatusServer)
		})
		resp, err = s.trComponentQuotaStatusServer.Do(req)
	case "ComponentsClient":
		initServer(s, &s.trComponentsServer, func() *ComponentsServerTransport { return NewComponentsServerTransport(&s.srv.ComponentsServer) })
		resp, err = s.trComponentsServer.Do(req)
	case "DeletedWorkbooksClient":
		initServer(s, &s.trDeletedWorkbooksServer, func() *DeletedWorkbooksServerTransport {
			return NewDeletedWorkbooksServerTransport(&s.srv.DeletedWorkbooksServer)
		})
		resp, err = s.trDeletedWorkbooksServer.Do(req)
	case "ExportConfigurationsClient":
		initServer(s, &s.trExportConfigurationsServer, func() *ExportConfigurationsServerTransport {
			return NewExportConfigurationsServerTransport(&s.srv.ExportConfigurationsServer)
		})
		resp, err = s.trExportConfigurationsServer.Do(req)
	case "FavoritesClient":
		initServer(s, &s.trFavoritesServer, func() *FavoritesServerTransport { return NewFavoritesServerTransport(&s.srv.FavoritesServer) })
		resp, err = s.trFavoritesServer.Do(req)
	case "LiveTokenClient":
		initServer(s, &s.trLiveTokenServer, func() *LiveTokenServerTransport { return NewLiveTokenServerTransport(&s.srv.LiveTokenServer) })
		resp, err = s.trLiveTokenServer.Do(req)
	case "OperationsClient":
		initServer(s, &s.trOperationsServer, func() *OperationsServerTransport { return NewOperationsServerTransport(&s.srv.OperationsServer) })
		resp, err = s.trOperationsServer.Do(req)
	case "ProactiveDetectionConfigurationsClient":
		initServer(s, &s.trProactiveDetectionConfigurationsServer, func() *ProactiveDetectionConfigurationsServerTransport {
			return NewProactiveDetectionConfigurationsServerTransport(&s.srv.ProactiveDetectionConfigurationsServer)
		})
		resp, err = s.trProactiveDetectionConfigurationsServer.Do(req)
	case "WebTestLocationsClient":
		initServer(s, &s.trWebTestLocationsServer, func() *WebTestLocationsServerTransport {
			return NewWebTestLocationsServerTransport(&s.srv.WebTestLocationsServer)
		})
		resp, err = s.trWebTestLocationsServer.Do(req)
	case "WebTestsClient":
		initServer(s, &s.trWebTestsServer, func() *WebTestsServerTransport { return NewWebTestsServerTransport(&s.srv.WebTestsServer) })
		resp, err = s.trWebTestsServer.Do(req)
	case "WorkItemConfigurationsClient":
		initServer(s, &s.trWorkItemConfigurationsServer, func() *WorkItemConfigurationsServerTransport {
			return NewWorkItemConfigurationsServerTransport(&s.srv.WorkItemConfigurationsServer)
		})
		resp, err = s.trWorkItemConfigurationsServer.Do(req)
	case "WorkbookTemplatesClient":
		initServer(s, &s.trWorkbookTemplatesServer, func() *WorkbookTemplatesServerTransport {
			return NewWorkbookTemplatesServerTransport(&s.srv.WorkbookTemplatesServer)
		})
		resp, err = s.trWorkbookTemplatesServer.Do(req)
	case "WorkbooksClient":
		initServer(s, &s.trWorkbooksServer, func() *WorkbooksServerTransport { return NewWorkbooksServerTransport(&s.srv.WorkbooksServer) })
		resp, err = s.trWorkbooksServer.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()
}
