// 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(ctx *context.T, message string, opts ...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(ctx *context.T, call 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
			},
		},
	},
}
