// 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: server.vdl

package server

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

	// VDL user imports
	"v.io/v23/security"
	"v.io/v23/vdlroot/signature"
	"v.io/v23/vdlroot/time"
	"v.io/v23/vtrace"
	"v.io/x/ref/services/wspr/internal/principal"
)

type Context struct {
	Language string
}

func (Context) __VDLReflect(struct {
	Name string `vdl:"v.io/x/ref/services/wspr/internal/rpc/server.Context"`
}) {
}

type SecurityCall struct {
	Method                string
	Suffix                string
	MethodTags            []*vdl.Value
	LocalBlessings        principal.BlessingsId
	LocalBlessingStrings  []string
	RemoteBlessings       principal.BlessingsId
	RemoteBlessingStrings []string
	LocalEndpoint         string
	RemoteEndpoint        string
}

func (SecurityCall) __VDLReflect(struct {
	Name string `vdl:"v.io/x/ref/services/wspr/internal/rpc/server.SecurityCall"`
}) {
}

type CaveatValidationRequest struct {
	Call    SecurityCall
	Context Context
	Cavs    [][]security.Caveat
}

func (CaveatValidationRequest) __VDLReflect(struct {
	Name string `vdl:"v.io/x/ref/services/wspr/internal/rpc/server.CaveatValidationRequest"`
}) {
}

type CaveatValidationResponse struct {
	Results []error
}

func (CaveatValidationResponse) __VDLReflect(struct {
	Name string `vdl:"v.io/x/ref/services/wspr/internal/rpc/server.CaveatValidationResponse"`
}) {
}

type ServerRpcRequestCall struct {
	SecurityCall     SecurityCall
	Deadline         time.Deadline
	Context          Context
	TraceRequest     vtrace.Request
	GrantedBlessings principal.BlessingsId
}

func (ServerRpcRequestCall) __VDLReflect(struct {
	Name string `vdl:"v.io/x/ref/services/wspr/internal/rpc/server.ServerRpcRequestCall"`
}) {
}

// A request from the proxy to javascript to handle an RPC
type ServerRpcRequest struct {
	ServerId uint32
	Handle   int32
	Method   string
	Args     []*vdl.Value
	Call     ServerRpcRequestCall
}

func (ServerRpcRequest) __VDLReflect(struct {
	Name string `vdl:"v.io/x/ref/services/wspr/internal/rpc/server.ServerRpcRequest"`
}) {
}

// A reply from javascript to a lookup request.
type LookupReply struct {
	Handle        int32
	HasAuthorizer bool
	HasGlobber    bool
	Signature     []signature.Interface
	Err           error
}

func (LookupReply) __VDLReflect(struct {
	Name string `vdl:"v.io/x/ref/services/wspr/internal/rpc/server.LookupReply"`
}) {
}

// A reply from javascript to an auth request.
type AuthReply struct {
	Err error
}

func (AuthReply) __VDLReflect(struct {
	Name string `vdl:"v.io/x/ref/services/wspr/internal/rpc/server.AuthReply"`
}) {
}

func init() {
	vdl.Register((*Context)(nil))
	vdl.Register((*SecurityCall)(nil))
	vdl.Register((*CaveatValidationRequest)(nil))
	vdl.Register((*CaveatValidationResponse)(nil))
	vdl.Register((*ServerRpcRequestCall)(nil))
	vdl.Register((*ServerRpcRequest)(nil))
	vdl.Register((*LookupReply)(nil))
	vdl.Register((*AuthReply)(nil))
}

var (
	ErrCaveatValidationTimeout                 = verror.Register("v.io/x/ref/services/wspr/internal/rpc/server.CaveatValidationTimeout", verror.NoRetry, "{1:}{2:} Caveat validation has timed out")
	ErrInvalidValidationResponseFromJavascript = verror.Register("v.io/x/ref/services/wspr/internal/rpc/server.InvalidValidationResponseFromJavascript", verror.NoRetry, "{1:}{2:} Invalid validation response from javascript")
	ErrServerStopped                           = verror.Register("v.io/x/ref/services/wspr/internal/rpc/server.ServerStopped", verror.RetryBackoff, "{1:}{2:} Server has been stopped")
)

func init() {
	i18n.Cat().SetWithBase(i18n.LangID("en"), i18n.MsgID(ErrCaveatValidationTimeout.ID), "{1:}{2:} Caveat validation has timed out")
	i18n.Cat().SetWithBase(i18n.LangID("en"), i18n.MsgID(ErrInvalidValidationResponseFromJavascript.ID), "{1:}{2:} Invalid validation response from javascript")
	i18n.Cat().SetWithBase(i18n.LangID("en"), i18n.MsgID(ErrServerStopped.ID), "{1:}{2:} Server has been stopped")
}

// NewErrCaveatValidationTimeout returns an error with the ErrCaveatValidationTimeout ID.
func NewErrCaveatValidationTimeout(ctx *context.T) error {
	return verror.New(ErrCaveatValidationTimeout, ctx)
}

// NewErrInvalidValidationResponseFromJavascript returns an error with the ErrInvalidValidationResponseFromJavascript ID.
func NewErrInvalidValidationResponseFromJavascript(ctx *context.T) error {
	return verror.New(ErrInvalidValidationResponseFromJavascript, ctx)
}

// NewErrServerStopped returns an error with the ErrServerStopped ID.
func NewErrServerStopped(ctx *context.T) error {
	return verror.New(ErrServerStopped, ctx)
}
