// This file was auto-generated by the vanadium vdl tool.
// Source: config.vdl

package device

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

// ConfigClientMethods is the client interface
// containing Config methods.
//
// Config is an RPC API to the config service.
type ConfigClientMethods interface {
	// Set sets the value for key.
	Set(ctx *context.T, key string, value string, opts ...ipc.CallOpt) error
}

// ConfigClientStub adds universal methods to ConfigClientMethods.
type ConfigClientStub interface {
	ConfigClientMethods
	ipc.UniversalServiceMethods
}

// ConfigClient returns a client stub for Config.
func ConfigClient(name string, opts ...ipc.BindOpt) ConfigClientStub {
	var client ipc.Client
	for _, opt := range opts {
		if clientOpt, ok := opt.(ipc.Client); ok {
			client = clientOpt
		}
	}
	return implConfigClientStub{name, client}
}

type implConfigClientStub struct {
	name   string
	client ipc.Client
}

func (c implConfigClientStub) c(ctx *context.T) ipc.Client {
	if c.client != nil {
		return c.client
	}
	return v23.GetClient(ctx)
}

func (c implConfigClientStub) Set(ctx *context.T, i0 string, i1 string, opts ...ipc.CallOpt) (err error) {
	var call ipc.ClientCall
	if call, err = c.c(ctx).StartCall(ctx, c.name, "Set", []interface{}{i0, i1}, opts...); err != nil {
		return
	}
	err = call.Finish()
	return
}

// ConfigServerMethods is the interface a server writer
// implements for Config.
//
// Config is an RPC API to the config service.
type ConfigServerMethods interface {
	// Set sets the value for key.
	Set(call ipc.ServerCall, key string, value string) error
}

// ConfigServerStubMethods is the server interface containing
// Config methods, as expected by ipc.Server.
// There is no difference between this interface and ConfigServerMethods
// since there are no streaming methods.
type ConfigServerStubMethods ConfigServerMethods

// ConfigServerStub adds universal methods to ConfigServerStubMethods.
type ConfigServerStub interface {
	ConfigServerStubMethods
	// Describe the Config interfaces.
	Describe__() []ipc.InterfaceDesc
}

// ConfigServer returns a server stub for Config.
// It converts an implementation of ConfigServerMethods into
// an object that may be used by ipc.Server.
func ConfigServer(impl ConfigServerMethods) ConfigServerStub {
	stub := implConfigServerStub{
		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 := ipc.NewGlobState(stub); gs != nil {
		stub.gs = gs
	} else if gs := ipc.NewGlobState(impl); gs != nil {
		stub.gs = gs
	}
	return stub
}

type implConfigServerStub struct {
	impl ConfigServerMethods
	gs   *ipc.GlobState
}

func (s implConfigServerStub) Set(call ipc.ServerCall, i0 string, i1 string) error {
	return s.impl.Set(call, i0, i1)
}

func (s implConfigServerStub) Globber() *ipc.GlobState {
	return s.gs
}

func (s implConfigServerStub) Describe__() []ipc.InterfaceDesc {
	return []ipc.InterfaceDesc{ConfigDesc}
}

// ConfigDesc describes the Config interface.
var ConfigDesc ipc.InterfaceDesc = descConfig

// descConfig hides the desc to keep godoc clean.
var descConfig = ipc.InterfaceDesc{
	Name:    "Config",
	PkgPath: "v.io/x/ref/services/mgmt/device",
	Doc:     "// Config is an RPC API to the config service.",
	Methods: []ipc.MethodDesc{
		{
			Name: "Set",
			Doc:  "// Set sets the value for key.",
			InArgs: []ipc.ArgDesc{
				{"key", ``},   // string
				{"value", ``}, // string
			},
		},
	},
}
