// Licensed to the Apache Software Foundation (ASF) under one or more
// contributor license agreements.  See the NOTICE file distributed with
// this work for additional information regarding copyright ownership.
// The ASF licenses this file to You under the Apache License, Version 2.0
// (the "License"); you may not use this file except in compliance with
// the License.  You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// Code generated by protoc-gen-connect-go. DO NOT EDIT.
//
// Source: registry/v1alpha1/recommendation.proto

package registryv1alpha1connect

import (
	context "context"
	errors "errors"
	http "net/http"
	strings "strings"
)

import (
	connect_go "github.com/bufbuild/connect-go"
)

import (
	v1alpha1 "github.com/apache/dubbo-kubernetes/pkg/bufman/gen/proto/go/registry/v1alpha1"
)

// This is a compile-time assertion to ensure that this generated file and the connect package are
// compatible. If you get a compiler error that this constant is not defined, this code was
// generated with a version of connect newer than the one compiled into your binary. You can fix the
// problem by either regenerating this code with an older version of connect or updating the connect
// version compiled into your binary.
const _ = connect_go.IsAtLeastVersion1_7_0

const (
	// RecommendationServiceName is the fully-qualified name of the RecommendationService service.
	RecommendationServiceName = "bufman.dubbo.apache.org.registry.v1alpha1.RecommendationService"
)

// These constants are the fully-qualified names of the RPCs defined in this package. They're
// exposed at runtime as Spec.Procedure and as the final two segments of the HTTP route.
//
// Note that these are different from the fully-qualified method names used by
// google.golang.org/protobuf/reflect/protoreflect. To convert from these constants to
// reflection-formatted method names, remove the leading slash and convert the remaining slash to a
// period.
const (
	// RecommendationServiceRecommendedRepositoriesProcedure is the fully-qualified name of the
	// RecommendationService's RecommendedRepositories RPC.
	RecommendationServiceRecommendedRepositoriesProcedure = "/bufman.dubbo.apache.org.registry.v1alpha1.RecommendationService/RecommendedRepositories"
	// RecommendationServiceRecommendedTemplatesProcedure is the fully-qualified name of the
	// RecommendationService's RecommendedTemplates RPC.
	RecommendationServiceRecommendedTemplatesProcedure = "/bufman.dubbo.apache.org.registry.v1alpha1.RecommendationService/RecommendedTemplates"
	// RecommendationServiceListRecommendedResourcesProcedure is the fully-qualified name of the
	// RecommendationService's ListRecommendedResources RPC.
	RecommendationServiceListRecommendedResourcesProcedure = "/bufman.dubbo.apache.org.registry.v1alpha1.RecommendationService/ListRecommendedResources"
	// RecommendationServiceSetRecommendedResourcesProcedure is the fully-qualified name of the
	// RecommendationService's SetRecommendedResources RPC.
	RecommendationServiceSetRecommendedResourcesProcedure = "/bufman.dubbo.apache.org.registry.v1alpha1.RecommendationService/SetRecommendedResources"
)

// RecommendationServiceClient is a client for the
// bufman.dubbo.apache.org.registry.v1alpha1.RecommendationService service.
type RecommendationServiceClient interface {
	// RecommendedRepositories returns a list of recommended repositories.
	RecommendedRepositories(context.Context, *connect_go.Request[v1alpha1.RecommendedRepositoriesRequest]) (*connect_go.Response[v1alpha1.RecommendedRepositoriesResponse], error)
	// RecommendedTemplates returns a list of recommended templates.
	//
	// Deprecated: do not use.
	RecommendedTemplates(context.Context, *connect_go.Request[v1alpha1.RecommendedTemplatesRequest]) (*connect_go.Response[v1alpha1.RecommendedTemplatesResponse], error)
	// ListRecommendedResources returns a list of recommended resources.
	ListRecommendedResources(context.Context, *connect_go.Request[v1alpha1.ListRecommendedResourcesRequest]) (*connect_go.Response[v1alpha1.ListRecommendedResourcesResponse], error)
	// SetRecommendedResources set the list of recommended resources in the server.
	SetRecommendedResources(context.Context, *connect_go.Request[v1alpha1.SetRecommendedResourcesRequest]) (*connect_go.Response[v1alpha1.SetRecommendedResourcesResponse], error)
}

