// Copyright 2015 The Vanadium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// This file was auto-generated by the vanadium vdl tool.
// Source: discharger.vdl

// Package discharger defines an interface for obtaining discharges for
// third-party caveats.
package discharger

import (
	// VDL system imports
	"v.io/v23"
	"v.io/v23/context"
	"v.io/v23/i18n"
	"v.io/v23/rpc"
	"v.io/v23/verror"

	// VDL user imports
	"v.io/v23/security"
)

var (
	// Indicates that the Caveat does not require a discharge
	ErrNotAThirdPartyCaveat = verror.Register("v.io/x/ref/services/discharger.NotAThirdPartyCaveat", verror.NoRetry, "{1:}{2:} discharges are not required for non-third-party caveats (id: {c.id})")
)

func init() {
	i18n.Cat().SetWithBase(i18n.LangID("en"), i18n.MsgID(ErrNotAThirdPartyCaveat.ID), "{1:}{2:} discharges are not required for non-third-party caveats (id: {c.id})")
}

// NewErrNotAThirdPartyCaveat returns an error with the ErrNotAThirdPartyCaveat ID.
func NewErrNotAThirdPartyCaveat(ctx *context.T, c security.Caveat) error {
	return verror.New(ErrNotAThirdPartyCaveat, ctx, c)
}

// DischargerClientMethods is the client interface
// containing Discharger methods.
//
// Discharger is the interface for obtaining discharges for ThirdPartyCaveats.
type DischargerClientMethods interface {
	// Discharge is called by a principal that holds a blessing with a third
	// party caveat and seeks to get a discharge that proves the fulfillment of
	// this caveat.
	Discharge(ctx *context.T, Caveat security.Caveat, Impetus security.DischargeImpetus, opts ...rpc.CallOpt) (Discharge security.Discharge, err error)
}

// DischargerClientStub adds universal methods to DischargerClientMethods.
type DischargerClientStub interface {
	DischargerClientMethods
	rpc.UniversalServiceMethods
}

// DischargerClient returns a client stub for Discharger.
func DischargerClient(name string) DischargerClientStub {
	return implDischargerClientStub{name}
}

type implDischargerClientStub struct {
	name string
}

func (c implDischargerClientStub) Discharge(ctx *context.T, i0 security.Caveat, i1 security.DischargeImpetus, opts ...rpc.CallOpt) (o0 security.Discharge, err error) {
	err = v23.GetClient(ctx).Call(ctx, c.name, "Discharge", []interface{}{i0, i1}, []interface{}{&o0}, opts...)
	return
}

// DischargerServerMethods is the interface a server writer
// implements for Discharger.
//
// Discharger is the interface for obtaining discharges for ThirdPartyCaveats.
type DischargerServerMethods interface {
	// Discharge is called by a principal that holds a blessing with a third
	// party caveat and seeks to get a discharge that proves the fulfillment of
	// this caveat.
	Discharge(ctx *context.T, call rpc.ServerCall, Caveat security.Caveat, Impetus security.DischargeImpetus) (Discharge security.Discharge, err error)
}

// DischargerServerStubMethods is the server interface containing
// Discharger methods, as expected by rpc.Server.
// There is no difference between this interface and DischargerServerMethods
// since there are no streaming methods.
type DischargerServerStubMethods DischargerServerMethods

// DischargerServerStub adds universal methods to DischargerServerStubMethods.
type DischargerServerStub interface {
	DischargerServerStubMethods
	// Describe the Discharger interfaces.
	Describe__() []rpc.InterfaceDesc
}

// DischargerServer returns a server stub for Discharger.
// It converts an implementation of DischargerServerMethods into
// an object that may be used by rpc.Server.
func DischargerServer(impl DischargerServerMethods) DischargerServerStub {
	stub := implDischargerServerStub{
		impl: impl,
	}
	// Initialize GlobState; always check the stub itself first, to handle the
	// case where the user has the Glob method defined in their VDL source.
	if gs := rpc.NewGlobState(stub); gs != nil {
		stub.gs = gs
	} else if gs := rpc.NewGlobState(impl); gs != nil {
		stub.gs = gs
	}
	return stub
}

type implDischargerServerStub struct {
	impl DischargerServerMethods
	gs   *rpc.GlobState
}

func (s implDischargerServerStub) Discharge(ctx *context.T, call rpc.ServerCall, i0 security.Caveat, i1 security.DischargeImpetus) (security.Discharge, error) {
	return s.impl.Discharge(ctx, call, i0, i1)
}

func (s implDischargerServerStub) Globber() *rpc.GlobState {
	return s.gs
}

func (s implDischargerServerStub) Describe__() []rpc.InterfaceDesc {
	return []rpc.InterfaceDesc{DischargerDesc}
}

// DischargerDesc describes the Discharger interface.
var DischargerDesc rpc.InterfaceDesc = descDischarger

// descDischarger hides the desc to keep godoc clean.
var descDischarger = rpc.InterfaceDesc{
	Name:    "Discharger",
	PkgPath: "v.io/x/ref/services/discharger",
	Doc:     "// Discharger is the interface for obtaining discharges for ThirdPartyCaveats.",
	Methods: []rpc.MethodDesc{
		{
			Name: "Discharge",
			Doc:  "// Discharge is called by a principal that holds a blessing with a third\n// party caveat and seeks to get a discharge that proves the fulfillment of\n// this caveat.",
			InArgs: []rpc.ArgDesc{
				{"Caveat", ``},  // security.Caveat
				{"Impetus", ``}, // security.DischargeImpetus
			},
			OutArgs: []rpc.ArgDesc{
				{"Discharge", ``}, // security.Discharge
			},
		},
	},
}
