// TenancyService and ProjectsService -- public IA-parity surface over
// fraser's existing customers / projects / project_members tables.
//
// Two services to mirror IA's split:
//   - TenancyService handles customers (the top-level tenant).
//   - ProjectsService handles per-customer projects + their members.
//
// Underlying data lives in the same rows fraser's admin.v1 service
// already manages (svc/internal/staff/valet/fraser/repository/customer*
// + project* + project_member*). Handlers here are a thin REST/CLI
// facade over those repositories -- no parallel SQL.
//
// CLI commands are surfaced under `ia customers ...` and `ia projects
// ...` so the muscle memory matches IA's reference CLI.

// Code generated by protoc-gen-connect-go. DO NOT EDIT.
//
// Source: tars/tenancy/v1/tenancy_service.proto

package tenancyv1connect

import (
	connect "connectrpc.com/connect"
	context "context"
	errors "errors"
	v1 "github.com/tetrateio/agentrouter-go/genapi/api/tars/tenancy/v1"
	emptypb "google.golang.org/protobuf/types/known/emptypb"
	http "net/http"
	strings "strings"
)

// 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.IsAtLeastVersion1_13_0

const (
	// TenancyServiceName is the fully-qualified name of the TenancyService service.
	TenancyServiceName = "tars.tenancy.v1.TenancyService"
	// ProjectsServiceName is the fully-qualified name of the ProjectsService service.
	ProjectsServiceName = "tars.tenancy.v1.ProjectsService"
)

// 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 (
	// TenancyServiceCreateCustomerProcedure is the fully-qualified name of the TenancyService's
	// CreateCustomer RPC.
	TenancyServiceCreateCustomerProcedure = "/tars.tenancy.v1.TenancyService/CreateCustomer"
	// TenancyServiceGetCustomerProcedure is the fully-qualified name of the TenancyService's
	// GetCustomer RPC.
	TenancyServiceGetCustomerProcedure = "/tars.tenancy.v1.TenancyService/GetCustomer"
	// TenancyServiceListCustomersProcedure is the fully-qualified name of the TenancyService's
	// ListCustomers RPC.
	TenancyServiceListCustomersProcedure = "/tars.tenancy.v1.TenancyService/ListCustomers"
	// TenancyServiceUpdateCustomerProcedure is the fully-qualified name of the TenancyService's
	// UpdateCustomer RPC.
	TenancyServiceUpdateCustomerProcedure = "/tars.tenancy.v1.TenancyService/UpdateCustomer"
	// TenancyServiceArchiveCustomerProcedure is the fully-qualified name of the TenancyService's
	// ArchiveCustomer RPC.
	TenancyServiceArchiveCustomerProcedure = "/tars.tenancy.v1.TenancyService/ArchiveCustomer"
	// ProjectsServiceCreateProjectProcedure is the fully-qualified name of the ProjectsService's
	// CreateProject RPC.
	ProjectsServiceCreateProjectProcedure = "/tars.tenancy.v1.ProjectsService/CreateProject"
	// ProjectsServiceGetProjectProcedure is the fully-qualified name of the ProjectsService's
	// GetProject RPC.
	ProjectsServiceGetProjectProcedure = "/tars.tenancy.v1.ProjectsService/GetProject"
	// ProjectsServiceListProjectsProcedure is the fully-qualified name of the ProjectsService's
	// ListProjects RPC.
	ProjectsServiceListProjectsProcedure = "/tars.tenancy.v1.ProjectsService/ListProjects"
	// ProjectsServiceUpdateProjectProcedure is the fully-qualified name of the ProjectsService's
	// UpdateProject RPC.
	ProjectsServiceUpdateProjectProcedure = "/tars.tenancy.v1.ProjectsService/UpdateProject"
	// ProjectsServiceArchiveProjectProcedure is the fully-qualified name of the ProjectsService's
	// ArchiveProject RPC.
	ProjectsServiceArchiveProjectProcedure = "/tars.tenancy.v1.ProjectsService/ArchiveProject"
	// ProjectsServiceAddProjectMemberProcedure is the fully-qualified name of the ProjectsService's
	// AddProjectMember RPC.
	ProjectsServiceAddProjectMemberProcedure = "/tars.tenancy.v1.ProjectsService/AddProjectMember"
	// ProjectsServiceListProjectMembersProcedure is the fully-qualified name of the ProjectsService's
	// ListProjectMembers RPC.
	ProjectsServiceListProjectMembersProcedure = "/tars.tenancy.v1.ProjectsService/ListProjectMembers"
	// ProjectsServiceUpdateProjectMemberProcedure is the fully-qualified name of the ProjectsService's
	// UpdateProjectMember RPC.
	ProjectsServiceUpdateProjectMemberProcedure = "/tars.tenancy.v1.ProjectsService/UpdateProjectMember"
	// ProjectsServiceRemoveProjectMemberProcedure is the fully-qualified name of the ProjectsService's
	// RemoveProjectMember RPC.
	ProjectsServiceRemoveProjectMemberProcedure = "/tars.tenancy.v1.ProjectsService/RemoveProjectMember"
)

