// 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) Go Code Generator. DO NOT EDIT.

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 armbilling.ClientFactory type.
type ServerFactory struct {
	// AccountsServer contains the fakes for client AccountsClient
	AccountsServer AccountsServer

	// AddressServer contains the fakes for client AddressClient
	AddressServer AddressServer

	// AgreementsServer contains the fakes for client AgreementsClient
	AgreementsServer AgreementsServer

	// AssociatedTenantsServer contains the fakes for client AssociatedTenantsClient
	AssociatedTenantsServer AssociatedTenantsServer

	// AvailableBalancesServer contains the fakes for client AvailableBalancesClient
	AvailableBalancesServer AvailableBalancesServer

	// CustomersServer contains the fakes for client CustomersClient
	CustomersServer CustomersServer

	// DepartmentsServer contains the fakes for client DepartmentsClient
	DepartmentsServer DepartmentsServer

	// EnrollmentAccountsServer contains the fakes for client EnrollmentAccountsClient
	EnrollmentAccountsServer EnrollmentAccountsServer

	// InvoiceSectionsServer contains the fakes for client InvoiceSectionsClient
	InvoiceSectionsServer InvoiceSectionsServer

	// InvoicesServer contains the fakes for client InvoicesClient
	InvoicesServer InvoicesServer

	// OperationsServer contains the fakes for client OperationsClient
	OperationsServer OperationsServer

	// PartnerTransfersServer contains the fakes for client PartnerTransfersClient
	PartnerTransfersServer PartnerTransfersServer

	// PaymentMethodsServer contains the fakes for client PaymentMethodsClient
	PaymentMethodsServer PaymentMethodsServer

	// PermissionsServer contains the fakes for client PermissionsClient
	PermissionsServer PermissionsServer

	// PoliciesServer contains the fakes for client PoliciesClient
	PoliciesServer PoliciesServer

	// ProductsServer contains the fakes for client ProductsClient
	ProductsServer ProductsServer

	// ProfilesServer contains the fakes for client ProfilesClient
	ProfilesServer ProfilesServer

	// PropertyServer contains the fakes for client PropertyClient
	PropertyServer PropertyServer

	// RecipientTransfersServer contains the fakes for client RecipientTransfersClient
	RecipientTransfersServer RecipientTransfersServer

	// RequestsServer contains the fakes for client RequestsClient
	RequestsServer RequestsServer

	// ReservationOrdersServer contains the fakes for client ReservationOrdersClient
	ReservationOrdersServer ReservationOrdersServer

	// ReservationsServer contains the fakes for client ReservationsClient
	ReservationsServer ReservationsServer

	// RoleAssignmentsServer contains the fakes for client RoleAssignmentsClient
	RoleAssignmentsServer RoleAssignmentsServer

	// RoleDefinitionServer contains the fakes for client RoleDefinitionClient
	RoleDefinitionServer RoleDefinitionServer

	// SavingsPlanOrdersServer contains the fakes for client SavingsPlanOrdersClient
	SavingsPlanOrdersServer SavingsPlanOrdersServer

	// SavingsPlansServer contains the fakes for client SavingsPlansClient
	SavingsPlansServer SavingsPlansServer

	// SubscriptionsAliasesServer contains the fakes for client SubscriptionsAliasesClient
	SubscriptionsAliasesServer SubscriptionsAliasesServer

	// SubscriptionsServer contains the fakes for client SubscriptionsClient
	SubscriptionsServer SubscriptionsServer

	// TransactionsServer contains the fakes for client TransactionsClient
	TransactionsServer TransactionsServer

	// TransfersServer contains the fakes for client TransfersClient
	TransfersServer TransfersServer
}

// NewServerFactoryTransport creates a new instance of ServerFactoryTransport with the provided implementation.
// The returned ServerFactoryTransport instance is connected to an instance of armbilling.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 armbilling.ClientFactory to instances of ServerFactory.
// Don't use this type directly, use NewServerFactoryTransport instead.
type ServerFactoryTransport struct {
	srv                          *ServerFactory
	trMu                         sync.Mutex
	trAccountsServer             *AccountsServerTransport
	trAddressServer              *AddressServerTransport
	trAgreementsServer           *AgreementsServerTransport
	trAssociatedTenantsServer    *AssociatedTenantsServerTransport
	trAvailableBalancesServer    *AvailableBalancesServerTransport
	trCustomersServer            *CustomersServerTransport
	trDepartmentsServer          *DepartmentsServerTransport
	trEnrollmentAccountsServer   *EnrollmentAccountsServerTransport
	trInvoiceSectionsServer      *InvoiceSectionsServerTransport
	trInvoicesServer             *InvoicesServerTransport
	trOperationsServer           *OperationsServerTransport
	trPartnerTransfersServer     *PartnerTransfersServerTransport
	trPaymentMethodsServer       *PaymentMethodsServerTransport
	trPermissionsServer          *PermissionsServerTransport
	trPoliciesServer             *PoliciesServerTransport
	trProductsServer             *ProductsServerTransport
	trProfilesServer             *ProfilesServerTransport
	trPropertyServer             *PropertyServerTransport
	trRecipientTransfersServer   *RecipientTransfersServerTransport
	trRequestsServer             *RequestsServerTransport
	trReservationOrdersServer    *ReservationOrdersServerTransport
	trReservationsServer         *ReservationsServerTransport
	trRoleAssignmentsServer      *RoleAssignmentsServerTransport
	trRoleDefinitionServer       *RoleDefinitionServerTransport
	trSavingsPlanOrdersServer    *SavingsPlanOrdersServerTransport
	trSavingsPlansServer         *SavingsPlansServerTransport
	trSubscriptionsAliasesServer *SubscriptionsAliasesServerTransport
	trSubscriptionsServer        *SubscriptionsServerTransport
	trTransactionsServer         *TransactionsServerTransport
	trTransfersServer            *TransfersServerTransport
}

