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

package main

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

// PingPongClientMethods is the client interface
// containing PingPong methods.
//
// Simple service used in the agent tests.
type PingPongClientMethods interface {
	Ping(_ *context.T, message string, _ ...rpc.CallOpt) (string, error)
}

// PingPongClientStub adds universal methods to PingPongClientMethods.
type PingPongClientStub interface {
	PingPongClientMethods
	rpc.UniversalServiceMethods
}

// PingPongClient returns a client stub for PingPong.
func PingPongClient(name string) PingPongClientStub {
	return implPingPongClientStub{name}
}

type implPingPongClientStub struct {
	name string
}

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

// PingPongServerMethods is the interface a server writer
// implements for PingPong.
//
// Simple service used in the agent tests.
type PingPongServerMethods interface {
	Ping(_ *context.T, _ rpc.ServerCall, message string) (string, error)
}

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

// PingPongServerStub adds universal methods to PingPongServerStubMethods.
type PingPongServerStub interface {
	PingPongServerStubMethods
	// Describe the PingPong interfaces.
	Describe__() []rpc.InterfaceDesc
}

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

func (s implPingPongServerStub) Ping(ctx *context.T, call rpc.ServerCall, i0 string) (string, error) {
	return s.impl.Ping(ctx, call, i0)
}

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

func (s implPingPongServerStub) Describe__() []rpc.InterfaceDesc {
	return []rpc.InterfaceDesc{PingPongDesc}
}

// PingPongDesc describes the PingPong interface.
var PingPongDesc rpc.InterfaceDesc = descPingPong

// descPingPong hides the desc to keep godoc clean.
var descPingPong = rpc.InterfaceDesc{
	Name:    "PingPong",
	PkgPath: "v.io/x/ref/services/agent/internal/pingpong",
	Doc:     "// Simple service used in the agent tests.",
	Methods: []rpc.MethodDesc{
		{
			Name: "Ping",
			InArgs: []rpc.ArgDesc{
				{"message", ``}, // string
			},
			OutArgs: []rpc.ArgDesc{
				{"", ``}, // string
			},
		},
	},
}
