// Code generated by protoc-gen-go-grpc. DO NOT EDIT.

package api_proto

import (
	context "context"
	grpc "google.golang.org/grpc"
	codes "google.golang.org/grpc/codes"
	status "google.golang.org/grpc/status"
)

// This is a compile-time assertion to ensure that this generated file
// is compatible with the grpc package it is being compiled against.
// Requires gRPC-Go v1.32.0 or later.
const _ = grpc.SupportPackageIsVersion7

// KillSwitchServiceClient is the client API for KillSwitchService service.
//
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
type KillSwitchServiceClient interface {
	GetKillSwitchStatus(ctx context.Context, in *GetKillSwitchStatusRequest, opts ...grpc.CallOption) (*GetKillSwitchStatusResponse, error)
	GetKillSwitchOverview(ctx context.Context, in *GetKillSwitchOverviewRequest, opts ...grpc.CallOption) (*GetKillSwitchOverviewResponse, error)
	ListFeatures(ctx context.Context, in *ListFeaturesRequest, opts ...grpc.CallOption) (*ListFeaturesResponse, error)
	SyncFeatures(ctx context.Context, in *SyncFeaturesRequest, opts ...grpc.CallOption) (*SyncFeaturesResponse, error)
	EnableKillSwitch(ctx context.Context, in *EnableKillSwitchRequest, opts ...grpc.CallOption) (*EnableKillSwitchResponse, error)
	DisableKillSwitch(ctx context.Context, in *DisableKillSwitchRequest, opts ...grpc.CallOption) (*DisableKillSwitchResponse, error)
	ListAuthorizedUsers(ctx context.Context, in *ListAuthorizedUsersRequest, opts ...grpc.CallOption) (*ListAuthorizedUsersResponse, error)
	AddAuthorizedUser(ctx context.Context, in *AddAuthorizedUserRequest, opts ...grpc.CallOption) (*AddAuthorizedUserResponse, error)
	UpdateAuthorizedUser(ctx context.Context, in *UpdateAuthorizedUserRequest, opts ...grpc.CallOption) (*UpdateAuthorizedUserResponse, error)
	DeleteAuthorizedUser(ctx context.Context, in *DeleteAuthorizedUserRequest, opts ...grpc.CallOption) (*DeleteAuthorizedUserResponse, error)
}

type killSwitchServiceClient struct {
	cc grpc.ClientConnInterface
}

func NewKillSwitchServiceClient(cc grpc.ClientConnInterface) KillSwitchServiceClient {
	return &killSwitchServiceClient{cc}
}

