// 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"
	"v.io/v23/vdl/vdlconv"
)

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 (m *LockStatus) FillVDLTarget(t vdl.Target, tt *vdl.Type) error {
	if err := t.FromInt(int64((*m)), tt); err != nil {
		return err
	}
	return nil
}

func (m *LockStatus) MakeVDLTarget() vdl.Target {
	return &LockStatusTarget{Value: m}
}

type LockStatusTarget struct {
	Value *LockStatus
	vdl.TargetBase
}

func (t *LockStatusTarget) FromUint(src uint64, tt *vdl.Type) error {

	val, err := vdlconv.Uint64ToInt32(src)
	if err != nil {
		return err
	}
	*t.Value = LockStatus(val)

	return nil
}
func (t *LockStatusTarget) FromInt(src int64, tt *vdl.Type) error {

	val, err := vdlconv.Int64ToInt32(src)
	if err != nil {
		return err
	}
	*t.Value = LockStatus(val)

	return nil
}
func (t *LockStatusTarget) FromFloat(src float64, tt *vdl.Type) error {

	val, err := vdlconv.Float64ToInt32(src)
	if err != nil {
		return err
	}
	*t.Value = LockStatus(val)

	return nil
}

// Create zero values for each type.
var (
	__VDLZeroLockStatus = LockStatus(0)
)

//////////////////////////////////////////////////
// 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
			},
		},
	},
}

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{}{}
	}

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

	return struct{}{}
}