// TenancyServiceClient is a client for the tars.tenancy.v1.TenancyService service.
type TenancyServiceClient interface {
	// CreateCustomer creates a new customer record. A customer owns
	// projects, identities, and billing. Typically called once during
	// provisioning of a new tenant.
	CreateCustomer(context.Context, *connect.Request[v1.CreateCustomerRequest]) (*connect.Response[v1.Customer], error)
	// GetCustomer returns a single customer by id.
	GetCustomer(context.Context, *connect.Request[v1.GetCustomerRequest]) (*connect.Response[v1.Customer], error)
	// ListCustomers lists all customers visible to the caller.
	ListCustomers(context.Context, *connect.Request[v1.ListCustomersRequest]) (*connect.Response[v1.ListCustomersResponse], error)
	// UpdateCustomer updates mutable customer fields (display_name,
	// description, labels). `customer_id` is immutable.
	UpdateCustomer(context.Context, *connect.Request[v1.UpdateCustomerRequest]) (*connect.Response[v1.Customer], error)
	// ArchiveCustomer soft-deletes a customer. The row stays in the
	// database with deleted_at set; future Get / List calls treat it as
	// missing.
	ArchiveCustomer(context.Context, *connect.Request[v1.ArchiveCustomerRequest]) (*connect.Response[emptypb.Empty], error)
}

// NewTenancyServiceClient constructs a client for the tars.tenancy.v1.TenancyService 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 NewTenancyServiceClient(httpClient connect.HTTPClient, baseURL string, opts ...connect.ClientOption) TenancyServiceClient {
	baseURL = strings.TrimRight(baseURL, "/")
	tenancyServiceMethods := v1.File_tars_tenancy_v1_tenancy_service_proto.Services().ByName("TenancyService").Methods()
	return &tenancyServiceClient{
		createCustomer: connect.NewClient[v1.CreateCustomerRequest, v1.Customer](
			httpClient,
			baseURL+TenancyServiceCreateCustomerProcedure,
			connect.WithSchema(tenancyServiceMethods.ByName("CreateCustomer")),
			connect.WithClientOptions(opts...),
		),
		getCustomer: connect.NewClient[v1.GetCustomerRequest, v1.Customer](
			httpClient,
			baseURL+TenancyServiceGetCustomerProcedure,
			connect.WithSchema(tenancyServiceMethods.ByName("GetCustomer")),
			connect.WithIdempotency(connect.IdempotencyNoSideEffects),
			connect.WithClientOptions(opts...),
		),
		listCustomers: connect.NewClient[v1.ListCustomersRequest, v1.ListCustomersResponse](
			httpClient,
			baseURL+TenancyServiceListCustomersProcedure,
			connect.WithSchema(tenancyServiceMethods.ByName("ListCustomers")),
			connect.WithIdempotency(connect.IdempotencyNoSideEffects),
			connect.WithClientOptions(opts...),
		),
		updateCustomer: connect.NewClient[v1.UpdateCustomerRequest, v1.Customer](
			httpClient,
			baseURL+TenancyServiceUpdateCustomerProcedure,
			connect.WithSchema(tenancyServiceMethods.ByName("UpdateCustomer")),
			connect.WithClientOptions(opts...),
		),
		archiveCustomer: connect.NewClient[v1.ArchiveCustomerRequest, emptypb.Empty](
			httpClient,
			baseURL+TenancyServiceArchiveCustomerProcedure,
			connect.WithSchema(tenancyServiceMethods.ByName("ArchiveCustomer")),
			connect.WithClientOptions(opts...),
		),
	}
}

// tenancyServiceClient implements TenancyServiceClient.
type tenancyServiceClient struct {
	createCustomer  *connect.Client[v1.CreateCustomerRequest, v1.Customer]
	getCustomer     *connect.Client[v1.GetCustomerRequest, v1.Customer]
	listCustomers   *connect.Client[v1.ListCustomersRequest, v1.ListCustomersResponse]
	updateCustomer  *connect.Client[v1.UpdateCustomerRequest, v1.Customer]
	archiveCustomer *connect.Client[v1.ArchiveCustomerRequest, emptypb.Empty]
}

