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

package stress

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

	// VDL user imports
	"time"
	"v.io/v23/security/access"
	_ "v.io/v23/vdlroot/time"
)

type StressResults struct {
	Iterations  int64
	Qps         float64
	MsecsPerRpc float64
}

func (StressResults) __VDLReflect(struct {
	Name string `vdl:"v.io/x/js.core/stress.StressResults"`
}) {
}

func init() {
	vdl.Register((*StressResults)(nil))
}

// StressClientMethods is the client interface
// containing Stress methods.
type StressClientMethods interface {
	// Echo returns the payload that it receives.
	Echo(_ *context.T, Payload []byte, _ ...rpc.CallOpt) ([]byte, error)
	// ServerEcho runs as many calls to Echo on the name provided in the duration
	// specified and returns the peformance results.
	ServerEcho(_ *context.T, totalTime time.Duration, name string, _ ...rpc.CallOpt) (StressResults, error)
}

// StressClientStub adds universal methods to StressClientMethods.
type StressClientStub interface {
	StressClientMethods
	rpc.UniversalServiceMethods
}

// StressClient returns a client stub for Stress.
func StressClient(name string) StressClientStub {
	return implStressClientStub{name}
}

type implStressClientStub struct {
	name string
}

func (c implStressClientStub) Echo(ctx *context.T, i0 []byte, opts ...rpc.CallOpt) (o0 []byte, err error) {
	err = v23.GetClient(ctx).Call(ctx, c.name, "Echo", []interface{}{i0}, []interface{}{&o0}, opts...)
	return
}

func (c implStressClientStub) ServerEcho(ctx *context.T, i0 time.Duration, i1 string, opts ...rpc.CallOpt) (o0 StressResults, err error) {
	err = v23.GetClient(ctx).Call(ctx, c.name, "ServerEcho", []interface{}{i0, i1}, []interface{}{&o0}, opts...)
	return
}

// StressServerMethods is the interface a server writer
// implements for Stress.
type StressServerMethods interface {
	// Echo returns the payload that it receives.
	Echo(_ *context.T, _ rpc.ServerCall, Payload []byte) ([]byte, error)
	// ServerEcho runs as many calls to Echo on the name provided in the duration
	// specified and returns the peformance results.
	ServerEcho(_ *context.T, _ rpc.ServerCall, totalTime time.Duration, name string) (StressResults, error)
}

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

// StressServerStub adds universal methods to StressServerStubMethods.
type StressServerStub interface {
	StressServerStubMethods
	// Describe the Stress interfaces.
	Describe__() []rpc.InterfaceDesc
}

// StressServer returns a server stub for Stress.
// It converts an implementation of StressServerMethods into
// an object that may be used by rpc.Server.
func StressServer(impl StressServerMethods) StressServerStub {
	stub := implStressServerStub{
		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 implStressServerStub struct {
	impl StressServerMethods
	gs   *rpc.GlobState
}

func (s implStressServerStub) Echo(ctx *context.T, call rpc.ServerCall, i0 []byte) ([]byte, error) {
	return s.impl.Echo(ctx, call, i0)
}

func (s implStressServerStub) ServerEcho(ctx *context.T, call rpc.ServerCall, i0 time.Duration, i1 string) (StressResults, error) {
	return s.impl.ServerEcho(ctx, call, i0, i1)
}

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

func (s implStressServerStub) Describe__() []rpc.InterfaceDesc {
	return []rpc.InterfaceDesc{StressDesc}
}

// StressDesc describes the Stress interface.
var StressDesc rpc.InterfaceDesc = descStress

// descStress hides the desc to keep godoc clean.
var descStress = rpc.InterfaceDesc{
	Name:    "Stress",
	PkgPath: "v.io/x/js.core/stress",
	Methods: []rpc.MethodDesc{
		{
			Name: "Echo",
			Doc:  "// Echo returns the payload that it receives.",
			InArgs: []rpc.ArgDesc{
				{"Payload", ``}, // []byte
			},
			OutArgs: []rpc.ArgDesc{
				{"", ``}, // []byte
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Read"))},
		},
		{
			Name: "ServerEcho",
			Doc:  "// ServerEcho runs as many calls to Echo on the name provided in the duration\n// specified and returns the peformance results.",
			InArgs: []rpc.ArgDesc{
				{"totalTime", ``}, // time.Duration
				{"name", ``},      // string
			},
			OutArgs: []rpc.ArgDesc{
				{"", ``}, // StressResults
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Read"))},
		},
	},
}
