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

	// BackupPoliciesServer contains the fakes for client BackupPoliciesClient
	BackupPoliciesServer BackupPoliciesServer

	// BackupVaultsServer contains the fakes for client BackupVaultsClient
	BackupVaultsServer BackupVaultsServer

	// BackupsServer contains the fakes for client BackupsClient
	BackupsServer BackupsServer

	// BackupsUnderAccountServer contains the fakes for client BackupsUnderAccountClient
	BackupsUnderAccountServer BackupsUnderAccountServer

	// BackupsUnderBackupVaultServer contains the fakes for client BackupsUnderBackupVaultClient
	BackupsUnderBackupVaultServer BackupsUnderBackupVaultServer

	// BackupsUnderVolumeServer contains the fakes for client BackupsUnderVolumeClient
	BackupsUnderVolumeServer BackupsUnderVolumeServer

	// OperationsServer contains the fakes for client OperationsClient
	OperationsServer OperationsServer

	// PoolsServer contains the fakes for client PoolsClient
	PoolsServer PoolsServer

	// ResourceServer contains the fakes for client ResourceClient
	ResourceServer ResourceServer

	// ResourceQuotaLimitsServer contains the fakes for client ResourceQuotaLimitsClient
	ResourceQuotaLimitsServer ResourceQuotaLimitsServer

	// ResourceRegionInfosServer contains the fakes for client ResourceRegionInfosClient
	ResourceRegionInfosServer ResourceRegionInfosServer

	// ResourceUsagesServer contains the fakes for client ResourceUsagesClient
	ResourceUsagesServer ResourceUsagesServer

	// SnapshotPoliciesServer contains the fakes for client SnapshotPoliciesClient
	SnapshotPoliciesServer SnapshotPoliciesServer

	// SnapshotsServer contains the fakes for client SnapshotsClient
	SnapshotsServer SnapshotsServer

	// SubvolumesServer contains the fakes for client SubvolumesClient
	SubvolumesServer SubvolumesServer

	// VolumeGroupsServer contains the fakes for client VolumeGroupsClient
	VolumeGroupsServer VolumeGroupsServer

	// VolumeQuotaRulesServer contains the fakes for client VolumeQuotaRulesClient
	VolumeQuotaRulesServer VolumeQuotaRulesServer

	// VolumesServer contains the fakes for client VolumesClient
	VolumesServer VolumesServer
}

// NewServerFactoryTransport creates a new instance of ServerFactoryTransport with the provided implementation.
// The returned ServerFactoryTransport instance is connected to an instance of armnetapp.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 armnetapp.ClientFactory to instances of ServerFactory.
// Don't use this type directly, use NewServerFactoryTransport instead.
type ServerFactoryTransport struct {
	srv                             *ServerFactory
	trMu                            sync.Mutex
	trAccountsServer                *AccountsServerTransport
	trBackupPoliciesServer          *BackupPoliciesServerTransport
	trBackupVaultsServer            *BackupVaultsServerTransport
	trBackupsServer                 *BackupsServerTransport
	trBackupsUnderAccountServer     *BackupsUnderAccountServerTransport
	trBackupsUnderBackupVaultServer *BackupsUnderBackupVaultServerTransport
	trBackupsUnderVolumeServer      *BackupsUnderVolumeServerTransport
	trOperationsServer              *OperationsServerTransport
	trPoolsServer                   *PoolsServerTransport
	trResourceServer                *ResourceServerTransport
	trResourceQuotaLimitsServer     *ResourceQuotaLimitsServerTransport
	trResourceRegionInfosServer     *ResourceRegionInfosServerTransport
	trResourceUsagesServer          *ResourceUsagesServerTransport
	trSnapshotPoliciesServer        *SnapshotPoliciesServerTransport
	trSnapshotsServer               *SnapshotsServerTransport
	trSubvolumesServer              *SubvolumesServerTransport
	trVolumeGroupsServer            *VolumeGroupsServerTransport
	trVolumeQuotaRulesServer        *VolumeQuotaRulesServerTransport
	trVolumesServer                 *VolumesServerTransport
}

