//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 armcosmos.ClientFactory type.
type ServerFactory struct {
	CassandraClustersServer            CassandraClustersServer
	CassandraDataCentersServer         CassandraDataCentersServer
	CassandraResourcesServer           CassandraResourcesServer
	CollectionServer                   CollectionServer
	CollectionPartitionServer          CollectionPartitionServer
	CollectionPartitionRegionServer    CollectionPartitionRegionServer
	CollectionRegionServer             CollectionRegionServer
	DataTransferJobsServer             DataTransferJobsServer
	DatabaseAccountRegionServer        DatabaseAccountRegionServer
	DatabaseAccountsServer             DatabaseAccountsServer
	DatabaseServer                     DatabaseServer
	GraphResourcesServer               GraphResourcesServer
	GremlinResourcesServer             GremlinResourcesServer
	LocationsServer                    LocationsServer
	MongoClustersServer                MongoClustersServer
	MongoDBResourcesServer             MongoDBResourcesServer
	NotebookWorkspacesServer           NotebookWorkspacesServer
	OperationsServer                   OperationsServer
	PartitionKeyRangeIDServer          PartitionKeyRangeIDServer
	PartitionKeyRangeIDRegionServer    PartitionKeyRangeIDRegionServer
	PercentileServer                   PercentileServer
	PercentileSourceTargetServer       PercentileSourceTargetServer
	PercentileTargetServer             PercentileTargetServer
	PrivateEndpointConnectionsServer   PrivateEndpointConnectionsServer
	PrivateLinkResourcesServer         PrivateLinkResourcesServer
	RestorableDatabaseAccountsServer   RestorableDatabaseAccountsServer
	RestorableGremlinDatabasesServer   RestorableGremlinDatabasesServer
	RestorableGremlinGraphsServer      RestorableGremlinGraphsServer
	RestorableGremlinResourcesServer   RestorableGremlinResourcesServer
	RestorableMongodbCollectionsServer RestorableMongodbCollectionsServer
	RestorableMongodbDatabasesServer   RestorableMongodbDatabasesServer
	RestorableMongodbResourcesServer   RestorableMongodbResourcesServer
	RestorableSQLContainersServer      RestorableSQLContainersServer
	RestorableSQLDatabasesServer       RestorableSQLDatabasesServer
	RestorableSQLResourcesServer       RestorableSQLResourcesServer
	RestorableTableResourcesServer     RestorableTableResourcesServer
	RestorableTablesServer             RestorableTablesServer
	SQLResourcesServer                 SQLResourcesServer
	ServiceServer                      ServiceServer
	TableResourcesServer               TableResourcesServer
}

// NewServerFactoryTransport creates a new instance of ServerFactoryTransport with the provided implementation.
// The returned ServerFactoryTransport instance is connected to an instance of armcosmos.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 armcosmos.ClientFactory to instances of ServerFactory.
// Don't use this type directly, use NewServerFactoryTransport instead.
type ServerFactoryTransport struct {
	srv                                  *ServerFactory
	trMu                                 sync.Mutex
	trCassandraClustersServer            *CassandraClustersServerTransport
	trCassandraDataCentersServer         *CassandraDataCentersServerTransport
	trCassandraResourcesServer           *CassandraResourcesServerTransport
	trCollectionServer                   *CollectionServerTransport
	trCollectionPartitionServer          *CollectionPartitionServerTransport
	trCollectionPartitionRegionServer    *CollectionPartitionRegionServerTransport
	trCollectionRegionServer             *CollectionRegionServerTransport
	trDataTransferJobsServer             *DataTransferJobsServerTransport
	trDatabaseAccountRegionServer        *DatabaseAccountRegionServerTransport
	trDatabaseAccountsServer             *DatabaseAccountsServerTransport
	trDatabaseServer                     *DatabaseServerTransport
	trGraphResourcesServer               *GraphResourcesServerTransport
	trGremlinResourcesServer             *GremlinResourcesServerTransport
	trLocationsServer                    *LocationsServerTransport
	trMongoClustersServer                *MongoClustersServerTransport
	trMongoDBResourcesServer             *MongoDBResourcesServerTransport
	trNotebookWorkspacesServer           *NotebookWorkspacesServerTransport
	trOperationsServer                   *OperationsServerTransport
	trPartitionKeyRangeIDServer          *PartitionKeyRangeIDServerTransport
	trPartitionKeyRangeIDRegionServer    *PartitionKeyRangeIDRegionServerTransport
	trPercentileServer                   *PercentileServerTransport
	trPercentileSourceTargetServer       *PercentileSourceTargetServerTransport
	trPercentileTargetServer             *PercentileTargetServerTransport
	trPrivateEndpointConnectionsServer   *PrivateEndpointConnectionsServerTransport
	trPrivateLinkResourcesServer         *PrivateLinkResourcesServerTransport
	trRestorableDatabaseAccountsServer   *RestorableDatabaseAccountsServerTransport
	trRestorableGremlinDatabasesServer   *RestorableGremlinDatabasesServerTransport
	trRestorableGremlinGraphsServer      *RestorableGremlinGraphsServerTransport
	trRestorableGremlinResourcesServer   *RestorableGremlinResourcesServerTransport
	trRestorableMongodbCollectionsServer *RestorableMongodbCollectionsServerTransport
	trRestorableMongodbDatabasesServer   *RestorableMongodbDatabasesServerTransport
	trRestorableMongodbResourcesServer   *RestorableMongodbResourcesServerTransport
	trRestorableSQLContainersServer      *RestorableSQLContainersServerTransport
	trRestorableSQLDatabasesServer       *RestorableSQLDatabasesServerTransport
	trRestorableSQLResourcesServer       *RestorableSQLResourcesServerTransport
	trRestorableTableResourcesServer     *RestorableTableResourcesServerTransport
	trRestorableTablesServer             *RestorableTablesServerTransport
	trSQLResourcesServer                 *SQLResourcesServerTransport
	trServiceServer                      *ServiceServerTransport
	trTableResourcesServer               *TableResourcesServerTransport
}