// CreateCustomer calls tars.tenancy.v1.TenancyService.CreateCustomer.
func (c *tenancyServiceClient) CreateCustomer(ctx context.Context, req *connect.Request[v1.CreateCustomerRequest]) (*connect.Response[v1.Customer], error) {
	return c.createCustomer.CallUnary(ctx, req)
}

// GetCustomer calls tars.tenancy.v1.TenancyService.GetCustomer.
func (c *tenancyServiceClient) GetCustomer(ctx context.Context, req *connect.Request[v1.GetCustomerRequest]) (*connect.Response[v1.Customer], error) {
	return c.getCustomer.CallUnary(ctx, req)
}

// ListCustomers calls tars.tenancy.v1.TenancyService.ListCustomers.
func (c *tenancyServiceClient) ListCustomers(ctx context.Context, req *connect.Request[v1.ListCustomersRequest]) (*connect.Response[v1.ListCustomersResponse], error) {
	return c.listCustomers.CallUnary(ctx, req)
}

// UpdateCustomer calls tars.tenancy.v1.TenancyService.UpdateCustomer.
func (c *tenancyServiceClient) UpdateCustomer(ctx context.Context, req *connect.Request[v1.UpdateCustomerRequest]) (*connect.Response[v1.Customer], error) {
	return c.updateCustomer.CallUnary(ctx, req)
}

// ArchiveCustomer calls tars.tenancy.v1.TenancyService.ArchiveCustomer.
func (c *tenancyServiceClient) ArchiveCustomer(ctx context.Context, req *connect.Request[v1.ArchiveCustomerRequest]) (*connect.Response[emptypb.Empty], error) {
	return c.archiveCustomer.CallUnary(ctx, req)
}

// TenancyServiceHandler is an implementation of the tars.tenancy.v1.TenancyService service.
type TenancyServiceHandler interface {
	// CreateCustomer creates a new customer record. A customer owns
	// projects, identities, and billing. Typically called once during
	// provisioning of a new tenant.
	CreateCustomer(context.Context, *connect.Request[v1.CreateCustomerRequest]) (*connect.Response[v1.Customer], error)
	// GetCustomer returns a single customer by id.
	GetCustomer(context.Context, *connect.Request[v1.GetCustomerRequest]) (*connect.Response[v1.Customer], error)
	// ListCustomers lists all customers visible to the caller.
	ListCustomers(context.Context, *connect.Request[v1.ListCustomersRequest]) (*connect.Response[v1.ListCustomersResponse], error)
	// UpdateCustomer updates mutable customer fields (display_name,
	// description, labels). `customer_id` is immutable.
	UpdateCustomer(context.Context, *connect.Request[v1.UpdateCustomerRequest]) (*connect.Response[v1.Customer], error)
	// ArchiveCustomer soft-deletes a customer. The row stays in the
	// database with deleted_at set; future Get / List calls treat it as
	// missing.
	ArchiveCustomer(context.Context, *connect.Request[v1.ArchiveCustomerRequest]) (*connect.Response[emptypb.Empty], error)
}

