// 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.
// Package: lock

// Package lock defines the interface and implementation
// for managing a physical lock.
//
// Each lock device runs a Vanadium RPC service that offers
// methods for locking and unlocking it. The Vanadium RPC protocol
// allows clients to securely communicate with this service in a
// peer to peer manner.
//
// The key for a lock is a blessing obtained during lock initialization.
// Only clients that present this blessing or extensions of it have access
// to the lock. Clients can delegate access to the lock to other principals
// by blessing them using this 'key' blessing.
package lock

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

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

//////////////////////////////////////////////////
// Type definitions

// LockStatus  indicates the status (locked or unlocked) of a lock.
type LockStatus int32

func (LockStatus) __VDLReflect(struct {
	Name string `vdl:"v.io/x/lock.LockStatus"`
}) {
}

func (x LockStatus) VDLIsZero() bool {
	return x == 0
}

func (x LockStatus) VDLWrite(enc vdl.Encoder) error {
	if err := enc.WriteValueInt(__VDLType_int32_1, int64(x)); err != nil {
		return err
	}
	return nil
}

func (x *LockStatus) VDLRead(dec vdl.Decoder) error {
	switch value, err := dec.ReadValueInt(32); {
	case err != nil:
		return err
	default:
		*x = LockStatus(value)
	}
	return nil
}

//////////////////////////////////////////////////
// Const definitions

const Locked = LockStatus(0)
const Unlocked = LockStatus(1)

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

// UnclaimedLockClientMethods is the client interface
// containing UnclaimedLock methods.
//
// UnclaimedLock represents an unclaimed lock device. It is the state
// in which the lock would be after a "factory reset".
//
// Claim is used to initialize the lock and create a blessing for the caller.
//
// Once initialized, this interface will be disabled and the device will instead
// export the 'Lock' interface. Only principals that present a blessing obtained
// by a call to UnclaimedLock.Claim, or an extension of it, will be authorized.
type UnclaimedLockClientMethods interface {
	// Claim makes the device export the "Lock" interface and returns a blessing
	// bound to the caller that can be used to invoke methods on the "Lock"
	// interface.
	//
	// The 'name' is the blessing name that the device will subsequently use to
	// authenticate to its callers.
	Claim(_ *context.T, name string, _ ...rpc.CallOpt) (security.Blessings, error)
}

// UnclaimedLockClientStub adds universal methods to UnclaimedLockClientMethods.
type UnclaimedLockClientStub interface {
	UnclaimedLockClientMethods
	rpc.UniversalServiceMethods
}

// UnclaimedLockClient returns a client stub for UnclaimedLock.
func UnclaimedLockClient(name string) UnclaimedLockClientStub {
	return implUnclaimedLockClientStub{name}
}

type implUnclaimedLockClientStub struct {
	name string
}

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

// UnclaimedLockServerMethods is the interface a server writer
// implements for UnclaimedLock.
//
// UnclaimedLock represents an unclaimed lock device. It is the state
// in which the lock would be after a "factory reset".
//
// Claim is used to initialize the lock and create a blessing for the caller.
//
// Once initialized, this interface will be disabled and the device will instead
// export the 'Lock' interface. Only principals that present a blessing obtained
// by a call to UnclaimedLock.Claim, or an extension of it, will be authorized.
type UnclaimedLockServerMethods interface {
	// Claim makes the device export the "Lock" interface and returns a blessing
	// bound to the caller that can be used to invoke methods on the "Lock"
	// interface.
	//
	// The 'name' is the blessing name that the device will subsequently use to
	// authenticate to its callers.
	Claim(_ *context.T, _ rpc.ServerCall, name string) (security.Blessings, error)
}

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

// UnclaimedLockServerStub adds universal methods to UnclaimedLockServerStubMethods.
type UnclaimedLockServerStub interface {
	UnclaimedLockServerStubMethods
	// Describe the UnclaimedLock interfaces.
	Describe__() []rpc.InterfaceDesc
}

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

func (s implUnclaimedLockServerStub) Claim(ctx *context.T, call rpc.ServerCall, i0 string) (security.Blessings, error) {
	return s.impl.Claim(ctx, call, i0)
}

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

func (s implUnclaimedLockServerStub) Describe__() []rpc.InterfaceDesc {
	return []rpc.InterfaceDesc{UnclaimedLockDesc}
}

// UnclaimedLockDesc describes the UnclaimedLock interface.
var UnclaimedLockDesc rpc.InterfaceDesc = descUnclaimedLock