// 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, &s.trAccountsServer, func() *AccountsServerTransport { return NewAccountsServerTransport(&s.srv.AccountsServer) })
		resp, err = s.trAccountsServer.Do(req)
	case "BackupPoliciesClient":
		initServer(s, &s.trBackupPoliciesServer, func() *BackupPoliciesServerTransport {
			return NewBackupPoliciesServerTransport(&s.srv.BackupPoliciesServer)
		})
		resp, err = s.trBackupPoliciesServer.Do(req)
	case "BackupVaultsClient":
		initServer(s, &s.trBackupVaultsServer, func() *BackupVaultsServerTransport { return NewBackupVaultsServerTransport(&s.srv.BackupVaultsServer) })
		resp, err = s.trBackupVaultsServer.Do(req)
	case "BackupsClient":
		initServer(s, &s.trBackupsServer, func() *BackupsServerTransport { return NewBackupsServerTransport(&s.srv.BackupsServer) })
		resp, err = s.trBackupsServer.Do(req)
	case "BackupsUnderAccountClient":
		initServer(s, &s.trBackupsUnderAccountServer, func() *BackupsUnderAccountServerTransport {
			return NewBackupsUnderAccountServerTransport(&s.srv.BackupsUnderAccountServer)
		})
		resp, err = s.trBackupsUnderAccountServer.Do(req)
	case "BackupsUnderBackupVaultClient":
		initServer(s, &s.trBackupsUnderBackupVaultServer, func() *BackupsUnderBackupVaultServerTransport {
			return NewBackupsUnderBackupVaultServerTransport(&s.srv.BackupsUnderBackupVaultServer)
		})
		resp, err = s.trBackupsUnderBackupVaultServer.Do(req)
	case "BackupsUnderVolumeClient":
		initServer(s, &s.trBackupsUnderVolumeServer, func() *BackupsUnderVolumeServerTransport {
			return NewBackupsUnderVolumeServerTransport(&s.srv.BackupsUnderVolumeServer)
		})
		resp, err = s.trBackupsUnderVolumeServer.Do(req)
	case "OperationsClient":
		initServer(s, &s.trOperationsServer, func() *OperationsServerTransport { return NewOperationsServerTransport(&s.srv.OperationsServer) })
		resp, err = s.trOperationsServer.Do(req)
	case "PoolsClient":
		initServer(s, &s.trPoolsServer, func() *PoolsServerTransport { return NewPoolsServerTransport(&s.srv.PoolsServer) })
		resp, err = s.trPoolsServer.Do(req)
	case "ResourceClient":
		initServer(s, &s.trResourceServer, func() *ResourceServerTransport { return NewResourceServerTransport(&s.srv.ResourceServer) })
		resp, err = s.trResourceServer.Do(req)
	case "ResourceQuotaLimitsClient":
		initServer(s, &s.trResourceQuotaLimitsServer, func() *ResourceQuotaLimitsServerTransport {
			return NewResourceQuotaLimitsServerTransport(&s.srv.ResourceQuotaLimitsServer)
		})
		resp, err = s.trResourceQuotaLimitsServer.Do(req)
	case "ResourceRegionInfosClient":
		initServer(s, &s.trResourceRegionInfosServer, func() *ResourceRegionInfosServerTransport {
			return NewResourceRegionInfosServerTransport(&s.srv.ResourceRegionInfosServer)
		})
		resp, err = s.trResourceRegionInfosServer.Do(req)
	case "ResourceUsagesClient":
		initServer(s, &s.trResourceUsagesServer, func() *ResourceUsagesServerTransport {
			return NewResourceUsagesServerTransport(&s.srv.ResourceUsagesServer)
		})
		resp, err = s.trResourceUsagesServer.Do(req)
	case "SnapshotPoliciesClient":
		initServer(s, &s.trSnapshotPoliciesServer, func() *SnapshotPoliciesServerTransport {
			return NewSnapshotPoliciesServerTransport(&s.srv.SnapshotPoliciesServer)
		})
		resp, err = s.trSnapshotPoliciesServer.Do(req)
	case "SnapshotsClient":
		initServer(s, &s.trSnapshotsServer, func() *SnapshotsServerTransport { return NewSnapshotsServerTransport(&s.srv.SnapshotsServer) })
		resp, err = s.trSnapshotsServer.Do(req)
	case "SubvolumesClient":
		initServer(s, &s.trSubvolumesServer, func() *SubvolumesServerTransport { return NewSubvolumesServerTransport(&s.srv.SubvolumesServer) })
		resp, err = s.trSubvolumesServer.Do(req)
	case "VolumeGroupsClient":
		initServer(s, &s.trVolumeGroupsServer, func() *VolumeGroupsServerTransport { return NewVolumeGroupsServerTransport(&s.srv.VolumeGroupsServer) })
		resp, err = s.trVolumeGroupsServer.Do(req)
	case "VolumeQuotaRulesClient":
		initServer(s, &s.trVolumeQuotaRulesServer, func() *VolumeQuotaRulesServerTransport {
			return NewVolumeQuotaRulesServerTransport(&s.srv.VolumeQuotaRulesServer)
		})
		resp, err = s.trVolumeQuotaRulesServer.Do(req)
	case "VolumesClient":
		initServer(s, &s.trVolumesServer, func() *VolumesServerTransport { return NewVolumesServerTransport(&s.srv.VolumesServer) })
		resp, err = s.trVolumesServer.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()
}
