// 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 contains the fakes for client CassandraClustersClient
	CassandraClustersServer CassandraClustersServer

	// CassandraDataCentersServer contains the fakes for client CassandraDataCentersClient
	CassandraDataCentersServer CassandraDataCentersServer

	// CassandraResourcesServer contains the fakes for client CassandraResourcesClient
	CassandraResourcesServer CassandraResourcesServer

	// CollectionServer contains the fakes for client CollectionClient
	CollectionServer CollectionServer

	// CollectionPartitionServer contains the fakes for client CollectionPartitionClient
	CollectionPartitionServer CollectionPartitionServer

	// CollectionPartitionRegionServer contains the fakes for client CollectionPartitionRegionClient
	CollectionPartitionRegionServer CollectionPartitionRegionServer

	// CollectionRegionServer contains the fakes for client CollectionRegionClient
	CollectionRegionServer CollectionRegionServer

	// DatabaseAccountRegionServer contains the fakes for client DatabaseAccountRegionClient
	DatabaseAccountRegionServer DatabaseAccountRegionServer

	// DatabaseAccountsServer contains the fakes for client DatabaseAccountsClient
	DatabaseAccountsServer DatabaseAccountsServer

	// DatabaseServer contains the fakes for client DatabaseClient
	DatabaseServer DatabaseServer

	// GremlinResourcesServer contains the fakes for client GremlinResourcesClient
	GremlinResourcesServer GremlinResourcesServer

	// LocationsServer contains the fakes for client LocationsClient
	LocationsServer LocationsServer

	// MongoDBResourcesServer contains the fakes for client MongoDBResourcesClient
	MongoDBResourcesServer MongoDBResourcesServer

	// NotebookWorkspacesServer contains the fakes for client NotebookWorkspacesClient
	NotebookWorkspacesServer NotebookWorkspacesServer

	// OperationsServer contains the fakes for client OperationsClient
	OperationsServer OperationsServer

	// PartitionKeyRangeIDServer contains the fakes for client PartitionKeyRangeIDClient
	PartitionKeyRangeIDServer PartitionKeyRangeIDServer

	// PartitionKeyRangeIDRegionServer contains the fakes for client PartitionKeyRangeIDRegionClient
	PartitionKeyRangeIDRegionServer PartitionKeyRangeIDRegionServer

	// PercentileServer contains the fakes for client PercentileClient
	PercentileServer PercentileServer

	// PercentileSourceTargetServer contains the fakes for client PercentileSourceTargetClient
	PercentileSourceTargetServer PercentileSourceTargetServer

	// PercentileTargetServer contains the fakes for client PercentileTargetClient
	PercentileTargetServer PercentileTargetServer

	// PrivateEndpointConnectionsServer contains the fakes for client PrivateEndpointConnectionsClient
	PrivateEndpointConnectionsServer PrivateEndpointConnectionsServer

	// PrivateLinkResourcesServer contains the fakes for client PrivateLinkResourcesClient
	PrivateLinkResourcesServer PrivateLinkResourcesServer

	// RestorableDatabaseAccountsServer contains the fakes for client RestorableDatabaseAccountsClient
	RestorableDatabaseAccountsServer RestorableDatabaseAccountsServer

	// RestorableGremlinDatabasesServer contains the fakes for client RestorableGremlinDatabasesClient
	RestorableGremlinDatabasesServer RestorableGremlinDatabasesServer

	// RestorableGremlinGraphsServer contains the fakes for client RestorableGremlinGraphsClient
	RestorableGremlinGraphsServer RestorableGremlinGraphsServer

	// RestorableGremlinResourcesServer contains the fakes for client RestorableGremlinResourcesClient
	RestorableGremlinResourcesServer RestorableGremlinResourcesServer

	// RestorableMongodbCollectionsServer contains the fakes for client RestorableMongodbCollectionsClient
	RestorableMongodbCollectionsServer RestorableMongodbCollectionsServer

	// RestorableMongodbDatabasesServer contains the fakes for client RestorableMongodbDatabasesClient
	RestorableMongodbDatabasesServer RestorableMongodbDatabasesServer

	// RestorableMongodbResourcesServer contains the fakes for client RestorableMongodbResourcesClient
	RestorableMongodbResourcesServer RestorableMongodbResourcesServer

	// RestorableSQLContainersServer contains the fakes for client RestorableSQLContainersClient
	RestorableSQLContainersServer RestorableSQLContainersServer

	// RestorableSQLDatabasesServer contains the fakes for client RestorableSQLDatabasesClient
	RestorableSQLDatabasesServer RestorableSQLDatabasesServer

	// RestorableSQLResourcesServer contains the fakes for client RestorableSQLResourcesClient
	RestorableSQLResourcesServer RestorableSQLResourcesServer

	// RestorableTableResourcesServer contains the fakes for client RestorableTableResourcesClient
	RestorableTableResourcesServer RestorableTableResourcesServer

	// RestorableTablesServer contains the fakes for client RestorableTablesClient
	RestorableTablesServer RestorableTablesServer

	// SQLResourcesServer contains the fakes for client SQLResourcesClient
	SQLResourcesServer SQLResourcesServer

	// ServiceServer contains the fakes for client ServiceClient
	ServiceServer ServiceServer

	// TableResourcesServer contains the fakes for client TableResourcesClient
	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
	trDatabaseAccountRegionServer        *DatabaseAccountRegionServerTransport
	trDatabaseAccountsServer             *DatabaseAccountsServerTransport
	trDatabaseServer                     *DatabaseServerTransport
	trGremlinResourcesServer             *GremlinResourcesServerTransport
	trLocationsServer                    *LocationsServerTransport
	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 "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 "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 "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()
}