// 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 "AccountsClient":
		initServer(&s.trMu, &s.trAccountsServer, func() *AccountsServerTransport { return NewAccountsServerTransport(&s.srv.AccountsServer) })
		resp, err = s.trAccountsServer.Do(req)
	case "AddressClient":
		initServer(&s.trMu, &s.trAddressServer, func() *AddressServerTransport { return NewAddressServerTransport(&s.srv.AddressServer) })
		resp, err = s.trAddressServer.Do(req)
	case "AgreementsClient":
		initServer(&s.trMu, &s.trAgreementsServer, func() *AgreementsServerTransport { return NewAgreementsServerTransport(&s.srv.AgreementsServer) })
		resp, err = s.trAgreementsServer.Do(req)
	case "AssociatedTenantsClient":
		initServer(&s.trMu, &s.trAssociatedTenantsServer, func() *AssociatedTenantsServerTransport {
			return NewAssociatedTenantsServerTransport(&s.srv.AssociatedTenantsServer)
		})
		resp, err = s.trAssociatedTenantsServer.Do(req)
	case "AvailableBalancesClient":
		initServer(&s.trMu, &s.trAvailableBalancesServer, func() *AvailableBalancesServerTransport {
			return NewAvailableBalancesServerTransport(&s.srv.AvailableBalancesServer)
		})
		resp, err = s.trAvailableBalancesServer.Do(req)
	case "CustomersClient":
		initServer(&s.trMu, &s.trCustomersServer, func() *CustomersServerTransport { return NewCustomersServerTransport(&s.srv.CustomersServer) })
		resp, err = s.trCustomersServer.Do(req)
	case "DepartmentsClient":
		initServer(&s.trMu, &s.trDepartmentsServer, func() *DepartmentsServerTransport { return NewDepartmentsServerTransport(&s.srv.DepartmentsServer) })
		resp, err = s.trDepartmentsServer.Do(req)
	case "EnrollmentAccountsClient":
		initServer(&s.trMu, &s.trEnrollmentAccountsServer, func() *EnrollmentAccountsServerTransport {
			return NewEnrollmentAccountsServerTransport(&s.srv.EnrollmentAccountsServer)
		})
		resp, err = s.trEnrollmentAccountsServer.Do(req)
	case "InvoiceSectionsClient":
		initServer(&s.trMu, &s.trInvoiceSectionsServer, func() *InvoiceSectionsServerTransport {
			return NewInvoiceSectionsServerTransport(&s.srv.InvoiceSectionsServer)
		})
		resp, err = s.trInvoiceSectionsServer.Do(req)
	case "InvoicesClient":
		initServer(&s.trMu, &s.trInvoicesServer, func() *InvoicesServerTransport { return NewInvoicesServerTransport(&s.srv.InvoicesServer) })
		resp, err = s.trInvoicesServer.Do(req)
	case "OperationsClient":
		initServer(&s.trMu, &s.trOperationsServer, func() *OperationsServerTransport { return NewOperationsServerTransport(&s.srv.OperationsServer) })
		resp, err = s.trOperationsServer.Do(req)
	case "PartnerTransfersClient":
		initServer(&s.trMu, &s.trPartnerTransfersServer, func() *PartnerTransfersServerTransport {
			return NewPartnerTransfersServerTransport(&s.srv.PartnerTransfersServer)
		})
		resp, err = s.trPartnerTransfersServer.Do(req)
	case "PaymentMethodsClient":
		initServer(&s.trMu, &s.trPaymentMethodsServer, func() *PaymentMethodsServerTransport {
			return NewPaymentMethodsServerTransport(&s.srv.PaymentMethodsServer)
		})
		resp, err = s.trPaymentMethodsServer.Do(req)
	case "PermissionsClient":
		initServer(&s.trMu, &s.trPermissionsServer, func() *PermissionsServerTransport { return NewPermissionsServerTransport(&s.srv.PermissionsServer) })
		resp, err = s.trPermissionsServer.Do(req)
	case "PoliciesClient":
		initServer(&s.trMu, &s.trPoliciesServer, func() *PoliciesServerTransport { return NewPoliciesServerTransport(&s.srv.PoliciesServer) })
		resp, err = s.trPoliciesServer.Do(req)
	case "ProductsClient":
		initServer(&s.trMu, &s.trProductsServer, func() *ProductsServerTransport { return NewProductsServerTransport(&s.srv.ProductsServer) })
		resp, err = s.trProductsServer.Do(req)
	case "ProfilesClient":
		initServer(&s.trMu, &s.trProfilesServer, func() *ProfilesServerTransport { return NewProfilesServerTransport(&s.srv.ProfilesServer) })
		resp, err = s.trProfilesServer.Do(req)
	case "PropertyClient":
		initServer(&s.trMu, &s.trPropertyServer, func() *PropertyServerTransport { return NewPropertyServerTransport(&s.srv.PropertyServer) })
		resp, err = s.trPropertyServer.Do(req)
	case "RecipientTransfersClient":
		initServer(&s.trMu, &s.trRecipientTransfersServer, func() *RecipientTransfersServerTransport {
			return NewRecipientTransfersServerTransport(&s.srv.RecipientTransfersServer)
		})
		resp, err = s.trRecipientTransfersServer.Do(req)
	case "RequestsClient":
		initServer(&s.trMu, &s.trRequestsServer, func() *RequestsServerTransport { return NewRequestsServerTransport(&s.srv.RequestsServer) })
		resp, err = s.trRequestsServer.Do(req)
	case "ReservationOrdersClient":
		initServer(&s.trMu, &s.trReservationOrdersServer, func() *ReservationOrdersServerTransport {
			return NewReservationOrdersServerTransport(&s.srv.ReservationOrdersServer)
		})
		resp, err = s.trReservationOrdersServer.Do(req)
	case "ReservationsClient":
		initServer(&s.trMu, &s.trReservationsServer, func() *ReservationsServerTransport { return NewReservationsServerTransport(&s.srv.ReservationsServer) })
		resp, err = s.trReservationsServer.Do(req)
	case "RoleAssignmentsClient":
		initServer(&s.trMu, &s.trRoleAssignmentsServer, func() *RoleAssignmentsServerTransport {
			return NewRoleAssignmentsServerTransport(&s.srv.RoleAssignmentsServer)
		})
		resp, err = s.trRoleAssignmentsServer.Do(req)
	case "RoleDefinitionClient":
		initServer(&s.trMu, &s.trRoleDefinitionServer, func() *RoleDefinitionServerTransport {
			return NewRoleDefinitionServerTransport(&s.srv.RoleDefinitionServer)
		})
		resp, err = s.trRoleDefinitionServer.Do(req)
	case "SavingsPlanOrdersClient":
		initServer(&s.trMu, &s.trSavingsPlanOrdersServer, func() *SavingsPlanOrdersServerTransport {
			return NewSavingsPlanOrdersServerTransport(&s.srv.SavingsPlanOrdersServer)
		})
		resp, err = s.trSavingsPlanOrdersServer.Do(req)
	case "SavingsPlansClient":
		initServer(&s.trMu, &s.trSavingsPlansServer, func() *SavingsPlansServerTransport { return NewSavingsPlansServerTransport(&s.srv.SavingsPlansServer) })
		resp, err = s.trSavingsPlansServer.Do(req)
	case "SubscriptionsAliasesClient":
		initServer(&s.trMu, &s.trSubscriptionsAliasesServer, func() *SubscriptionsAliasesServerTransport {
			return NewSubscriptionsAliasesServerTransport(&s.srv.SubscriptionsAliasesServer)
		})
		resp, err = s.trSubscriptionsAliasesServer.Do(req)
	case "SubscriptionsClient":
		initServer(&s.trMu, &s.trSubscriptionsServer, func() *SubscriptionsServerTransport {
			return NewSubscriptionsServerTransport(&s.srv.SubscriptionsServer)
		})
		resp, err = s.trSubscriptionsServer.Do(req)
	case "TransactionsClient":
		initServer(&s.trMu, &s.trTransactionsServer, func() *TransactionsServerTransport { return NewTransactionsServerTransport(&s.srv.TransactionsServer) })
		resp, err = s.trTransactionsServer.Do(req)
	case "TransfersClient":
		initServer(&s.trMu, &s.trTransfersServer, func() *TransfersServerTransport { return NewTransfersServerTransport(&s.srv.TransfersServer) })
		resp, err = s.trTransfersServer.Do(req)
	default:
		err = fmt.Errorf("unhandled client %s", client)
	}

	if err != nil {
		return nil, err
	}

	return resp, nil
}
