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

package security

import (
	"v.io/core/veyron2/security"

	// The non-user imports are prefixed with "__" to prevent collisions.
	__veyron2 "v.io/core/veyron2"
	__context "v.io/core/veyron2/context"
	__ipc "v.io/core/veyron2/ipc"
	__vdl "v.io/core/veyron2/vdl"
)

// 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.
	//
	// Caveat and Discharge are of type ThirdPartyCaveat and Discharge
	// respectively. (not enforced here because vdl does not know these types)
	// TODO(ataly,ashankar): Figure out a VDL representation for ThirdPartyCaveat
	// and Discharge and use those here?
	Discharge(ctx *__context.T, Caveat __vdl.AnyRep, Impetus security.DischargeImpetus, opts ...__ipc.CallOpt) (Discharge __vdl.AnyRep, err error)
}

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

// DischargerClient returns a client stub for Discharger.
func DischargerClient(name string, opts ...__ipc.BindOpt) DischargerClientStub {
	var client __ipc.Client
	for _, opt := range opts {
		if clientOpt, ok := opt.(__ipc.Client); ok {
			client = clientOpt
		}
	}
	return implDischargerClientStub{name, client}
}

type implDischargerClientStub struct {
	name   string
	client __ipc.Client
}

func (c implDischargerClientStub) c(ctx *__context.T) __ipc.Client {
	if c.client != nil {
		return c.client
	}
	return __veyron2.GetClient(ctx)
}

func (c implDischargerClientStub) Discharge(ctx *__context.T, i0 __vdl.AnyRep, i1 security.DischargeImpetus, opts ...__ipc.CallOpt) (o0 __vdl.AnyRep, err error) {
	var call __ipc.Call
	if call, err = c.c(ctx).StartCall(ctx, c.name, "Discharge", []interface{}{i0, i1}, opts...); err != nil {
		return
	}
	if ierr := call.Finish(&o0, &err); ierr != nil {
		err = ierr
	}
	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.
	//
	// Caveat and Discharge are of type ThirdPartyCaveat and Discharge
	// respectively. (not enforced here because vdl does not know these types)
	// TODO(ataly,ashankar): Figure out a VDL representation for ThirdPartyCaveat
	// and Discharge and use those here?
	Discharge(ctx __ipc.ServerContext, Caveat __vdl.AnyRep, Impetus security.DischargeImpetus) (Discharge __vdl.AnyRep, err error)
}

// DischargerServerStubMethods is the server interface containing
// Discharger methods, as expected by ipc.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__() []__ipc.InterfaceDesc
}

// DischargerServer returns a server stub for Discharger.
// It converts an implementation of DischargerServerMethods into
// an object that may be used by ipc.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 := __ipc.NewGlobState(stub); gs != nil {
		stub.gs = gs
	} else if gs := __ipc.NewGlobState(impl); gs != nil {
		stub.gs = gs
	}
	return stub
}

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

func (s implDischargerServerStub) Discharge(ctx __ipc.ServerContext, i0 __vdl.AnyRep, i1 security.DischargeImpetus) (__vdl.AnyRep, error) {
	return s.impl.Discharge(ctx, i0, i1)
}

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

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

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

// descDischarger hides the desc to keep godoc clean.
var descDischarger = __ipc.InterfaceDesc{
	Name:    "Discharger",
	PkgPath: "v.io/core/veyron/services/security",
	Doc:     "// Discharger is the interface for obtaining discharges for ThirdPartyCaveats.",
	Methods: []__ipc.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.\n//\n// Caveat and Discharge are of type ThirdPartyCaveat and Discharge\n// respectively. (not enforced here because vdl does not know these types)\n// TODO(ataly,ashankar): Figure out a VDL representation for ThirdPartyCaveat\n// and Discharge and use those here?",
			InArgs: []__ipc.ArgDesc{
				{"Caveat", ``},  // __vdl.AnyRep
				{"Impetus", ``}, // security.DischargeImpetus
			},
			OutArgs: []__ipc.ArgDesc{
				{"Discharge", ``}, // __vdl.AnyRep
				{"err", ``},       // error
			},
		},
	},
}
