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

package device

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

// 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(_ *context.T, key string, value string, _ ...rpc.CallOpt) error
}

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

// ConfigClient returns a client stub for Config.
func ConfigClient(name string) ConfigClientStub {
	return implConfigClientStub{name}
}

type implConfigClientStub struct {
	name string
}

func (c implConfigClientStub) Set(ctx *context.T, i0 string, i1 string, opts ...rpc.CallOpt) (err error) {
	err = v23.GetClient(ctx).Call(ctx, c.name, "Set", []interface{}{i0, i1}, nil, opts...)
	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(_ *context.T, _ rpc.ServerCall, key string, value string) error
}

// ConfigServerStubMethods is the server interface containing
// Config methods, as expected by rpc.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__() []rpc.InterfaceDesc
}

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

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

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

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

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

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

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