// NewTenancyServiceHandler 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 NewTenancyServiceHandler(svc TenancyServiceHandler, opts ...connect.HandlerOption) (string, http.Handler) {
	tenancyServiceMethods := v1.File_tars_tenancy_v1_tenancy_service_proto.Services().ByName("TenancyService").Methods()
	tenancyServiceCreateCustomerHandler := connect.NewUnaryHandler(
		TenancyServiceCreateCustomerProcedure,
		svc.CreateCustomer,
		connect.WithSchema(tenancyServiceMethods.ByName("CreateCustomer")),
		connect.WithHandlerOptions(opts...),
	)
	tenancyServiceGetCustomerHandler := connect.NewUnaryHandler(
		TenancyServiceGetCustomerProcedure,
		svc.GetCustomer,
		connect.WithSchema(tenancyServiceMethods.ByName("GetCustomer")),
		connect.WithIdempotency(connect.IdempotencyNoSideEffects),
		connect.WithHandlerOptions(opts...),
	)
	tenancyServiceListCustomersHandler := connect.NewUnaryHandler(
		TenancyServiceListCustomersProcedure,
		svc.ListCustomers,
		connect.WithSchema(tenancyServiceMethods.ByName("ListCustomers")),
		connect.WithIdempotency(connect.IdempotencyNoSideEffects),
		connect.WithHandlerOptions(opts...),
	)
	tenancyServiceUpdateCustomerHandler := connect.NewUnaryHandler(
		TenancyServiceUpdateCustomerProcedure,
		svc.UpdateCustomer,
		connect.WithSchema(tenancyServiceMethods.ByName("UpdateCustomer")),
		connect.WithHandlerOptions(opts...),
	)
	tenancyServiceArchiveCustomerHandler := connect.NewUnaryHandler(
		TenancyServiceArchiveCustomerProcedure,
		svc.ArchiveCustomer,
		connect.WithSchema(tenancyServiceMethods.ByName("ArchiveCustomer")),
		connect.WithHandlerOptions(opts...),
	)
	return "/tars.tenancy.v1.TenancyService/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		switch r.URL.Path {
		case TenancyServiceCreateCustomerProcedure:
			tenancyServiceCreateCustomerHandler.ServeHTTP(w, r)
		case TenancyServiceGetCustomerProcedure:
			tenancyServiceGetCustomerHandler.ServeHTTP(w, r)
		case TenancyServiceListCustomersProcedure:
			tenancyServiceListCustomersHandler.ServeHTTP(w, r)
		case TenancyServiceUpdateCustomerProcedure:
			tenancyServiceUpdateCustomerHandler.ServeHTTP(w, r)
		case TenancyServiceArchiveCustomerProcedure:
			tenancyServiceArchiveCustomerHandler.ServeHTTP(w, r)
		default:
			http.NotFound(w, r)
		}
	})
}

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

func (UnimplementedTenancyServiceHandler) CreateCustomer(context.Context, *connect.Request[v1.CreateCustomerRequest]) (*connect.Response[v1.Customer], error) {
	return nil, connect.NewError(connect.CodeUnimplemented, errors.New("tars.tenancy.v1.TenancyService.CreateCustomer is not implemented"))
}

func (UnimplementedTenancyServiceHandler) GetCustomer(context.Context, *connect.Request[v1.GetCustomerRequest]) (*connect.Response[v1.Customer], error) {
	return nil, connect.NewError(connect.CodeUnimplemented, errors.New("tars.tenancy.v1.TenancyService.GetCustomer is not implemented"))
}

func (UnimplementedTenancyServiceHandler) ListCustomers(context.Context, *connect.Request[v1.ListCustomersRequest]) (*connect.Response[v1.ListCustomersResponse], error) {
	return nil, connect.NewError(connect.CodeUnimplemented, errors.New("tars.tenancy.v1.TenancyService.ListCustomers is not implemented"))
}

func (UnimplementedTenancyServiceHandler) UpdateCustomer(context.Context, *connect.Request[v1.UpdateCustomerRequest]) (*connect.Response[v1.Customer], error) {
	return nil, connect.NewError(connect.CodeUnimplemented, errors.New("tars.tenancy.v1.TenancyService.UpdateCustomer is not implemented"))
}

func (UnimplementedTenancyServiceHandler) ArchiveCustomer(context.Context, *connect.Request[v1.ArchiveCustomerRequest]) (*connect.Response[emptypb.Empty], error) {
	return nil, connect.NewError(connect.CodeUnimplemented, errors.New("tars.tenancy.v1.TenancyService.ArchiveCustomer is not implemented"))
}

// ProjectsServiceClient is a client for the tars.tenancy.v1.ProjectsService service.
type ProjectsServiceClient interface {
	// CreateProject creates a project within a customer scope.
	CreateProject(context.Context, *connect.Request[v1.CreateProjectRequest]) (*connect.Response[v1.Project], error)
	// GetProject returns a single project by id.
	GetProject(context.Context, *connect.Request[v1.GetProjectRequest]) (*connect.Response[v1.Project], error)
	// ListProjects lists projects within a customer scope.
	ListProjects(context.Context, *connect.Request[v1.ListProjectsRequest]) (*connect.Response[v1.ListProjectsResponse], error)
	// UpdateProject updates mutable project fields.
	UpdateProject(context.Context, *connect.Request[v1.UpdateProjectRequest]) (*connect.Response[v1.Project], error)
	// ArchiveProject soft-deletes a project. Refuses to archive the
	// default project, matching the existing admin.v1 behaviour.
	ArchiveProject(context.Context, *connect.Request[v1.ArchiveProjectRequest]) (*connect.Response[emptypb.Empty], error)
	// AddProjectMember grants an identity access to a project with the
	// given role bundle.
	AddProjectMember(context.Context, *connect.Request[v1.AddProjectMemberRequest]) (*connect.Response[v1.ProjectMember], error)
	// ListProjectMembers lists all members of a project and their roles.
	ListProjectMembers(context.Context, *connect.Request[v1.ListProjectMembersRequest]) (*connect.Response[v1.ListProjectMembersResponse], error)
	// UpdateProjectMember updates an existing project member's role.
	UpdateProjectMember(context.Context, *connect.Request[v1.UpdateProjectMemberRequest]) (*connect.Response[v1.ProjectMember], error)
	// RemoveProjectMember revokes an identity's membership in a project.
	RemoveProjectMember(context.Context, *connect.Request[v1.RemoveProjectMemberRequest]) (*connect.Response[emptypb.Empty], error)
}

