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

package test_service

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

// CancelCollectorClientMethods is the client interface
// containing CancelCollector methods.
//
// CancelCollector is a test interface for use in testing cancellation and deadlines.
type CancelCollectorClientMethods interface {
	// A function that never returns, but records the status of the given key.
	NeverReturn(_ *context.T, key int64, _ ...rpc.CallOpt) error
	// Wait for the call with the given key to have the given status.  Possible statuses are:
	// "running", and, "cancelled".  Returns the number of nanoseconds left on
	// the deadline of the specified call when the call first began.
	WaitForStatus(_ *context.T, key int64, status string, _ ...rpc.CallOpt) (timeout int64, _ error)
}

// CancelCollectorClientStub adds universal methods to CancelCollectorClientMethods.
type CancelCollectorClientStub interface {
	CancelCollectorClientMethods
	rpc.UniversalServiceMethods
}

// CancelCollectorClient returns a client stub for CancelCollector.
func CancelCollectorClient(name string) CancelCollectorClientStub {
	return implCancelCollectorClientStub{name}
}

type implCancelCollectorClientStub struct {
	name string
}

func (c implCancelCollectorClientStub) NeverReturn(ctx *context.T, i0 int64, opts ...rpc.CallOpt) (err error) {
	err = v23.GetClient(ctx).Call(ctx, c.name, "NeverReturn", []interface{}{i0}, nil, opts...)
	return
}

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

// CancelCollectorServerMethods is the interface a server writer
// implements for CancelCollector.
//
// CancelCollector is a test interface for use in testing cancellation and deadlines.
type CancelCollectorServerMethods interface {
	// A function that never returns, but records the status of the given key.
	NeverReturn(_ *context.T, _ rpc.ServerCall, key int64) error
	// Wait for the call with the given key to have the given status.  Possible statuses are:
	// "running", and, "cancelled".  Returns the number of nanoseconds left on
	// the deadline of the specified call when the call first began.
	WaitForStatus(_ *context.T, _ rpc.ServerCall, key int64, status string) (timeout int64, _ error)
}

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

// CancelCollectorServerStub adds universal methods to CancelCollectorServerStubMethods.
type CancelCollectorServerStub interface {
	CancelCollectorServerStubMethods
	// Describe the CancelCollector interfaces.
	Describe__() []rpc.InterfaceDesc
}

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

func (s implCancelCollectorServerStub) NeverReturn(ctx *context.T, call rpc.ServerCall, i0 int64) error {
	return s.impl.NeverReturn(ctx, call, i0)
}

func (s implCancelCollectorServerStub) WaitForStatus(ctx *context.T, call rpc.ServerCall, i0 int64, i1 string) (int64, error) {
	return s.impl.WaitForStatus(ctx, call, i0, i1)
}

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

func (s implCancelCollectorServerStub) Describe__() []rpc.InterfaceDesc {
	return []rpc.InterfaceDesc{CancelCollectorDesc}
}

// CancelCollectorDesc describes the CancelCollector interface.
var CancelCollectorDesc rpc.InterfaceDesc = descCancelCollector

// descCancelCollector hides the desc to keep godoc clean.
var descCancelCollector = rpc.InterfaceDesc{
	Name:    "CancelCollector",
	PkgPath: "v.io/x/js.core/test_service",
	Doc:     "// CancelCollector is a test interface for use in testing cancellation and deadlines.",
	Methods: []rpc.MethodDesc{
		{
			Name: "NeverReturn",
			Doc:  "// A function that never returns, but records the status of the given key.",
			InArgs: []rpc.ArgDesc{
				{"key", ``}, // int64
			},
		},
		{
			Name: "WaitForStatus",
			Doc:  "// Wait for the call with the given key to have the given status.  Possible statuses are:\n// \"running\", and, \"cancelled\".  Returns the number of nanoseconds left on\n// the deadline of the specified call when the call first began.",
			InArgs: []rpc.ArgDesc{
				{"key", ``},    // int64
				{"status", ``}, // string
			},
			OutArgs: []rpc.ArgDesc{
				{"timeout", ``}, // int64
			},
		},
	},
}