// 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 "CassandraClustersClient":
		initServer(s, &s.trCassandraClustersServer, func() *CassandraClustersServerTransport {
			return NewCassandraClustersServerTransport(&s.srv.CassandraClustersServer)
		})
		resp, err = s.trCassandraClustersServer.Do(req)
	case "CassandraDataCentersClient":
		initServer(s, &s.trCassandraDataCentersServer, func() *CassandraDataCentersServerTransport {
			return NewCassandraDataCentersServerTransport(&s.srv.CassandraDataCentersServer)
		})
		resp, err = s.trCassandraDataCentersServer.Do(req)
	case "CassandraResourcesClient":
		initServer(s, &s.trCassandraResourcesServer, func() *CassandraResourcesServerTransport {
			return NewCassandraResourcesServerTransport(&s.srv.CassandraResourcesServer)
		})
		resp, err = s.trCassandraResourcesServer.Do(req)
	case "CollectionClient":
		initServer(s, &s.trCollectionServer, func() *CollectionServerTransport { return NewCollectionServerTransport(&s.srv.CollectionServer) })
		resp, err = s.trCollectionServer.Do(req)
	case "CollectionPartitionClient":
		initServer(s, &s.trCollectionPartitionServer, func() *CollectionPartitionServerTransport {
			return NewCollectionPartitionServerTransport(&s.srv.CollectionPartitionServer)
		})
		resp, err = s.trCollectionPartitionServer.Do(req)
	case "CollectionPartitionRegionClient":
		initServer(s, &s.trCollectionPartitionRegionServer, func() *CollectionPartitionRegionServerTransport {
			return NewCollectionPartitionRegionServerTransport(&s.srv.CollectionPartitionRegionServer)
		})
		resp, err = s.trCollectionPartitionRegionServer.Do(req)
	case "CollectionRegionClient":
		initServer(s, &s.trCollectionRegionServer, func() *CollectionRegionServerTransport {
			return NewCollectionRegionServerTransport(&s.srv.CollectionRegionServer)
		})
		resp, err = s.trCollectionRegionServer.Do(req)
	case "DataTransferJobsClient":
		initServer(s, &s.trDataTransferJobsServer, func() *DataTransferJobsServerTransport {
			return NewDataTransferJobsServerTransport(&s.srv.DataTransferJobsServer)
		})
		resp, err = s.trDataTransferJobsServer.Do(req)
	case "DatabaseAccountRegionClient":
		initServer(s, &s.trDatabaseAccountRegionServer, func() *DatabaseAccountRegionServerTransport {
			return NewDatabaseAccountRegionServerTransport(&s.srv.DatabaseAccountRegionServer)
		})
		resp, err = s.trDatabaseAccountRegionServer.Do(req)
	case "DatabaseAccountsClient":
		initServer(s, &s.trDatabaseAccountsServer, func() *DatabaseAccountsServerTransport {
			return NewDatabaseAccountsServerTransport(&s.srv.DatabaseAccountsServer)
		})
		resp, err = s.trDatabaseAccountsServer.Do(req)
	case "DatabaseClient":
		initServer(s, &s.trDatabaseServer, func() *DatabaseServerTransport { return NewDatabaseServerTransport(&s.srv.DatabaseServer) })
		resp, err = s.trDatabaseServer.Do(req)
	case "GraphResourcesClient":
		initServer(s, &s.trGraphResourcesServer, func() *GraphResourcesServerTransport {
			return NewGraphResourcesServerTransport(&s.srv.GraphResourcesServer)
		})
		resp, err = s.trGraphResourcesServer.Do(req)
	case "GremlinResourcesClient":
		initServer(s, &s.trGremlinResourcesServer, func() *GremlinResourcesServerTransport {
			return NewGremlinResourcesServerTransport(&s.srv.GremlinResourcesServer)
		})
		resp, err = s.trGremlinResourcesServer.Do(req)
	case "LocationsClient":
		initServer(s, &s.trLocationsServer, func() *LocationsServerTransport { return NewLocationsServerTransport(&s.srv.LocationsServer) })
		resp, err = s.trLocationsServer.Do(req)
	case "MongoClustersClient":
		initServer(s, &s.trMongoClustersServer, func() *MongoClustersServerTransport {
			return NewMongoClustersServerTransport(&s.srv.MongoClustersServer)
		})
		resp, err = s.trMongoClustersServer.Do(req)
	case "MongoDBResourcesClient":
		initServer(s, &s.trMongoDBResourcesServer, func() *MongoDBResourcesServerTransport {
			return NewMongoDBResourcesServerTransport(&s.srv.MongoDBResourcesServer)
		})
		resp, err = s.trMongoDBResourcesServer.Do(req)
	case "NotebookWorkspacesClient":
		initServer(s, &s.trNotebookWorkspacesServer, func() *NotebookWorkspacesServerTransport {
			return NewNotebookWorkspacesServerTransport(&s.srv.NotebookWorkspacesServer)
		})
		resp, err = s.trNotebookWorkspacesServer.Do(req)
	case "OperationsClient":
		initServer(s, &s.trOperationsServer, func() *OperationsServerTransport { return NewOperationsServerTransport(&s.srv.OperationsServer) })
		resp, err = s.trOperationsServer.Do(req)
	case "PartitionKeyRangeIDClient":
		initServer(s, &s.trPartitionKeyRangeIDServer, func() *PartitionKeyRangeIDServerTransport {
			return NewPartitionKeyRangeIDServerTransport(&s.srv.PartitionKeyRangeIDServer)
		})
		resp, err = s.trPartitionKeyRangeIDServer.Do(req)
	case "PartitionKeyRangeIDRegionClient":
		initServer(s, &s.trPartitionKeyRangeIDRegionServer, func() *PartitionKeyRangeIDRegionServerTransport {
			return NewPartitionKeyRangeIDRegionServerTransport(&s.srv.PartitionKeyRangeIDRegionServer)
		})
		resp, err = s.trPartitionKeyRangeIDRegionServer.Do(req)
	case "PercentileClient":
		initServer(s, &s.trPercentileServer, func() *PercentileServerTransport { return NewPercentileServerTransport(&s.srv.PercentileServer) })
		resp, err = s.trPercentileServer.Do(req)
	case "PercentileSourceTargetClient":
		initServer(s, &s.trPercentileSourceTargetServer, func() *PercentileSourceTargetServerTransport {
			return NewPercentileSourceTargetServerTransport(&s.srv.PercentileSourceTargetServer)
		})
		resp, err = s.trPercentileSourceTargetServer.Do(req)
	case "PercentileTargetClient":
		initServer(s, &s.trPercentileTargetServer, func() *PercentileTargetServerTransport {
			return NewPercentileTargetServerTransport(&s.srv.PercentileTargetServer)
		})
		resp, err = s.trPercentileTargetServer.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 "RestorableDatabaseAccountsClient":
		initServer(s, &s.trRestorableDatabaseAccountsServer, func() *RestorableDatabaseAccountsServerTransport {
			return NewRestorableDatabaseAccountsServerTransport(&s.srv.RestorableDatabaseAccountsServer)
		})
		resp, err = s.trRestorableDatabaseAccountsServer.Do(req)
	case "RestorableGremlinDatabasesClient":
		initServer(s, &s.trRestorableGremlinDatabasesServer, func() *RestorableGremlinDatabasesServerTransport {
			return NewRestorableGremlinDatabasesServerTransport(&s.srv.RestorableGremlinDatabasesServer)
		})
		resp, err = s.trRestorableGremlinDatabasesServer.Do(req)
	case "RestorableGremlinGraphsClient":
		initServer(s, &s.trRestorableGremlinGraphsServer, func() *RestorableGremlinGraphsServerTransport {
			return NewRestorableGremlinGraphsServerTransport(&s.srv.RestorableGremlinGraphsServer)
		})
		resp, err = s.trRestorableGremlinGraphsServer.Do(req)
	case "RestorableGremlinResourcesClient":
		initServer(s, &s.trRestorableGremlinResourcesServer, func() *RestorableGremlinResourcesServerTransport {
			return NewRestorableGremlinResourcesServerTransport(&s.srv.RestorableGremlinResourcesServer)
		})
		resp, err = s.trRestorableGremlinResourcesServer.Do(req)
	case "RestorableMongodbCollectionsClient":
		initServer(s, &s.trRestorableMongodbCollectionsServer, func() *RestorableMongodbCollectionsServerTransport {
			return NewRestorableMongodbCollectionsServerTransport(&s.srv.RestorableMongodbCollectionsServer)
		})
		resp, err = s.trRestorableMongodbCollectionsServer.Do(req)
	case "RestorableMongodbDatabasesClient":
		initServer(s, &s.trRestorableMongodbDatabasesServer, func() *RestorableMongodbDatabasesServerTransport {
			return NewRestorableMongodbDatabasesServerTransport(&s.srv.RestorableMongodbDatabasesServer)
		})
		resp, err = s.trRestorableMongodbDatabasesServer.Do(req)
	case "RestorableMongodbResourcesClient":
		initServer(s, &s.trRestorableMongodbResourcesServer, func() *RestorableMongodbResourcesServerTransport {
			return NewRestorableMongodbResourcesServerTransport(&s.srv.RestorableMongodbResourcesServer)
		})
		resp, err = s.trRestorableMongodbResourcesServer.Do(req)
	case "RestorableSQLContainersClient":
		initServer(s, &s.trRestorableSQLContainersServer, func() *RestorableSQLContainersServerTransport {
			return NewRestorableSQLContainersServerTransport(&s.srv.RestorableSQLContainersServer)
		})
		resp, err = s.trRestorableSQLContainersServer.Do(req)
	case "RestorableSQLDatabasesClient":
		initServer(s, &s.trRestorableSQLDatabasesServer, func() *RestorableSQLDatabasesServerTransport {
			return NewRestorableSQLDatabasesServerTransport(&s.srv.RestorableSQLDatabasesServer)
		})
		resp, err = s.trRestorableSQLDatabasesServer.Do(req)
	case "RestorableSQLResourcesClient":
		initServer(s, &s.trRestorableSQLResourcesServer, func() *RestorableSQLResourcesServerTransport {
			return NewRestorableSQLResourcesServerTransport(&s.srv.RestorableSQLResourcesServer)
		})
		resp, err = s.trRestorableSQLResourcesServer.Do(req)
	case "RestorableTableResourcesClient":
		initServer(s, &s.trRestorableTableResourcesServer, func() *RestorableTableResourcesServerTransport {
			return NewRestorableTableResourcesServerTransport(&s.srv.RestorableTableResourcesServer)
		})
		resp, err = s.trRestorableTableResourcesServer.Do(req)
	case "RestorableTablesClient":
		initServer(s, &s.trRestorableTablesServer, func() *RestorableTablesServerTransport {
			return NewRestorableTablesServerTransport(&s.srv.RestorableTablesServer)
		})
		resp, err = s.trRestorableTablesServer.Do(req)
	case "SQLResourcesClient":
		initServer(s, &s.trSQLResourcesServer, func() *SQLResourcesServerTransport { return NewSQLResourcesServerTransport(&s.srv.SQLResourcesServer) })
		resp, err = s.trSQLResourcesServer.Do(req)
	case "ServiceClient":
		initServer(s, &s.trServiceServer, func() *ServiceServerTransport { return NewServiceServerTransport(&s.srv.ServiceServer) })
		resp, err = s.trServiceServer.Do(req)
	case "TableResourcesClient":
		initServer(s, &s.trTableResourcesServer, func() *TableResourcesServerTransport {
			return NewTableResourcesServerTransport(&s.srv.TableResourcesServer)
		})
		resp, err = s.trTableResourcesServer.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()
}