// NewProjectsServiceClient constructs a client for the tars.tenancy.v1.ProjectsService 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 NewProjectsServiceClient(httpClient connect.HTTPClient, baseURL string, opts ...connect.ClientOption) ProjectsServiceClient {
	baseURL = strings.TrimRight(baseURL, "/")
	projectsServiceMethods := v1.File_tars_tenancy_v1_tenancy_service_proto.Services().ByName("ProjectsService").Methods()
	return &projectsServiceClient{
		createProject: connect.NewClient[v1.CreateProjectRequest, v1.Project](
			httpClient,
			baseURL+ProjectsServiceCreateProjectProcedure,
			connect.WithSchema(projectsServiceMethods.ByName("CreateProject")),
			connect.WithClientOptions(opts...),
		),
		getProject: connect.NewClient[v1.GetProjectRequest, v1.Project](
			httpClient,
			baseURL+ProjectsServiceGetProjectProcedure,
			connect.WithSchema(projectsServiceMethods.ByName("GetProject")),
			connect.WithIdempotency(connect.IdempotencyNoSideEffects),
			connect.WithClientOptions(opts...),
		),
		listProjects: connect.NewClient[v1.ListProjectsRequest, v1.ListProjectsResponse](
			httpClient,
			baseURL+ProjectsServiceListProjectsProcedure,
			connect.WithSchema(projectsServiceMethods.ByName("ListProjects")),
			connect.WithIdempotency(connect.IdempotencyNoSideEffects),
			connect.WithClientOptions(opts...),
		),
		updateProject: connect.NewClient[v1.UpdateProjectRequest, v1.Project](
			httpClient,
			baseURL+ProjectsServiceUpdateProjectProcedure,
			connect.WithSchema(projectsServiceMethods.ByName("UpdateProject")),
			connect.WithClientOptions(opts...),
		),
		archiveProject: connect.NewClient[v1.ArchiveProjectRequest, emptypb.Empty](
			httpClient,
			baseURL+ProjectsServiceArchiveProjectProcedure,
			connect.WithSchema(projectsServiceMethods.ByName("ArchiveProject")),
			connect.WithClientOptions(opts...),
		),
		addProjectMember: connect.NewClient[v1.AddProjectMemberRequest, v1.ProjectMember](
			httpClient,
			baseURL+ProjectsServiceAddProjectMemberProcedure,
			connect.WithSchema(projectsServiceMethods.ByName("AddProjectMember")),
			connect.WithClientOptions(opts...),
		),
		listProjectMembers: connect.NewClient[v1.ListProjectMembersRequest, v1.ListProjectMembersResponse](
			httpClient,
			baseURL+ProjectsServiceListProjectMembersProcedure,
			connect.WithSchema(projectsServiceMethods.ByName("ListProjectMembers")),
			connect.WithIdempotency(connect.IdempotencyNoSideEffects),
			connect.WithClientOptions(opts...),
		),
		updateProjectMember: connect.NewClient[v1.UpdateProjectMemberRequest, v1.ProjectMember](
			httpClient,
			baseURL+ProjectsServiceUpdateProjectMemberProcedure,
			connect.WithSchema(projectsServiceMethods.ByName("UpdateProjectMember")),
			connect.WithClientOptions(opts...),
		),
		removeProjectMember: connect.NewClient[v1.RemoveProjectMemberRequest, emptypb.Empty](
			httpClient,
			baseURL+ProjectsServiceRemoveProjectMemberProcedure,
			connect.WithSchema(projectsServiceMethods.ByName("RemoveProjectMember")),
			connect.WithClientOptions(opts...),
		),
	}
}

