// 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 armworkloadorchestration.ClientFactory type.
type ServerFactory struct {
	// ConfigTemplateVersionsServer contains the fakes for client ConfigTemplateVersionsClient
	ConfigTemplateVersionsServer ConfigTemplateVersionsServer

	// ConfigTemplatesServer contains the fakes for client ConfigTemplatesClient
	ConfigTemplatesServer ConfigTemplatesServer

	// ContextsServer contains the fakes for client ContextsClient
	ContextsServer ContextsServer

	// DiagnosticsServer contains the fakes for client DiagnosticsClient
	DiagnosticsServer DiagnosticsServer

	// DynamicSchemaVersionsServer contains the fakes for client DynamicSchemaVersionsClient
	DynamicSchemaVersionsServer DynamicSchemaVersionsServer

	// DynamicSchemasServer contains the fakes for client DynamicSchemasClient
	DynamicSchemasServer DynamicSchemasServer

	// ExecutionsServer contains the fakes for client ExecutionsClient
	ExecutionsServer ExecutionsServer

	// InstanceHistoriesServer contains the fakes for client InstanceHistoriesClient
	InstanceHistoriesServer InstanceHistoriesServer

	// InstancesServer contains the fakes for client InstancesClient
	InstancesServer InstancesServer

	// JobsServer contains the fakes for client JobsClient
	JobsServer JobsServer

	// SchemaReferencesServer contains the fakes for client SchemaReferencesClient
	SchemaReferencesServer SchemaReferencesServer

	// SchemaVersionsServer contains the fakes for client SchemaVersionsClient
	SchemaVersionsServer SchemaVersionsServer

	// SchemasServer contains the fakes for client SchemasClient
	SchemasServer SchemasServer

	// SiteReferencesServer contains the fakes for client SiteReferencesClient
	SiteReferencesServer SiteReferencesServer

	// SolutionTemplateVersionsServer contains the fakes for client SolutionTemplateVersionsClient
	SolutionTemplateVersionsServer SolutionTemplateVersionsServer

	// SolutionTemplatesServer contains the fakes for client SolutionTemplatesClient
	SolutionTemplatesServer SolutionTemplatesServer

	// SolutionVersionsServer contains the fakes for client SolutionVersionsClient
	SolutionVersionsServer SolutionVersionsServer

	// SolutionsServer contains the fakes for client SolutionsClient
	SolutionsServer SolutionsServer

	// TargetsServer contains the fakes for client TargetsClient
	TargetsServer TargetsServer

	// WorkflowVersionsServer contains the fakes for client WorkflowVersionsClient
	WorkflowVersionsServer WorkflowVersionsServer

	// WorkflowsServer contains the fakes for client WorkflowsClient
	WorkflowsServer WorkflowsServer
}

// NewServerFactoryTransport creates a new instance of ServerFactoryTransport with the provided implementation.
// The returned ServerFactoryTransport instance is connected to an instance of armworkloadorchestration.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 armworkloadorchestration.ClientFactory to instances of ServerFactory.
// Don't use this type directly, use NewServerFactoryTransport instead.
type ServerFactoryTransport struct {
	srv                              *ServerFactory
	trMu                             sync.Mutex
	trConfigTemplateVersionsServer   *ConfigTemplateVersionsServerTransport
	trConfigTemplatesServer          *ConfigTemplatesServerTransport
	trContextsServer                 *ContextsServerTransport
	trDiagnosticsServer              *DiagnosticsServerTransport
	trDynamicSchemaVersionsServer    *DynamicSchemaVersionsServerTransport
	trDynamicSchemasServer           *DynamicSchemasServerTransport
	trExecutionsServer               *ExecutionsServerTransport
	trInstanceHistoriesServer        *InstanceHistoriesServerTransport
	trInstancesServer                *InstancesServerTransport
	trJobsServer                     *JobsServerTransport
	trSchemaReferencesServer         *SchemaReferencesServerTransport
	trSchemaVersionsServer           *SchemaVersionsServerTransport
	trSchemasServer                  *SchemasServerTransport
	trSiteReferencesServer           *SiteReferencesServerTransport
	trSolutionTemplateVersionsServer *SolutionTemplateVersionsServerTransport
	trSolutionTemplatesServer        *SolutionTemplatesServerTransport
	trSolutionVersionsServer         *SolutionVersionsServerTransport
	trSolutionsServer                *SolutionsServerTransport
	trTargetsServer                  *TargetsServerTransport
	trWorkflowVersionsServer         *WorkflowVersionsServerTransport
	trWorkflowsServer                *WorkflowsServerTransport
}

