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

package mounttablelib

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

// CollectionClientMethods is the client interface
// containing Collection methods.
type CollectionClientMethods interface {
	// Export sets the value for a name.  Overwrite controls the behavior when
	// an entry exists, if Overwrite is true, then the binding is replaced,
	// otherwise the call fails with an error.  The Val must be no larger than
	// MaxSize bytes.
	Export(ctx *context.T, Val string, Overwrite bool, opts ...rpc.CallOpt) error
	// Lookup retrieves the value associated with a name.  Returns an error if
	// there is no such binding.
	Lookup(*context.T, ...rpc.CallOpt) ([]byte, error)
}

// CollectionClientStub adds universal methods to CollectionClientMethods.
type CollectionClientStub interface {
	CollectionClientMethods
	rpc.UniversalServiceMethods
}

// CollectionClient returns a client stub for Collection.
func CollectionClient(name string) CollectionClientStub {
	return implCollectionClientStub{name}
}

type implCollectionClientStub struct {
	name string
}

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

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

// CollectionServerMethods is the interface a server writer
// implements for Collection.
type CollectionServerMethods interface {
	// Export sets the value for a name.  Overwrite controls the behavior when
	// an entry exists, if Overwrite is true, then the binding is replaced,
	// otherwise the call fails with an error.  The Val must be no larger than
	// MaxSize bytes.
	Export(ctx *context.T, call rpc.ServerCall, Val string, Overwrite bool) error
	// Lookup retrieves the value associated with a name.  Returns an error if
	// there is no such binding.
	Lookup(*context.T, rpc.ServerCall) ([]byte, error)
}

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

// CollectionServerStub adds universal methods to CollectionServerStubMethods.
type CollectionServerStub interface {
	CollectionServerStubMethods
	// Describe the Collection interfaces.
	Describe__() []rpc.InterfaceDesc
}

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

func (s implCollectionServerStub) Export(ctx *context.T, call rpc.ServerCall, i0 string, i1 bool) error {
	return s.impl.Export(ctx, call, i0, i1)
}

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

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

func (s implCollectionServerStub) Describe__() []rpc.InterfaceDesc {
	return []rpc.InterfaceDesc{CollectionDesc}
}

// CollectionDesc describes the Collection interface.
var CollectionDesc rpc.InterfaceDesc = descCollection

// descCollection hides the desc to keep godoc clean.
var descCollection = rpc.InterfaceDesc{
	Name:    "Collection",
	PkgPath: "v.io/x/ref/services/mounttable/mounttablelib",
	Methods: []rpc.MethodDesc{
		{
			Name: "Export",
			Doc:  "// Export sets the value for a name.  Overwrite controls the behavior when\n// an entry exists, if Overwrite is true, then the binding is replaced,\n// otherwise the call fails with an error.  The Val must be no larger than\n// MaxSize bytes.",
			InArgs: []rpc.ArgDesc{
				{"Val", ``},       // string
				{"Overwrite", ``}, // bool
			},
		},
		{
			Name: "Lookup",
			Doc:  "// Lookup retrieves the value associated with a name.  Returns an error if\n// there is no such binding.",
			OutArgs: []rpc.ArgDesc{
				{"", ``}, // []byte
			},
		},
	},
}