// projectsServiceClient implements ProjectsServiceClient.
type projectsServiceClient struct {
	createProject       *connect.Client[v1.CreateProjectRequest, v1.Project]
	getProject          *connect.Client[v1.GetProjectRequest, v1.Project]
	listProjects        *connect.Client[v1.ListProjectsRequest, v1.ListProjectsResponse]
	updateProject       *connect.Client[v1.UpdateProjectRequest, v1.Project]
	archiveProject      *connect.Client[v1.ArchiveProjectRequest, emptypb.Empty]
	addProjectMember    *connect.Client[v1.AddProjectMemberRequest, v1.ProjectMember]
	listProjectMembers  *connect.Client[v1.ListProjectMembersRequest, v1.ListProjectMembersResponse]
	updateProjectMember *connect.Client[v1.UpdateProjectMemberRequest, v1.ProjectMember]
	removeProjectMember *connect.Client[v1.RemoveProjectMemberRequest, emptypb.Empty]
}

// CreateProject calls tars.tenancy.v1.ProjectsService.CreateProject.
func (c *projectsServiceClient) CreateProject(ctx context.Context, req *connect.Request[v1.CreateProjectRequest]) (*connect.Response[v1.Project], error) {
	return c.createProject.CallUnary(ctx, req)
}

// GetProject calls tars.tenancy.v1.ProjectsService.GetProject.
func (c *projectsServiceClient) GetProject(ctx context.Context, req *connect.Request[v1.GetProjectRequest]) (*connect.Response[v1.Project], error) {
	return c.getProject.CallUnary(ctx, req)
}

// ListProjects calls tars.tenancy.v1.ProjectsService.ListProjects.
func (c *projectsServiceClient) ListProjects(ctx context.Context, req *connect.Request[v1.ListProjectsRequest]) (*connect.Response[v1.ListProjectsResponse], error) {
	return c.listProjects.CallUnary(ctx, req)
}

// UpdateProject calls tars.tenancy.v1.ProjectsService.UpdateProject.
func (c *projectsServiceClient) UpdateProject(ctx context.Context, req *connect.Request[v1.UpdateProjectRequest]) (*connect.Response[v1.Project], error) {
	return c.updateProject.CallUnary(ctx, req)
}

// ArchiveProject calls tars.tenancy.v1.ProjectsService.ArchiveProject.
func (c *projectsServiceClient) ArchiveProject(ctx context.Context, req *connect.Request[v1.ArchiveProjectRequest]) (*connect.Response[emptypb.Empty], error) {
	return c.archiveProject.CallUnary(ctx, req)
}

// AddProjectMember calls tars.tenancy.v1.ProjectsService.AddProjectMember.
func (c *projectsServiceClient) AddProjectMember(ctx context.Context, req *connect.Request[v1.AddProjectMemberRequest]) (*connect.Response[v1.ProjectMember], error) {
	return c.addProjectMember.CallUnary(ctx, req)
}

// ListProjectMembers calls tars.tenancy.v1.ProjectsService.ListProjectMembers.
func (c *projectsServiceClient) ListProjectMembers(ctx context.Context, req *connect.Request[v1.ListProjectMembersRequest]) (*connect.Response[v1.ListProjectMembersResponse], error) {
	return c.listProjectMembers.CallUnary(ctx, req)
}

// UpdateProjectMember calls tars.tenancy.v1.ProjectsService.UpdateProjectMember.
func (c *projectsServiceClient) UpdateProjectMember(ctx context.Context, req *connect.Request[v1.UpdateProjectMemberRequest]) (*connect.Response[v1.ProjectMember], error) {
	return c.updateProjectMember.CallUnary(ctx, req)
}

// RemoveProjectMember calls tars.tenancy.v1.ProjectsService.RemoveProjectMember.
func (c *projectsServiceClient) RemoveProjectMember(ctx context.Context, req *connect.Request[v1.RemoveProjectMemberRequest]) (*connect.Response[emptypb.Empty], error) {
	return c.removeProjectMember.CallUnary(ctx, req)
}