// NewRecommendationServiceClient constructs a client for the
// bufman.dubbo.apache.org.registry.v1alpha1.RecommendationService service. By default, it uses the
// Connect protocol with the binary Protobuf Codec, asks for gzipped responses, and sends
// uncompressed requests. To use the gRPC or gRPC-Web protocols, supply the connect.WithGRPC() or
// connect.WithGRPCWeb() options.
//
// The URL supplied here should be the base URL for the Connect or gRPC server (for example,
// http://api.acme.com or https://acme.com/grpc).
func NewRecommendationServiceClient(httpClient connect_go.HTTPClient, baseURL string, opts ...connect_go.ClientOption) RecommendationServiceClient {
	baseURL = strings.TrimRight(baseURL, "/")
	return &recommendationServiceClient{
		recommendedRepositories: connect_go.NewClient[v1alpha1.RecommendedRepositoriesRequest, v1alpha1.RecommendedRepositoriesResponse](
			httpClient,
			baseURL+RecommendationServiceRecommendedRepositoriesProcedure,
			connect_go.WithIdempotency(connect_go.IdempotencyNoSideEffects),
			connect_go.WithClientOptions(opts...),
		),
		recommendedTemplates: connect_go.NewClient[v1alpha1.RecommendedTemplatesRequest, v1alpha1.RecommendedTemplatesResponse](
			httpClient,
			baseURL+RecommendationServiceRecommendedTemplatesProcedure,
			connect_go.WithIdempotency(connect_go.IdempotencyNoSideEffects),
			connect_go.WithClientOptions(opts...),
		),
		listRecommendedResources: connect_go.NewClient[v1alpha1.ListRecommendedResourcesRequest, v1alpha1.ListRecommendedResourcesResponse](
			httpClient,
			baseURL+RecommendationServiceListRecommendedResourcesProcedure,
			connect_go.WithIdempotency(connect_go.IdempotencyNoSideEffects),
			connect_go.WithClientOptions(opts...),
		),
		setRecommendedResources: connect_go.NewClient[v1alpha1.SetRecommendedResourcesRequest, v1alpha1.SetRecommendedResourcesResponse](
			httpClient,
			baseURL+RecommendationServiceSetRecommendedResourcesProcedure,
			connect_go.WithIdempotency(connect_go.IdempotencyIdempotent),
			connect_go.WithClientOptions(opts...),
		),
	}
}

// recommendationServiceClient implements RecommendationServiceClient.
type recommendationServiceClient struct {
	recommendedRepositories  *connect_go.Client[v1alpha1.RecommendedRepositoriesRequest, v1alpha1.RecommendedRepositoriesResponse]
	recommendedTemplates     *connect_go.Client[v1alpha1.RecommendedTemplatesRequest, v1alpha1.RecommendedTemplatesResponse]
	listRecommendedResources *connect_go.Client[v1alpha1.ListRecommendedResourcesRequest, v1alpha1.ListRecommendedResourcesResponse]
	setRecommendedResources  *connect_go.Client[v1alpha1.SetRecommendedResourcesRequest, v1alpha1.SetRecommendedResourcesResponse]
}

// RecommendedRepositories calls
// bufman.dubbo.apache.org.registry.v1alpha1.RecommendationService.RecommendedRepositories.
func (c *recommendationServiceClient) RecommendedRepositories(ctx context.Context, req *connect_go.Request[v1alpha1.RecommendedRepositoriesRequest]) (*connect_go.Response[v1alpha1.RecommendedRepositoriesResponse], error) {
	return c.recommendedRepositories.CallUnary(ctx, req)
}

// RecommendedTemplates calls
// bufman.dubbo.apache.org.registry.v1alpha1.RecommendationService.RecommendedTemplates.
//
// Deprecated: do not use.
func (c *recommendationServiceClient) RecommendedTemplates(ctx context.Context, req *connect_go.Request[v1alpha1.RecommendedTemplatesRequest]) (*connect_go.Response[v1alpha1.RecommendedTemplatesResponse], error) {
	return c.recommendedTemplates.CallUnary(ctx, req)
}

// ListRecommendedResources calls
// bufman.dubbo.apache.org.registry.v1alpha1.RecommendationService.ListRecommendedResources.
func (c *recommendationServiceClient) ListRecommendedResources(ctx context.Context, req *connect_go.Request[v1alpha1.ListRecommendedResourcesRequest]) (*connect_go.Response[v1alpha1.ListRecommendedResourcesResponse], error) {
	return c.listRecommendedResources.CallUnary(ctx, req)
}

// SetRecommendedResources calls
// bufman.dubbo.apache.org.registry.v1alpha1.RecommendationService.SetRecommendedResources.
func (c *recommendationServiceClient) SetRecommendedResources(ctx context.Context, req *connect_go.Request[v1alpha1.SetRecommendedResourcesRequest]) (*connect_go.Response[v1alpha1.SetRecommendedResourcesResponse], error) {
	return c.setRecommendedResources.CallUnary(ctx, req)
}

// RecommendationServiceHandler is an implementation of the
// bufman.dubbo.apache.org.registry.v1alpha1.RecommendationService service.
type RecommendationServiceHandler interface {
	// RecommendedRepositories returns a list of recommended repositories.
	RecommendedRepositories(context.Context, *connect_go.Request[v1alpha1.RecommendedRepositoriesRequest]) (*connect_go.Response[v1alpha1.RecommendedRepositoriesResponse], error)
	// RecommendedTemplates returns a list of recommended templates.
	//
	// Deprecated: do not use.
	RecommendedTemplates(context.Context, *connect_go.Request[v1alpha1.RecommendedTemplatesRequest]) (*connect_go.Response[v1alpha1.RecommendedTemplatesResponse], error)
	// ListRecommendedResources returns a list of recommended resources.
	ListRecommendedResources(context.Context, *connect_go.Request[v1alpha1.ListRecommendedResourcesRequest]) (*connect_go.Response[v1alpha1.ListRecommendedResourcesResponse], error)
	// SetRecommendedResources set the list of recommended resources in the server.
	SetRecommendedResources(context.Context, *connect_go.Request[v1alpha1.SetRecommendedResourcesRequest]) (*connect_go.Response[v1alpha1.SetRecommendedResourcesResponse], error)
}

