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

package sample

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

// RoboDogStatus represents the status of a robotic dog.
type RoboDogStatus struct {
	Name   string // the dog's current name
	Mood   string // mood improves when played with and not hungry
	Hunger string // hunger worsens over time. Improves while eating.
	Eating bool   // the dog is busy while eating.
}

func (RoboDogStatus) __VDLReflect(struct {
	Name string "v.io/x/browser/sample.RoboDogStatus"
}) {
}

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

// PetFeederClientMethods is the client interface
// containing PetFeeder methods.
//
// PetFeeder allows clients to remotely feed their pets.
type PetFeederClientMethods interface {
	// Status returns the current status of the PetFeeder (how full the bowl is).
	Status(*context.T, ...rpc.CallOpt) (float64, error)
	// Fill fills the pet feeder bowl with food. Errors if the bowl will overflow.
	Fill(ctx *context.T, amount float64, opts ...rpc.CallOpt) error
	// Empty removes all food from the pet feeder bowl.
	Empty(*context.T, ...rpc.CallOpt) error
}

// PetFeederClientStub adds universal methods to PetFeederClientMethods.
type PetFeederClientStub interface {
	PetFeederClientMethods
	rpc.UniversalServiceMethods
}

// PetFeederClient returns a client stub for PetFeeder.
func PetFeederClient(name string) PetFeederClientStub {
	return implPetFeederClientStub{name}
}

type implPetFeederClientStub struct {
	name string
}

func (c implPetFeederClientStub) Status(ctx *context.T, opts ...rpc.CallOpt) (o0 float64, err error) {
	err = v23.GetClient(ctx).Call(ctx, c.name, "Status", nil, []interface{}{&o0}, opts...)
	return
}

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

func (c implPetFeederClientStub) Empty(ctx *context.T, opts ...rpc.CallOpt) (err error) {
	err = v23.GetClient(ctx).Call(ctx, c.name, "Empty", nil, nil, opts...)
	return
}

// PetFeederServerMethods is the interface a server writer
// implements for PetFeeder.
//
// PetFeeder allows clients to remotely feed their pets.
type PetFeederServerMethods interface {
	// Status returns the current status of the PetFeeder (how full the bowl is).
	Status(*context.T, rpc.ServerCall) (float64, error)
	// Fill fills the pet feeder bowl with food. Errors if the bowl will overflow.
	Fill(ctx *context.T, call rpc.ServerCall, amount float64) error
	// Empty removes all food from the pet feeder bowl.
	Empty(*context.T, rpc.ServerCall) error
}

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

// PetFeederServerStub adds universal methods to PetFeederServerStubMethods.
type PetFeederServerStub interface {
	PetFeederServerStubMethods
	// Describe the PetFeeder interfaces.
	Describe__() []rpc.InterfaceDesc
}

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

func (s implPetFeederServerStub) Status(ctx *context.T, call rpc.ServerCall) (float64, error) {
	return s.impl.Status(ctx, call)
}

func (s implPetFeederServerStub) Fill(ctx *context.T, call rpc.ServerCall, i0 float64) error {
	return s.impl.Fill(ctx, call, i0)
}

func (s implPetFeederServerStub) Empty(ctx *context.T, call rpc.ServerCall) error {
	return s.impl.Empty(ctx, call)
}

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

func (s implPetFeederServerStub) Describe__() []rpc.InterfaceDesc {
	return []rpc.InterfaceDesc{PetFeederDesc}
}

// PetFeederDesc describes the PetFeeder interface.
var PetFeederDesc rpc.InterfaceDesc = descPetFeeder

// descPetFeeder hides the desc to keep godoc clean.
var descPetFeeder = rpc.InterfaceDesc{
	Name:    "PetFeeder",
	PkgPath: "v.io/x/browser/sample",
	Doc:     "// PetFeeder allows clients to remotely feed their pets.",
	Methods: []rpc.MethodDesc{
		{
			Name: "Status",
			Doc:  "// Status returns the current status of the PetFeeder (how full the bowl is).",
			OutArgs: []rpc.ArgDesc{
				{"", ``}, // float64
			},
		},
		{
			Name: "Fill",
			Doc:  "// Fill fills the pet feeder bowl with food. Errors if the bowl will overflow.",
			InArgs: []rpc.ArgDesc{
				{"amount", ``}, // float64
			},
		},
		{
			Name: "Empty",
			Doc:  "// Empty removes all food from the pet feeder bowl.",
		},
	},
}