func (c *killSwitchServiceClient) GetKillSwitchStatus(ctx context.Context, in *GetKillSwitchStatusRequest, opts ...grpc.CallOption) (*GetKillSwitchStatusResponse, error) {
	out := new(GetKillSwitchStatusResponse)
	err := c.cc.Invoke(ctx, "/KillSwitchService/GetKillSwitchStatus", in, out, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

func (c *killSwitchServiceClient) GetKillSwitchOverview(ctx context.Context, in *GetKillSwitchOverviewRequest, opts ...grpc.CallOption) (*GetKillSwitchOverviewResponse, error) {
	out := new(GetKillSwitchOverviewResponse)
	err := c.cc.Invoke(ctx, "/KillSwitchService/GetKillSwitchOverview", in, out, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

func (c *killSwitchServiceClient) ListFeatures(ctx context.Context, in *ListFeaturesRequest, opts ...grpc.CallOption) (*ListFeaturesResponse, error) {
	out := new(ListFeaturesResponse)
	err := c.cc.Invoke(ctx, "/KillSwitchService/ListFeatures", in, out, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

func (c *killSwitchServiceClient) SyncFeatures(ctx context.Context, in *SyncFeaturesRequest, opts ...grpc.CallOption) (*SyncFeaturesResponse, error) {
	out := new(SyncFeaturesResponse)
	err := c.cc.Invoke(ctx, "/KillSwitchService/SyncFeatures", in, out, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

func (c *killSwitchServiceClient) EnableKillSwitch(ctx context.Context, in *EnableKillSwitchRequest, opts ...grpc.CallOption) (*EnableKillSwitchResponse, error) {
	out := new(EnableKillSwitchResponse)
	err := c.cc.Invoke(ctx, "/KillSwitchService/EnableKillSwitch", in, out, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

func (c *killSwitchServiceClient) DisableKillSwitch(ctx context.Context, in *DisableKillSwitchRequest, opts ...grpc.CallOption) (*DisableKillSwitchResponse, error) {
	out := new(DisableKillSwitchResponse)
	err := c.cc.Invoke(ctx, "/KillSwitchService/DisableKillSwitch", in, out, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

func (c *killSwitchServiceClient) ListAuthorizedUsers(ctx context.Context, in *ListAuthorizedUsersRequest, opts ...grpc.CallOption) (*ListAuthorizedUsersResponse, error) {
	out := new(ListAuthorizedUsersResponse)
	err := c.cc.Invoke(ctx, "/KillSwitchService/ListAuthorizedUsers", in, out, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

func (c *killSwitchServiceClient) AddAuthorizedUser(ctx context.Context, in *AddAuthorizedUserRequest, opts ...grpc.CallOption) (*AddAuthorizedUserResponse, error) {
	out := new(AddAuthorizedUserResponse)
	err := c.cc.Invoke(ctx, "/KillSwitchService/AddAuthorizedUser", in, out, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

func (c *killSwitchServiceClient) UpdateAuthorizedUser(ctx context.Context, in *UpdateAuthorizedUserRequest, opts ...grpc.CallOption) (*UpdateAuthorizedUserResponse, error) {
	out := new(UpdateAuthorizedUserResponse)
	err := c.cc.Invoke(ctx, "/KillSwitchService/UpdateAuthorizedUser", in, out, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

func (c *killSwitchServiceClient) DeleteAuthorizedUser(ctx context.Context, in *DeleteAuthorizedUserRequest, opts ...grpc.CallOption) (*DeleteAuthorizedUserResponse, error) {
	out := new(DeleteAuthorizedUserResponse)
	err := c.cc.Invoke(ctx, "/KillSwitchService/DeleteAuthorizedUser", in, out, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

// KillSwitchServiceServer is the server API for KillSwitchService service.
// All implementations must embed UnimplementedKillSwitchServiceServer
// for forward compatibility
type KillSwitchServiceServer interface {
	GetKillSwitchStatus(context.Context, *GetKillSwitchStatusRequest) (*GetKillSwitchStatusResponse, error)
	GetKillSwitchOverview(context.Context, *GetKillSwitchOverviewRequest) (*GetKillSwitchOverviewResponse, error)
	ListFeatures(context.Context, *ListFeaturesRequest) (*ListFeaturesResponse, error)
	SyncFeatures(context.Context, *SyncFeaturesRequest) (*SyncFeaturesResponse, error)
	EnableKillSwitch(context.Context, *EnableKillSwitchRequest) (*EnableKillSwitchResponse, error)
	DisableKillSwitch(context.Context, *DisableKillSwitchRequest) (*DisableKillSwitchResponse, error)
	ListAuthorizedUsers(context.Context, *ListAuthorizedUsersRequest) (*ListAuthorizedUsersResponse, error)
	AddAuthorizedUser(context.Context, *AddAuthorizedUserRequest) (*AddAuthorizedUserResponse, error)
	UpdateAuthorizedUser(context.Context, *UpdateAuthorizedUserRequest) (*UpdateAuthorizedUserResponse, error)
	DeleteAuthorizedUser(context.Context, *DeleteAuthorizedUserRequest) (*DeleteAuthorizedUserResponse, error)
	mustEmbedUnimplementedKillSwitchServiceServer()
}

// UnimplementedKillSwitchServiceServer must be embedded to have forward compatible implementations.
type UnimplementedKillSwitchServiceServer struct {
}

func (UnimplementedKillSwitchServiceServer) GetKillSwitchStatus(context.Context, *GetKillSwitchStatusRequest) (*GetKillSwitchStatusResponse, error) {
	return nil, status.Errorf(codes.Unimplemented, "method GetKillSwitchStatus not implemented")
}
func (UnimplementedKillSwitchServiceServer) GetKillSwitchOverview(context.Context, *GetKillSwitchOverviewRequest) (*GetKillSwitchOverviewResponse, error) {
	return nil, status.Errorf(codes.Unimplemented, "method GetKillSwitchOverview not implemented")
}
func (UnimplementedKillSwitchServiceServer) ListFeatures(context.Context, *ListFeaturesRequest) (*ListFeaturesResponse, error) {
	return nil, status.Errorf(codes.Unimplemented, "method ListFeatures not implemented")
}
func (UnimplementedKillSwitchServiceServer) SyncFeatures(context.Context, *SyncFeaturesRequest) (*SyncFeaturesResponse, error) {
	return nil, status.Errorf(codes.Unimplemented, "method SyncFeatures not implemented")
}
func (UnimplementedKillSwitchServiceServer) EnableKillSwitch(context.Context, *EnableKillSwitchRequest) (*EnableKillSwitchResponse, error) {
	return nil, status.Errorf(codes.Unimplemented, "method EnableKillSwitch not implemented")
}
func (UnimplementedKillSwitchServiceServer) DisableKillSwitch(context.Context, *DisableKillSwitchRequest) (*DisableKillSwitchResponse, error) {
	return nil, status.Errorf(codes.Unimplemented, "method DisableKillSwitch not implemented")
}
func (UnimplementedKillSwitchServiceServer) ListAuthorizedUsers(context.Context, *ListAuthorizedUsersRequest) (*ListAuthorizedUsersResponse, error) {
	return nil, status.Errorf(codes.Unimplemented, "method ListAuthorizedUsers not implemented")
}
func (UnimplementedKillSwitchServiceServer) AddAuthorizedUser(context.Context, *AddAuthorizedUserRequest) (*AddAuthorizedUserResponse, error) {
	return nil, status.Errorf(codes.Unimplemented, "method AddAuthorizedUser not implemented")
}
func (UnimplementedKillSwitchServiceServer) UpdateAuthorizedUser(context.Context, *UpdateAuthorizedUserRequest) (*UpdateAuthorizedUserResponse, error) {
	return nil, status.Errorf(codes.Unimplemented, "method UpdateAuthorizedUser not implemented")
}
func (UnimplementedKillSwitchServiceServer) DeleteAuthorizedUser(context.Context, *DeleteAuthorizedUserRequest) (*DeleteAuthorizedUserResponse, error) {
	return nil, status.Errorf(codes.Unimplemented, "method DeleteAuthorizedUser not implemented")
}
func (UnimplementedKillSwitchServiceServer) mustEmbedUnimplementedKillSwitchServiceServer() {}

// UnsafeKillSwitchServiceServer may be embedded to opt out of forward compatibility for this service.
// Use of this interface is not recommended, as added methods to KillSwitchServiceServer will
// result in compilation errors.
type UnsafeKillSwitchServiceServer interface {
	mustEmbedUnimplementedKillSwitchServiceServer()
}

func RegisterKillSwitchServiceServer(s grpc.ServiceRegistrar, srv KillSwitchServiceServer) {
	s.RegisterService(&KillSwitchService_ServiceDesc, srv)
}

func _KillSwitchService_GetKillSwitchStatus_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
	in := new(GetKillSwitchStatusRequest)
	if err := dec(in); err != nil {
		return nil, err
	}
	if interceptor == nil {
		return srv.(KillSwitchServiceServer).GetKillSwitchStatus(ctx, in)
	}
	info := &grpc.UnaryServerInfo{
		Server:     srv,
		FullMethod: "/KillSwitchService/GetKillSwitchStatus",
	}
	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
		return srv.(KillSwitchServiceServer).GetKillSwitchStatus(ctx, req.(*GetKillSwitchStatusRequest))
	}
	return interceptor(ctx, in, info, handler)
}

func _KillSwitchService_GetKillSwitchOverview_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
	in := new(GetKillSwitchOverviewRequest)
	if err := dec(in); err != nil {
		return nil, err
	}
	if interceptor == nil {
		return srv.(KillSwitchServiceServer).GetKillSwitchOverview(ctx, in)
	}
	info := &grpc.UnaryServerInfo{
		Server:     srv,
		FullMethod: "/KillSwitchService/GetKillSwitchOverview",
	}
	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
		return srv.(KillSwitchServiceServer).GetKillSwitchOverview(ctx, req.(*GetKillSwitchOverviewRequest))
	}
	return interceptor(ctx, in, info, handler)
}

func _KillSwitchService_ListFeatures_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
	in := new(ListFeaturesRequest)
	if err := dec(in); err != nil {
		return nil, err
	}
	if interceptor == nil {
		return srv.(KillSwitchServiceServer).ListFeatures(ctx, in)
	}
	info := &grpc.UnaryServerInfo{
		Server:     srv,
		FullMethod: "/KillSwitchService/ListFeatures",
	}
	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
		return srv.(KillSwitchServiceServer).ListFeatures(ctx, req.(*ListFeaturesRequest))
	}
	return interceptor(ctx, in, info, handler)
}

func _KillSwitchService_SyncFeatures_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
	in := new(SyncFeaturesRequest)
	if err := dec(in); err != nil {
		return nil, err
	}
	if interceptor == nil {
		return srv.(KillSwitchServiceServer).SyncFeatures(ctx, in)
	}
	info := &grpc.UnaryServerInfo{
		Server:     srv,
		FullMethod: "/KillSwitchService/SyncFeatures",
	}
	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
		return srv.(KillSwitchServiceServer).SyncFeatures(ctx, req.(*SyncFeaturesRequest))
	}
	return interceptor(ctx, in, info, handler)
}

func _KillSwitchService_EnableKillSwitch_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
	in := new(EnableKillSwitchRequest)
	if err := dec(in); err != nil {
		return nil, err
	}
	if interceptor == nil {
		return srv.(KillSwitchServiceServer).EnableKillSwitch(ctx, in)
	}
	info := &grpc.UnaryServerInfo{
		Server:     srv,
		FullMethod: "/KillSwitchService/EnableKillSwitch",
	}
	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
		return srv.(KillSwitchServiceServer).EnableKillSwitch(ctx, req.(*EnableKillSwitchRequest))
	}
	return interceptor(ctx, in, info, handler)
}

func _KillSwitchService_DisableKillSwitch_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
	in := new(DisableKillSwitchRequest)
	if err := dec(in); err != nil {
		return nil, err
	}
	if interceptor == nil {
		return srv.(KillSwitchServiceServer).DisableKillSwitch(ctx, in)
	}
	info := &grpc.UnaryServerInfo{
		Server:     srv,
		FullMethod: "/KillSwitchService/DisableKillSwitch",
	}
	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
		return srv.(KillSwitchServiceServer).DisableKillSwitch(ctx, req.(*DisableKillSwitchRequest))
	}
	return interceptor(ctx, in, info, handler)
}

func _KillSwitchService_ListAuthorizedUsers_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
	in := new(ListAuthorizedUsersRequest)
	if err := dec(in); err != nil {
		return nil, err
	}
	if interceptor == nil {
		return srv.(KillSwitchServiceServer).ListAuthorizedUsers(ctx, in)
	}
	info := &grpc.UnaryServerInfo{
		Server:     srv,
		FullMethod: "/KillSwitchService/ListAuthorizedUsers",
	}
	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
		return srv.(KillSwitchServiceServer).ListAuthorizedUsers(ctx, req.(*ListAuthorizedUsersRequest))
	}
	return interceptor(ctx, in, info, handler)
}

func _KillSwitchService_AddAuthorizedUser_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
	in := new(AddAuthorizedUserRequest)
	if err := dec(in); err != nil {
		return nil, err
	}
	if interceptor == nil {
		return srv.(KillSwitchServiceServer).AddAuthorizedUser(ctx, in)
	}
	info := &grpc.UnaryServerInfo{
		Server:     srv,
		FullMethod: "/KillSwitchService/AddAuthorizedUser",
	}
	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
		return srv.(KillSwitchServiceServer).AddAuthorizedUser(ctx, req.(*AddAuthorizedUserRequest))
	}
	return interceptor(ctx, in, info, handler)
}

func _KillSwitchService_UpdateAuthorizedUser_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
	in := new(UpdateAuthorizedUserRequest)
	if err := dec(in); err != nil {
		return nil, err
	}
	if interceptor == nil {
		return srv.(KillSwitchServiceServer).UpdateAuthorizedUser(ctx, in)
	}
	info := &grpc.UnaryServerInfo{
		Server:     srv,
		FullMethod: "/KillSwitchService/UpdateAuthorizedUser",
	}
	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
		return srv.(KillSwitchServiceServer).UpdateAuthorizedUser(ctx, req.(*UpdateAuthorizedUserRequest))
	}
	return interceptor(ctx, in, info, handler)
}

func _KillSwitchService_DeleteAuthorizedUser_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
	in := new(DeleteAuthorizedUserRequest)
	if err := dec(in); err != nil {
		return nil, err
	}
	if interceptor == nil {
		return srv.(KillSwitchServiceServer).DeleteAuthorizedUser(ctx, in)
	}
	info := &grpc.UnaryServerInfo{
		Server:     srv,
		FullMethod: "/KillSwitchService/DeleteAuthorizedUser",
	}
	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
		return srv.(KillSwitchServiceServer).DeleteAuthorizedUser(ctx, req.(*DeleteAuthorizedUserRequest))
	}
	return interceptor(ctx, in, info, handler)
}