// ProjectsServiceHandler is an implementation of the tars.tenancy.v1.ProjectsService service.
type ProjectsServiceHandler interface {
	// CreateProject creates a project within a customer scope.
	CreateProject(context.Context, *connect.Request[v1.CreateProjectRequest]) (*connect.Response[v1.Project], error)
	// GetProject returns a single project by id.
	GetProject(context.Context, *connect.Request[v1.GetProjectRequest]) (*connect.Response[v1.Project], error)
	// ListProjects lists projects within a customer scope.
	ListProjects(context.Context, *connect.Request[v1.ListProjectsRequest]) (*connect.Response[v1.ListProjectsResponse], error)
	// UpdateProject updates mutable project fields.
	UpdateProject(context.Context, *connect.Request[v1.UpdateProjectRequest]) (*connect.Response[v1.Project], error)
	// ArchiveProject soft-deletes a project. Refuses to archive the
	// default project, matching the existing admin.v1 behaviour.
	ArchiveProject(context.Context, *connect.Request[v1.ArchiveProjectRequest]) (*connect.Response[emptypb.Empty], error)
	// AddProjectMember grants an identity access to a project with the
	// given role bundle.
	AddProjectMember(context.Context, *connect.Request[v1.AddProjectMemberRequest]) (*connect.Response[v1.ProjectMember], error)
	// ListProjectMembers lists all members of a project and their roles.
	ListProjectMembers(context.Context, *connect.Request[v1.ListProjectMembersRequest]) (*connect.Response[v1.ListProjectMembersResponse], error)
	// UpdateProjectMember updates an existing project member's role.
	UpdateProjectMember(context.Context, *connect.Request[v1.UpdateProjectMemberRequest]) (*connect.Response[v1.ProjectMember], error)
	// RemoveProjectMember revokes an identity's membership in a project.
	RemoveProjectMember(context.Context, *connect.Request[v1.RemoveProjectMemberRequest]) (*connect.Response[emptypb.Empty], error)
}

// NewProjectsServiceHandler 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 NewProjectsServiceHandler(svc ProjectsServiceHandler, opts ...connect.HandlerOption) (string, http.Handler) {
	projectsServiceMethods := v1.File_tars_tenancy_v1_tenancy_service_proto.Services().ByName("ProjectsService").Methods()
	projectsServiceCreateProjectHandler := connect.NewUnaryHandler(
		ProjectsServiceCreateProjectProcedure,
		svc.CreateProject,
		connect.WithSchema(projectsServiceMethods.ByName("CreateProject")),
		connect.WithHandlerOptions(opts...),
	)
	projectsServiceGetProjectHandler := connect.NewUnaryHandler(
		ProjectsServiceGetProjectProcedure,
		svc.GetProject,
		connect.WithSchema(projectsServiceMethods.ByName("GetProject")),
		connect.WithIdempotency(connect.IdempotencyNoSideEffects),
		connect.WithHandlerOptions(opts...),
	)
	projectsServiceListProjectsHandler := connect.NewUnaryHandler(
		ProjectsServiceListProjectsProcedure,
		svc.ListProjects,
		connect.WithSchema(projectsServiceMethods.ByName("ListProjects")),
		connect.WithIdempotency(connect.IdempotencyNoSideEffects),
		connect.WithHandlerOptions(opts...),
	)
	projectsServiceUpdateProjectHandler := connect.NewUnaryHandler(
		ProjectsServiceUpdateProjectProcedure,
		svc.UpdateProject,
		connect.WithSchema(projectsServiceMethods.ByName("UpdateProject")),
		connect.WithHandlerOptions(opts...),
	)
	projectsServiceArchiveProjectHandler := connect.NewUnaryHandler(
		ProjectsServiceArchiveProjectProcedure,
		svc.ArchiveProject,
		connect.WithSchema(projectsServiceMethods.ByName("ArchiveProject")),
		connect.WithHandlerOptions(opts...),
	)
	projectsServiceAddProjectMemberHandler := connect.NewUnaryHandler(
		ProjectsServiceAddProjectMemberProcedure,
		svc.AddProjectMember,
		connect.WithSchema(projectsServiceMethods.ByName("AddProjectMember")),
		connect.WithHandlerOptions(opts...),
	)
	projectsServiceListProjectMembersHandler := connect.NewUnaryHandler(
		ProjectsServiceListProjectMembersProcedure,
		svc.ListProjectMembers,
		connect.WithSchema(projectsServiceMethods.ByName("ListProjectMembers")),
		connect.WithIdempotency(connect.IdempotencyNoSideEffects),
		connect.WithHandlerOptions(opts...),
	)
	projectsServiceUpdateProjectMemberHandler := connect.NewUnaryHandler(
		ProjectsServiceUpdateProjectMemberProcedure,
		svc.UpdateProjectMember,
		connect.WithSchema(projectsServiceMethods.ByName("UpdateProjectMember")),
		connect.WithHandlerOptions(opts...),
	)
	projectsServiceRemoveProjectMemberHandler := connect.NewUnaryHandler(
		ProjectsServiceRemoveProjectMemberProcedure,
		svc.RemoveProjectMember,
		connect.WithSchema(projectsServiceMethods.ByName("RemoveProjectMember")),
		connect.WithHandlerOptions(opts...),
	)
	return "/tars.tenancy.v1.ProjectsService/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		switch r.URL.Path {
		case ProjectsServiceCreateProjectProcedure:
			projectsServiceCreateProjectHandler.ServeHTTP(w, r)
		case ProjectsServiceGetProjectProcedure:
			projectsServiceGetProjectHandler.ServeHTTP(w, r)
		case ProjectsServiceListProjectsProcedure:
			projectsServiceListProjectsHandler.ServeHTTP(w, r)
		case ProjectsServiceUpdateProjectProcedure:
			projectsServiceUpdateProjectHandler.ServeHTTP(w, r)
		case ProjectsServiceArchiveProjectProcedure:
			projectsServiceArchiveProjectHandler.ServeHTTP(w, r)
		case ProjectsServiceAddProjectMemberProcedure:
			projectsServiceAddProjectMemberHandler.ServeHTTP(w, r)
		case ProjectsServiceListProjectMembersProcedure:
			projectsServiceListProjectMembersHandler.ServeHTTP(w, r)
		case ProjectsServiceUpdateProjectMemberProcedure:
			projectsServiceUpdateProjectMemberHandler.ServeHTTP(w, r)
		case ProjectsServiceRemoveProjectMemberProcedure:
			projectsServiceRemoveProjectMemberHandler.ServeHTTP(w, r)
		default:
			http.NotFound(w, r)
		}
	})
}

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