// RoboDogClientMethods is the client interface
// containing RoboDog methods.
//
// RoboDog allows clients to play with a virtual robotic dog.
type RoboDogClientMethods interface {
	// Status returns the state of the robotic dog.
	Status(*context.T, ...rpc.CallOpt) (RoboDogStatus, error)
	// Speak allows a client to speak with the robotic dog.
	Speak(ctx *context.T, words string, opts ...rpc.CallOpt) (string, error)
	// Play allows a client to play with the robotic dog.
	// Errors if the dog does not want to play.
	Play(ctx *context.T, duration uint32, opts ...rpc.CallOpt) error
	// SetName allows a client to set the robotic dog's name.
	SetName(ctx *context.T, name string, opts ...rpc.CallOpt) error
}

// RoboDogClientStub adds universal methods to RoboDogClientMethods.
type RoboDogClientStub interface {
	RoboDogClientMethods
	rpc.UniversalServiceMethods
}

// RoboDogClient returns a client stub for RoboDog.
func RoboDogClient(name string) RoboDogClientStub {
	return implRoboDogClientStub{name}
}

type implRoboDogClientStub struct {
	name string
}

func (c implRoboDogClientStub) Status(ctx *context.T, opts ...rpc.CallOpt) (o0 RoboDogStatus, err error) {
	err = v23.GetClient(ctx).Call(ctx, c.name, "Status", nil, []interface{}{&o0}, opts...)
	return
}

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

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

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

// RoboDogServerMethods is the interface a server writer
// implements for RoboDog.
//
// RoboDog allows clients to play with a virtual robotic dog.
type RoboDogServerMethods interface {
	// Status returns the state of the robotic dog.
	Status(*context.T, rpc.ServerCall) (RoboDogStatus, error)
	// Speak allows a client to speak with the robotic dog.
	Speak(ctx *context.T, call rpc.ServerCall, words string) (string, error)
	// Play allows a client to play with the robotic dog.
	// Errors if the dog does not want to play.
	Play(ctx *context.T, call rpc.ServerCall, duration uint32) error
	// SetName allows a client to set the robotic dog's name.
	SetName(ctx *context.T, call rpc.ServerCall, name string) error
}

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

// RoboDogServerStub adds universal methods to RoboDogServerStubMethods.
type RoboDogServerStub interface {
	RoboDogServerStubMethods
	// Describe the RoboDog interfaces.
	Describe__() []rpc.InterfaceDesc
}

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

func (s implRoboDogServerStub) Status(ctx *context.T, call rpc.ServerCall) (RoboDogStatus, error) {
	return s.impl.Status(ctx, call)
}

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

func (s implRoboDogServerStub) Play(ctx *context.T, call rpc.ServerCall, i0 uint32) error {
	return s.impl.Play(ctx, call, i0)
}

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

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

func (s implRoboDogServerStub) Describe__() []rpc.InterfaceDesc {
	return []rpc.InterfaceDesc{RoboDogDesc}
}

// RoboDogDesc describes the RoboDog interface.
var RoboDogDesc rpc.InterfaceDesc = descRoboDog

// descRoboDog hides the desc to keep godoc clean.
var descRoboDog = rpc.InterfaceDesc{
	Name:    "RoboDog",
	PkgPath: "v.io/x/browser/sample",
	Doc:     "// RoboDog allows clients to play with a virtual robotic dog.",
	Methods: []rpc.MethodDesc{
		{
			Name: "Status",
			Doc:  "// Status returns the state of the robotic dog.",
			OutArgs: []rpc.ArgDesc{
				{"", ``}, // RoboDogStatus
			},
		},
		{
			Name: "Speak",
			Doc:  "// Speak allows a client to speak with the robotic dog.",
			InArgs: []rpc.ArgDesc{
				{"words", ``}, // string
			},
			OutArgs: []rpc.ArgDesc{
				{"", ``}, // string
			},
		},
		{
			Name: "Play",
			Doc:  "// Play allows a client to play with the robotic dog.\n// Errors if the dog does not want to play.",
			InArgs: []rpc.ArgDesc{
				{"duration", ``}, // uint32
			},
		},
		{
			Name: "SetName",
			Doc:  "// SetName allows a client to set the robotic dog's name.",
			InArgs: []rpc.ArgDesc{
				{"name", ``}, // string
			},
		},
	},
}