// KillSwitchService_ServiceDesc is the grpc.ServiceDesc for KillSwitchService service.
// It's only intended for direct use with grpc.RegisterService,
// and not to be introspected or modified (even as a copy)
var KillSwitchService_ServiceDesc = grpc.ServiceDesc{
	ServiceName: "KillSwitchService",
	HandlerType: (*KillSwitchServiceServer)(nil),
	Methods: []grpc.MethodDesc{
		{
			MethodName: "GetKillSwitchStatus",
			Handler:    _KillSwitchService_GetKillSwitchStatus_Handler,
		},
		{
			MethodName: "GetKillSwitchOverview",
			Handler:    _KillSwitchService_GetKillSwitchOverview_Handler,
		},
		{
			MethodName: "ListFeatures",
			Handler:    _KillSwitchService_ListFeatures_Handler,
		},
		{
			MethodName: "SyncFeatures",
			Handler:    _KillSwitchService_SyncFeatures_Handler,
		},
		{
			MethodName: "EnableKillSwitch",
			Handler:    _KillSwitchService_EnableKillSwitch_Handler,
		},
		{
			MethodName: "DisableKillSwitch",
			Handler:    _KillSwitchService_DisableKillSwitch_Handler,
		},
		{
			MethodName: "ListAuthorizedUsers",
			Handler:    _KillSwitchService_ListAuthorizedUsers_Handler,
		},
		{
			MethodName: "AddAuthorizedUser",
			Handler:    _KillSwitchService_AddAuthorizedUser_Handler,
		},
		{
			MethodName: "UpdateAuthorizedUser",
			Handler:    _KillSwitchService_UpdateAuthorizedUser_Handler,
		},
		{
			MethodName: "DeleteAuthorizedUser",
			Handler:    _KillSwitchService_DeleteAuthorizedUser_Handler,
		},
	},
	Streams:  []grpc.StreamDesc{},
	Metadata: "api_proto/kill_switch.proto",
}