// NewRecommendationServiceHandler builds an HTTP handler from the service implementation. It
// returns the path on which to mount the handler and the handler itself.
//
// By default, handlers support the Connect, gRPC, and gRPC-Web protocols with the binary Protobuf
// and JSON codecs. They also support gzip compression.
func NewRecommendationServiceHandler(svc RecommendationServiceHandler, opts ...connect_go.HandlerOption) (string, http.Handler) {
	recommendationServiceRecommendedRepositoriesHandler := connect_go.NewUnaryHandler(
		RecommendationServiceRecommendedRepositoriesProcedure,
		svc.RecommendedRepositories,
		connect_go.WithIdempotency(connect_go.IdempotencyNoSideEffects),
		connect_go.WithHandlerOptions(opts...),
	)
	recommendationServiceRecommendedTemplatesHandler := connect_go.NewUnaryHandler(
		RecommendationServiceRecommendedTemplatesProcedure,
		svc.RecommendedTemplates,
		connect_go.WithIdempotency(connect_go.IdempotencyNoSideEffects),
		connect_go.WithHandlerOptions(opts...),
	)
	recommendationServiceListRecommendedResourcesHandler := connect_go.NewUnaryHandler(
		RecommendationServiceListRecommendedResourcesProcedure,
		svc.ListRecommendedResources,
		connect_go.WithIdempotency(connect_go.IdempotencyNoSideEffects),
		connect_go.WithHandlerOptions(opts...),
	)
	recommendationServiceSetRecommendedResourcesHandler := connect_go.NewUnaryHandler(
		RecommendationServiceSetRecommendedResourcesProcedure,
		svc.SetRecommendedResources,
		connect_go.WithIdempotency(connect_go.IdempotencyIdempotent),
		connect_go.WithHandlerOptions(opts...),
	)
	return "/bufman.dubbo.apache.org.registry.v1alpha1.RecommendationService/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		switch r.URL.Path {
		case RecommendationServiceRecommendedRepositoriesProcedure:
			recommendationServiceRecommendedRepositoriesHandler.ServeHTTP(w, r)
		case RecommendationServiceRecommendedTemplatesProcedure:
			recommendationServiceRecommendedTemplatesHandler.ServeHTTP(w, r)
		case RecommendationServiceListRecommendedResourcesProcedure:
			recommendationServiceListRecommendedResourcesHandler.ServeHTTP(w, r)
		case RecommendationServiceSetRecommendedResourcesProcedure:
			recommendationServiceSetRecommendedResourcesHandler.ServeHTTP(w, r)
		default:
			http.NotFound(w, r)
		}
	})
}

// UnimplementedRecommendationServiceHandler returns CodeUnimplemented from all methods.
type UnimplementedRecommendationServiceHandler struct{}

func (UnimplementedRecommendationServiceHandler) RecommendedRepositories(context.Context, *connect_go.Request[v1alpha1.RecommendedRepositoriesRequest]) (*connect_go.Response[v1alpha1.RecommendedRepositoriesResponse], error) {
	return nil, connect_go.NewError(connect_go.CodeUnimplemented, errors.New("bufman.dubbo.apache.org.registry.v1alpha1.RecommendationService.RecommendedRepositories is not implemented"))
}

func (UnimplementedRecommendationServiceHandler) RecommendedTemplates(context.Context, *connect_go.Request[v1alpha1.RecommendedTemplatesRequest]) (*connect_go.Response[v1alpha1.RecommendedTemplatesResponse], error) {
	return nil, connect_go.NewError(connect_go.CodeUnimplemented, errors.New("bufman.dubbo.apache.org.registry.v1alpha1.RecommendationService.RecommendedTemplates is not implemented"))
}

func (UnimplementedRecommendationServiceHandler) ListRecommendedResources(context.Context, *connect_go.Request[v1alpha1.ListRecommendedResourcesRequest]) (*connect_go.Response[v1alpha1.ListRecommendedResourcesResponse], error) {
	return nil, connect_go.NewError(connect_go.CodeUnimplemented, errors.New("bufman.dubbo.apache.org.registry.v1alpha1.RecommendationService.ListRecommendedResources is not implemented"))
}

func (UnimplementedRecommendationServiceHandler) SetRecommendedResources(context.Context, *connect_go.Request[v1alpha1.SetRecommendedResourcesRequest]) (*connect_go.Response[v1alpha1.SetRecommendedResourcesResponse], error) {
	return nil, connect_go.NewError(connect_go.CodeUnimplemented, errors.New("bufman.dubbo.apache.org.registry.v1alpha1.RecommendationService.SetRecommendedResources is not implemented"))
}