// 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 "ConfigTemplateVersionsClient":
		initServer(s, &s.trConfigTemplateVersionsServer, func() *ConfigTemplateVersionsServerTransport {
			return NewConfigTemplateVersionsServerTransport(&s.srv.ConfigTemplateVersionsServer)
		})
		resp, err = s.trConfigTemplateVersionsServer.Do(req)
	case "ConfigTemplatesClient":
		initServer(s, &s.trConfigTemplatesServer, func() *ConfigTemplatesServerTransport {
			return NewConfigTemplatesServerTransport(&s.srv.ConfigTemplatesServer)
		})
		resp, err = s.trConfigTemplatesServer.Do(req)
	case "ContextsClient":
		initServer(s, &s.trContextsServer, func() *ContextsServerTransport { return NewContextsServerTransport(&s.srv.ContextsServer) })
		resp, err = s.trContextsServer.Do(req)
	case "DiagnosticsClient":
		initServer(s, &s.trDiagnosticsServer, func() *DiagnosticsServerTransport { return NewDiagnosticsServerTransport(&s.srv.DiagnosticsServer) })
		resp, err = s.trDiagnosticsServer.Do(req)
	case "DynamicSchemaVersionsClient":
		initServer(s, &s.trDynamicSchemaVersionsServer, func() *DynamicSchemaVersionsServerTransport {
			return NewDynamicSchemaVersionsServerTransport(&s.srv.DynamicSchemaVersionsServer)
		})
		resp, err = s.trDynamicSchemaVersionsServer.Do(req)
	case "DynamicSchemasClient":
		initServer(s, &s.trDynamicSchemasServer, func() *DynamicSchemasServerTransport {
			return NewDynamicSchemasServerTransport(&s.srv.DynamicSchemasServer)
		})
		resp, err = s.trDynamicSchemasServer.Do(req)
	case "ExecutionsClient":
		initServer(s, &s.trExecutionsServer, func() *ExecutionsServerTransport { return NewExecutionsServerTransport(&s.srv.ExecutionsServer) })
		resp, err = s.trExecutionsServer.Do(req)
	case "InstanceHistoriesClient":
		initServer(s, &s.trInstanceHistoriesServer, func() *InstanceHistoriesServerTransport {
			return NewInstanceHistoriesServerTransport(&s.srv.InstanceHistoriesServer)
		})
		resp, err = s.trInstanceHistoriesServer.Do(req)
	case "InstancesClient":
		initServer(s, &s.trInstancesServer, func() *InstancesServerTransport { return NewInstancesServerTransport(&s.srv.InstancesServer) })
		resp, err = s.trInstancesServer.Do(req)
	case "JobsClient":
		initServer(s, &s.trJobsServer, func() *JobsServerTransport { return NewJobsServerTransport(&s.srv.JobsServer) })
		resp, err = s.trJobsServer.Do(req)
	case "SchemaReferencesClient":
		initServer(s, &s.trSchemaReferencesServer, func() *SchemaReferencesServerTransport {
			return NewSchemaReferencesServerTransport(&s.srv.SchemaReferencesServer)
		})
		resp, err = s.trSchemaReferencesServer.Do(req)
	case "SchemaVersionsClient":
		initServer(s, &s.trSchemaVersionsServer, func() *SchemaVersionsServerTransport {
			return NewSchemaVersionsServerTransport(&s.srv.SchemaVersionsServer)
		})
		resp, err = s.trSchemaVersionsServer.Do(req)
	case "SchemasClient":
		initServer(s, &s.trSchemasServer, func() *SchemasServerTransport { return NewSchemasServerTransport(&s.srv.SchemasServer) })
		resp, err = s.trSchemasServer.Do(req)
	case "SiteReferencesClient":
		initServer(s, &s.trSiteReferencesServer, func() *SiteReferencesServerTransport {
			return NewSiteReferencesServerTransport(&s.srv.SiteReferencesServer)
		})
		resp, err = s.trSiteReferencesServer.Do(req)
	case "SolutionTemplateVersionsClient":
		initServer(s, &s.trSolutionTemplateVersionsServer, func() *SolutionTemplateVersionsServerTransport {
			return NewSolutionTemplateVersionsServerTransport(&s.srv.SolutionTemplateVersionsServer)
		})
		resp, err = s.trSolutionTemplateVersionsServer.Do(req)
	case "SolutionTemplatesClient":
		initServer(s, &s.trSolutionTemplatesServer, func() *SolutionTemplatesServerTransport {
			return NewSolutionTemplatesServerTransport(&s.srv.SolutionTemplatesServer)
		})
		resp, err = s.trSolutionTemplatesServer.Do(req)
	case "SolutionVersionsClient":
		initServer(s, &s.trSolutionVersionsServer, func() *SolutionVersionsServerTransport {
			return NewSolutionVersionsServerTransport(&s.srv.SolutionVersionsServer)
		})
		resp, err = s.trSolutionVersionsServer.Do(req)
	case "SolutionsClient":
		initServer(s, &s.trSolutionsServer, func() *SolutionsServerTransport { return NewSolutionsServerTransport(&s.srv.SolutionsServer) })
		resp, err = s.trSolutionsServer.Do(req)
	case "TargetsClient":
		initServer(s, &s.trTargetsServer, func() *TargetsServerTransport { return NewTargetsServerTransport(&s.srv.TargetsServer) })
		resp, err = s.trTargetsServer.Do(req)
	case "WorkflowVersionsClient":
		initServer(s, &s.trWorkflowVersionsServer, func() *WorkflowVersionsServerTransport {
			return NewWorkflowVersionsServerTransport(&s.srv.WorkflowVersionsServer)
		})
		resp, err = s.trWorkflowVersionsServer.Do(req)
	case "WorkflowsClient":
		initServer(s, &s.trWorkflowsServer, func() *WorkflowsServerTransport { return NewWorkflowsServerTransport(&s.srv.WorkflowsServer) })
		resp, err = s.trWorkflowsServer.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()
}