func (UnimplementedProjectsServiceHandler) CreateProject(context.Context, *connect.Request[v1.CreateProjectRequest]) (*connect.Response[v1.Project], error) {
	return nil, connect.NewError(connect.CodeUnimplemented, errors.New("tars.tenancy.v1.ProjectsService.CreateProject is not implemented"))
}

func (UnimplementedProjectsServiceHandler) GetProject(context.Context, *connect.Request[v1.GetProjectRequest]) (*connect.Response[v1.Project], error) {
	return nil, connect.NewError(connect.CodeUnimplemented, errors.New("tars.tenancy.v1.ProjectsService.GetProject is not implemented"))
}

func (UnimplementedProjectsServiceHandler) ListProjects(context.Context, *connect.Request[v1.ListProjectsRequest]) (*connect.Response[v1.ListProjectsResponse], error) {
	return nil, connect.NewError(connect.CodeUnimplemented, errors.New("tars.tenancy.v1.ProjectsService.ListProjects is not implemented"))
}

func (UnimplementedProjectsServiceHandler) UpdateProject(context.Context, *connect.Request[v1.UpdateProjectRequest]) (*connect.Response[v1.Project], error) {
	return nil, connect.NewError(connect.CodeUnimplemented, errors.New("tars.tenancy.v1.ProjectsService.UpdateProject is not implemented"))
}

func (UnimplementedProjectsServiceHandler) ArchiveProject(context.Context, *connect.Request[v1.ArchiveProjectRequest]) (*connect.Response[emptypb.Empty], error) {
	return nil, connect.NewError(connect.CodeUnimplemented, errors.New("tars.tenancy.v1.ProjectsService.ArchiveProject is not implemented"))
}

func (UnimplementedProjectsServiceHandler) AddProjectMember(context.Context, *connect.Request[v1.AddProjectMemberRequest]) (*connect.Response[v1.ProjectMember], error) {
	return nil, connect.NewError(connect.CodeUnimplemented, errors.New("tars.tenancy.v1.ProjectsService.AddProjectMember is not implemented"))
}

func (UnimplementedProjectsServiceHandler) ListProjectMembers(context.Context, *connect.Request[v1.ListProjectMembersRequest]) (*connect.Response[v1.ListProjectMembersResponse], error) {
	return nil, connect.NewError(connect.CodeUnimplemented, errors.New("tars.tenancy.v1.ProjectsService.ListProjectMembers is not implemented"))
}

func (UnimplementedProjectsServiceHandler) UpdateProjectMember(context.Context, *connect.Request[v1.UpdateProjectMemberRequest]) (*connect.Response[v1.ProjectMember], error) {
	return nil, connect.NewError(connect.CodeUnimplemented, errors.New("tars.tenancy.v1.ProjectsService.UpdateProjectMember is not implemented"))
}

func (UnimplementedProjectsServiceHandler) RemoveProjectMember(context.Context, *connect.Request[v1.RemoveProjectMemberRequest]) (*connect.Response[emptypb.Empty], error) {
	return nil, connect.NewError(connect.CodeUnimplemented, errors.New("tars.tenancy.v1.ProjectsService.RemoveProjectMember is not implemented"))
}