// descUnclaimedLock hides the desc to keep godoc clean.
var descUnclaimedLock = rpc.InterfaceDesc{
	Name:    "UnclaimedLock",
	PkgPath: "v.io/x/lock",
	Doc:     "// UnclaimedLock represents an unclaimed lock device. It is the state\n// in which the lock would be after a \"factory reset\".\n//\n// Claim is used to initialize the lock and create a blessing for the caller.\n//\n// Once initialized, this interface will be disabled and the device will instead\n// export the 'Lock' interface. Only principals that present a blessing obtained\n// by a call to UnclaimedLock.Claim, or an extension of it, will be authorized.",
	Methods: []rpc.MethodDesc{
		{
			Name: "Claim",
			Doc:  "// Claim makes the device export the \"Lock\" interface and returns a blessing\n// bound to the caller that can be used to invoke methods on the \"Lock\"\n// interface.\n//\n// The 'name' is the blessing name that the device will subsequently use to\n// authenticate to its callers.",
			InArgs: []rpc.ArgDesc{
				{"name", ``}, // string
			},
			OutArgs: []rpc.ArgDesc{
				{"", ``}, // security.Blessings
			},
		},
	},
}

// LockClientMethods is the client interface
// containing Lock methods.
//
// Lock is the interface for managing a physical lock.
//
// Only principals that present a blessing obtained by a call to UnclaimedLock.Claim,
// or an extension of it, will be authorized.
type LockClientMethods interface {
	// Lock locks the lock.
	Lock(*context.T, ...rpc.CallOpt) error
	// Unlock unlocks the lock.
	Unlock(*context.T, ...rpc.CallOpt) error
	// Status returns the current status (locked or unlocked) of the
	// lock.
	Status(*context.T, ...rpc.CallOpt) (LockStatus, error)
}

// LockClientStub adds universal methods to LockClientMethods.
type LockClientStub interface {
	LockClientMethods
	rpc.UniversalServiceMethods
}

// LockClient returns a client stub for Lock.
func LockClient(name string) LockClientStub {
	return implLockClientStub{name}
}

type implLockClientStub struct {
	name string
}

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

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

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

// LockServerMethods is the interface a server writer
// implements for Lock.
//
// Lock is the interface for managing a physical lock.
//
// Only principals that present a blessing obtained by a call to UnclaimedLock.Claim,
// or an extension of it, will be authorized.
type LockServerMethods interface {
	// Lock locks the lock.
	Lock(*context.T, rpc.ServerCall) error
	// Unlock unlocks the lock.
	Unlock(*context.T, rpc.ServerCall) error
	// Status returns the current status (locked or unlocked) of the
	// lock.
	Status(*context.T, rpc.ServerCall) (LockStatus, error)
}

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

// LockServerStub adds universal methods to LockServerStubMethods.
type LockServerStub interface {
	LockServerStubMethods
	// Describe the Lock interfaces.
	Describe__() []rpc.InterfaceDesc
}

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

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

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

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

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

func (s implLockServerStub) Describe__() []rpc.InterfaceDesc {
	return []rpc.InterfaceDesc{LockDesc}
}

// LockDesc describes the Lock interface.
var LockDesc rpc.InterfaceDesc = descLock

// descLock hides the desc to keep godoc clean.
var descLock = rpc.InterfaceDesc{
	Name:    "Lock",
	PkgPath: "v.io/x/lock",
	Doc:     "// Lock is the interface for managing a physical lock.\n//\n// Only principals that present a blessing obtained by a call to UnclaimedLock.Claim,\n// or an extension of it, will be authorized.",
	Methods: []rpc.MethodDesc{
		{
			Name: "Lock",
			Doc:  "// Lock locks the lock.",
		},
		{
			Name: "Unlock",
			Doc:  "// Unlock unlocks the lock.",
		},
		{
			Name: "Status",
			Doc:  "// Status returns the current status (locked or unlocked) of the\n// lock.",
			OutArgs: []rpc.ArgDesc{
				{"", ``}, // LockStatus
			},
		},
	},
}

// Hold type definitions in package-level variables, for better performance.
var (
	__VDLType_int32_1 *vdl.Type
)

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

	// Register types.
	vdl.Register((*LockStatus)(nil))

	// Initialize type definitions.
	__VDLType_int32_1 = vdl.TypeOf((*LockStatus)(nil))

	return struct{}{}
}
