// Copyright 2016 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.
// Package: wakeup

// Package wakeup defines interfaces for waking up remote services, likely running
// on mobile devices (e.g., Android, iOS).
package wakeup

import (
	"v.io/v23"
	"v.io/v23/context"
	"v.io/v23/rpc"
)

var _ = __VDLInit() // Must be first; see __VDLInit comments for details.

//////////////////////////////////////////////////
// Interface definitions

// WakeUpClientMethods is the client interface
// containing WakeUp methods.
//
// WakeUp interface defines methods for services that wish to be woken up remotely.
type WakeUpClientMethods interface {
	// Register returns a rooted name where the service should mount itself
	// in order to be woken up using the provided wakeup token.
	Register(_ *context.T, token string, _ ...rpc.CallOpt) (string, error)
}

// WakeUpClientStub adds universal methods to WakeUpClientMethods.
type WakeUpClientStub interface {
	WakeUpClientMethods
	rpc.UniversalServiceMethods
}

// WakeUpClient returns a client stub for WakeUp.
func WakeUpClient(name string) WakeUpClientStub {
	return implWakeUpClientStub{name}
}

type implWakeUpClientStub struct {
	name string
}

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

// WakeUpServerMethods is the interface a server writer
// implements for WakeUp.
//
// WakeUp interface defines methods for services that wish to be woken up remotely.
type WakeUpServerMethods interface {
	// Register returns a rooted name where the service should mount itself
	// in order to be woken up using the provided wakeup token.
	Register(_ *context.T, _ rpc.ServerCall, token string) (string, error)
}

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

// WakeUpServerStub adds universal methods to WakeUpServerStubMethods.
type WakeUpServerStub interface {
	WakeUpServerStubMethods
	// Describe the WakeUp interfaces.
	Describe__() []rpc.InterfaceDesc
}

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

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

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

func (s implWakeUpServerStub) Describe__() []rpc.InterfaceDesc {
	return []rpc.InterfaceDesc{WakeUpDesc}
}

// WakeUpDesc describes the WakeUp interface.
var WakeUpDesc rpc.InterfaceDesc = descWakeUp

// descWakeUp hides the desc to keep godoc clean.
var descWakeUp = rpc.InterfaceDesc{
	Name:    "WakeUp",
	PkgPath: "v.io/v23/services/wakeup",
	Doc:     "// WakeUp interface defines methods for services that wish to be woken up remotely.",
	Methods: []rpc.MethodDesc{
		{
			Name: "Register",
			Doc:  "// Register returns a rooted name where the service should mount itself\n// in order to be woken up using the provided wakeup token.",
			InArgs: []rpc.ArgDesc{
				{"token", ``}, // string
			},
			OutArgs: []rpc.ArgDesc{
				{"", ``}, // string
			},
		},
	},
}

var __VDLInitCalled bool

// __VDLInit performs vdl initialization.  It is safe to call multiple times.
// If you have an init ordering issue, just insert the following line verbatim
// into your source files in this package, right after the "package foo" clause:
//
//    var _ = __VDLInit()
//
// The purpose of this function is to ensure that vdl initialization occurs in
// the right order, and very early in the init sequence.  In particular, vdl
// registration and package variable initialization needs to occur before
// functions like vdl.TypeOf will work properly.
//
// This function returns a dummy value, so that it can be used to initialize the
// first var in the file, to take advantage of Go's defined init order.
func __VDLInit() struct{} {
	if __VDLInitCalled {
		return struct{}{}
	}
	__VDLInitCalled = true

	return struct{}{}
}
