// 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: discovery

package discovery

import (
	"v.io/v23"
	"v.io/v23/context"
	"v.io/v23/discovery"
	"v.io/v23/i18n"
	"v.io/v23/rpc"
	"v.io/v23/security/access"
	"v.io/v23/vdl"
	"v.io/v23/verror"
)

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

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

type Uuid []byte

func (Uuid) __VDLReflect(struct {
	Name string `vdl:"v.io/x/ref/lib/discovery.Uuid"`
}) {
}

func (x Uuid) VDLIsZero() bool {
	return len(x) == 0
}

func (x Uuid) VDLWrite(enc vdl.Encoder) error {
	if err := enc.WriteValueBytes(__VDLType_list_1, []byte(x)); err != nil {
		return err
	}
	return nil
}

func (x *Uuid) VDLRead(dec vdl.Decoder) error {
	var bytes []byte
	if err := dec.ReadValueBytes(-1, &bytes); err != nil {
		return err
	}
	*x = bytes
	return nil
}

type EncryptionAlgorithm int32

func (EncryptionAlgorithm) __VDLReflect(struct {
	Name string `vdl:"v.io/x/ref/lib/discovery.EncryptionAlgorithm"`
}) {
}

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

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

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

type EncryptionKey []byte

func (EncryptionKey) __VDLReflect(struct {
	Name string `vdl:"v.io/x/ref/lib/discovery.EncryptionKey"`
}) {
}

func (x EncryptionKey) VDLIsZero() bool {
	return len(x) == 0
}

func (x EncryptionKey) VDLWrite(enc vdl.Encoder) error {
	if err := enc.WriteValueBytes(__VDLType_list_3, []byte(x)); err != nil {
		return err
	}
	return nil
}

func (x *EncryptionKey) VDLRead(dec vdl.Decoder) error {
	var bytes []byte
	if err := dec.ReadValueBytes(-1, &bytes); err != nil {
		return err
	}
	*x = bytes
	return nil
}

type AdStatus byte

func (AdStatus) __VDLReflect(struct {
	Name string `vdl:"v.io/x/ref/lib/discovery.AdStatus"`
}) {
}

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

func (x AdStatus) VDLWrite(enc vdl.Encoder) error {
	if err := enc.WriteValueUint(__VDLType_byte_4, uint64(x)); err != nil {
		return err
	}
	return nil
}

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

// An AdHash is a hash of an advertisement.
type AdHash [8]byte

func (AdHash) __VDLReflect(struct {
	Name string `vdl:"v.io/x/ref/lib/discovery.AdHash"`
}) {
}

func (x AdHash) VDLIsZero() bool {
	return x == AdHash{}
}

func (x AdHash) VDLWrite(enc vdl.Encoder) error {
	if err := enc.WriteValueBytes(__VDLType_array_5, x[:]); err != nil {
		return err
	}
	return nil
}

func (x *AdHash) VDLRead(dec vdl.Decoder) error {
	bytes := x[:]
	if err := dec.ReadValueBytes(8, &bytes); err != nil {
		return err
	}
	return nil
}

// AdInfo represents advertisement information for discovery.
type AdInfo struct {
	Ad discovery.Advertisement
	// Type of encryption applied to the advertisement so that it can
	// only be decoded by authorized principals.
	EncryptionAlgorithm EncryptionAlgorithm
	// If the advertisement is encrypted, then the data required to
	// decrypt it. The format of this data is a function of the algorithm.
	EncryptionKeys []EncryptionKey
	// Hash of the current advertisement. This does not include the fields below.
	Hash AdHash
	// Unix time in nanoseconds at which the advertisement was created.
	TimestampNs int64
	// The addresses (vanadium object names) that the advertisement directory service
	// is served on. See directory.vdl.
	DirAddrs []string
	// Status of the current advertisement. Valid for scanned advertisements.
	Status AdStatus
	// TODO(jhahn): Add proximity.
	// TODO(jhahn): Use proximity for Lost.
	Lost bool
}

func (AdInfo) __VDLReflect(struct {
	Name string `vdl:"v.io/x/ref/lib/discovery.AdInfo"`
}) {
}

func (x AdInfo) VDLIsZero() bool {
	if !x.Ad.VDLIsZero() {
		return false
	}
	if x.EncryptionAlgorithm != 0 {
		return false
	}
	if len(x.EncryptionKeys) != 0 {
		return false
	}
	if x.Hash != (AdHash{}) {
		return false
	}
	if x.TimestampNs != 0 {
		return false
	}
	if len(x.DirAddrs) != 0 {
		return false
	}
	if x.Status != 0 {
		return false
	}
	if x.Lost {
		return false
	}
	return true
}

func (x AdInfo) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(__VDLType_struct_6); err != nil {
		return err
	}
	if !x.Ad.VDLIsZero() {
		if err := enc.NextField(0); err != nil {
			return err
		}
		if err := x.Ad.VDLWrite(enc); err != nil {
			return err
		}
	}
	if x.EncryptionAlgorithm != 0 {
		if err := enc.NextFieldValueInt(1, __VDLType_int32_2, int64(x.EncryptionAlgorithm)); err != nil {
			return err
		}
	}
	if len(x.EncryptionKeys) != 0 {
		if err := enc.NextField(2); err != nil {
			return err
		}
		if err := __VDLWriteAnon_list_1(enc, x.EncryptionKeys); err != nil {
			return err
		}
	}
	if x.Hash != (AdHash{}) {
		if err := enc.NextFieldValueBytes(3, __VDLType_array_5, x.Hash[:]); err != nil {
			return err
		}
	}
	if x.TimestampNs != 0 {
		if err := enc.NextFieldValueInt(4, vdl.Int64Type, x.TimestampNs); err != nil {
			return err
		}
	}
	if len(x.DirAddrs) != 0 {
		if err := enc.NextField(5); err != nil {
			return err
		}
		if err := __VDLWriteAnon_list_2(enc, x.DirAddrs); err != nil {
			return err
		}
	}
	if x.Status != 0 {
		if err := enc.NextFieldValueUint(6, __VDLType_byte_4, uint64(x.Status)); err != nil {
			return err
		}
	}
	if x.Lost {
		if err := enc.NextFieldValueBool(7, vdl.BoolType, x.Lost); err != nil {
			return err
		}
	}
	if err := enc.NextField(-1); err != nil {
		return err
	}
	return enc.FinishValue()
}

func __VDLWriteAnon_list_1(enc vdl.Encoder, x []EncryptionKey) error {
	if err := enc.StartValue(__VDLType_list_8); err != nil {
		return err
	}
	if err := enc.SetLenHint(len(x)); err != nil {
		return err
	}
	for _, elem := range x {
		if err := enc.NextEntryValueBytes(__VDLType_list_3, []byte(elem)); err != nil {
			return err
		}
	}
	if err := enc.NextEntry(true); err != nil {
		return err
	}
	return enc.FinishValue()
}

func __VDLWriteAnon_list_2(enc vdl.Encoder, x []string) error {
	if err := enc.StartValue(__VDLType_list_9); err != nil {
		return err
	}
	if err := enc.SetLenHint(len(x)); err != nil {
		return err
	}
	for _, elem := range x {
		if err := enc.NextEntryValueString(vdl.StringType, elem); err != nil {
			return err
		}
	}
	if err := enc.NextEntry(true); err != nil {
		return err
	}
	return enc.FinishValue()
}

func (x *AdInfo) VDLRead(dec vdl.Decoder) error {
	*x = AdInfo{}
	if err := dec.StartValue(__VDLType_struct_6); err != nil {
		return err
	}
	decType := dec.Type()
	for {
		index, err := dec.NextField()
		switch {
		case err != nil:
			return err
		case index == -1:
			return dec.FinishValue()
		}
		if decType != __VDLType_struct_6 {
			index = __VDLType_struct_6.FieldIndexByName(decType.Field(index).Name)
			if index == -1 {
				if err := dec.SkipValue(); err != nil {
					return err
				}
				continue
			}
		}
		switch index {
		case 0:
			if err := x.Ad.VDLRead(dec); err != nil {
				return err
			}
		case 1:
			switch value, err := dec.ReadValueInt(32); {
			case err != nil:
				return err
			default:
				x.EncryptionAlgorithm = EncryptionAlgorithm(value)
			}
		case 2:
			if err := __VDLReadAnon_list_1(dec, &x.EncryptionKeys); err != nil {
				return err
			}
		case 3:
			bytes := x.Hash[:]
			if err := dec.ReadValueBytes(8, &bytes); err != nil {
				return err
			}
		case 4:
			switch value, err := dec.ReadValueInt(64); {
			case err != nil:
				return err
			default:
				x.TimestampNs = value
			}
		case 5:
			if err := __VDLReadAnon_list_2(dec, &x.DirAddrs); err != nil {
				return err
			}
		case 6:
			switch value, err := dec.ReadValueUint(8); {
			case err != nil:
				return err
			default:
				x.Status = AdStatus(value)
			}
		case 7:
			switch value, err := dec.ReadValueBool(); {
			case err != nil:
				return err
			default:
				x.Lost = value
			}
		}
	}
}

func __VDLReadAnon_list_1(dec vdl.Decoder, x *[]EncryptionKey) error {
	if err := dec.StartValue(__VDLType_list_8); err != nil {
		return err
	}
	if len := dec.LenHint(); len > 0 {
		*x = make([]EncryptionKey, 0, len)
	} else {
		*x = nil
	}
	for {
		switch done, err := dec.NextEntry(); {
		case err != nil:
			return err
		case done:
			return dec.FinishValue()
		default:
			var elem EncryptionKey
			var bytes []byte
			if err := dec.ReadValueBytes(-1, &bytes); err != nil {
				return err
			}
			elem = bytes
			*x = append(*x, elem)
		}
	}
}

func __VDLReadAnon_list_2(dec vdl.Decoder, x *[]string) error {
	if err := dec.StartValue(__VDLType_list_9); err != nil {
		return err
	}
	if len := dec.LenHint(); len > 0 {
		*x = make([]string, 0, len)
	} else {
		*x = nil
	}
	for {
		switch done, elem, err := dec.NextEntryValueString(); {
		case err != nil:
			return err
		case done:
			return dec.FinishValue()
		default:
			*x = append(*x, elem)
		}
	}
}

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

const NoEncryption = EncryptionAlgorithm(0)
const TestEncryption = EncryptionAlgorithm(1)
const IbeEncryption = EncryptionAlgorithm(2)
const AdReady = AdStatus(0)          // All information is available
const AdNotReady = AdStatus(1)       // Not all information is available for querying against it
const AdPartiallyReady = AdStatus(2) // All information except attachments is available

//////////////////////////////////////////////////
// Error definitions

var (
	ErrAdvertisementNotFound  = verror.Register("v.io/x/ref/lib/discovery.AdvertisementNotFound", verror.NoRetry, "{1:}{2:} advertisement not found: {3}")
	ErrAlreadyBeingAdvertised = verror.Register("v.io/x/ref/lib/discovery.AlreadyBeingAdvertised", verror.NoRetry, "{1:}{2:} already being advertised: {3}")
	ErrBadAdvertisement       = verror.Register("v.io/x/ref/lib/discovery.BadAdvertisement", verror.NoRetry, "{1:}{2:} invalid advertisement: {3}")
	ErrBadQuery               = verror.Register("v.io/x/ref/lib/discovery.BadQuery", verror.NoRetry, "{1:}{2:} invalid query: {3}")
	ErrDiscoveryClosed        = verror.Register("v.io/x/ref/lib/discovery.DiscoveryClosed", verror.NoRetry, "{1:}{2:} discovery closed")
	ErrNoDiscoveryPlugin      = verror.Register("v.io/x/ref/lib/discovery.NoDiscoveryPlugin", verror.NoRetry, "{1:}{2:} no discovery plugin")
	ErrTooManyPlugins         = verror.Register("v.io/x/ref/lib/discovery.TooManyPlugins", verror.NoRetry, "{1:}{2:} too many plugins ({3}), support at most {4}")
)

// NewErrAdvertisementNotFound returns an error with the ErrAdvertisementNotFound ID.
func NewErrAdvertisementNotFound(ctx *context.T, id discovery.AdId) error {
	return verror.New(ErrAdvertisementNotFound, ctx, id)
}

// NewErrAlreadyBeingAdvertised returns an error with the ErrAlreadyBeingAdvertised ID.
func NewErrAlreadyBeingAdvertised(ctx *context.T, id discovery.AdId) error {
	return verror.New(ErrAlreadyBeingAdvertised, ctx, id)
}

// NewErrBadAdvertisement returns an error with the ErrBadAdvertisement ID.
func NewErrBadAdvertisement(ctx *context.T, err error) error {
	return verror.New(ErrBadAdvertisement, ctx, err)
}

// NewErrBadQuery returns an error with the ErrBadQuery ID.
func NewErrBadQuery(ctx *context.T, err error) error {
	return verror.New(ErrBadQuery, ctx, err)
}

// NewErrDiscoveryClosed returns an error with the ErrDiscoveryClosed ID.
func NewErrDiscoveryClosed(ctx *context.T) error {
	return verror.New(ErrDiscoveryClosed, ctx)
}

// NewErrNoDiscoveryPlugin returns an error with the ErrNoDiscoveryPlugin ID.
func NewErrNoDiscoveryPlugin(ctx *context.T) error {
	return verror.New(ErrNoDiscoveryPlugin, ctx)
}

// NewErrTooManyPlugins returns an error with the ErrTooManyPlugins ID.
func NewErrTooManyPlugins(ctx *context.T, actual int32, limit int32) error {
	return verror.New(ErrTooManyPlugins, ctx, actual, limit)
}

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

// DirectoryClientMethods is the client interface
// containing Directory methods.
//
// Directory is the interface for advertisement directory service.
type DirectoryClientMethods interface {
	// Lookup returns the advertisement of the given service instance.
	//
	// The returned advertisement may not include all attachments.
	Lookup(_ *context.T, id discovery.AdId, _ ...rpc.CallOpt) (AdInfo, error)
	// GetAttachment returns the named attachment. Accessing non-existent attachment
	// is not an error - nil data is returned if not found.
	//
	// TODO(jhahn): Consider to return an error if not found.
	GetAttachment(_ *context.T, id discovery.AdId, name string, _ ...rpc.CallOpt) ([]byte, error)
}

// DirectoryClientStub adds universal methods to DirectoryClientMethods.
type DirectoryClientStub interface {
	DirectoryClientMethods
	rpc.UniversalServiceMethods
}

// DirectoryClient returns a client stub for Directory.
func DirectoryClient(name string) DirectoryClientStub {
	return implDirectoryClientStub{name}
}

type implDirectoryClientStub struct {
	name string
}

func (c implDirectoryClientStub) Lookup(ctx *context.T, i0 discovery.AdId, opts ...rpc.CallOpt) (o0 AdInfo, err error) {
	err = v23.GetClient(ctx).Call(ctx, c.name, "Lookup", []interface{}{i0}, []interface{}{&o0}, opts...)
	return
}

func (c implDirectoryClientStub) GetAttachment(ctx *context.T, i0 discovery.AdId, i1 string, opts ...rpc.CallOpt) (o0 []byte, err error) {
	err = v23.GetClient(ctx).Call(ctx, c.name, "GetAttachment", []interface{}{i0, i1}, []interface{}{&o0}, opts...)
	return
}

// DirectoryServerMethods is the interface a server writer
// implements for Directory.
//
// Directory is the interface for advertisement directory service.
type DirectoryServerMethods interface {
	// Lookup returns the advertisement of the given service instance.
	//
	// The returned advertisement may not include all attachments.
	Lookup(_ *context.T, _ rpc.ServerCall, id discovery.AdId) (AdInfo, error)
	// GetAttachment returns the named attachment. Accessing non-existent attachment
	// is not an error - nil data is returned if not found.
	//
	// TODO(jhahn): Consider to return an error if not found.
	GetAttachment(_ *context.T, _ rpc.ServerCall, id discovery.AdId, name string) ([]byte, error)
}

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

// DirectoryServerStub adds universal methods to DirectoryServerStubMethods.
type DirectoryServerStub interface {
	DirectoryServerStubMethods
	// Describe the Directory interfaces.
	Describe__() []rpc.InterfaceDesc
}

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

func (s implDirectoryServerStub) Lookup(ctx *context.T, call rpc.ServerCall, i0 discovery.AdId) (AdInfo, error) {
	return s.impl.Lookup(ctx, call, i0)
}

func (s implDirectoryServerStub) GetAttachment(ctx *context.T, call rpc.ServerCall, i0 discovery.AdId, i1 string) ([]byte, error) {
	return s.impl.GetAttachment(ctx, call, i0, i1)
}

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

func (s implDirectoryServerStub) Describe__() []rpc.InterfaceDesc {
	return []rpc.InterfaceDesc{DirectoryDesc}
}

// DirectoryDesc describes the Directory interface.
var DirectoryDesc rpc.InterfaceDesc = descDirectory

// descDirectory hides the desc to keep godoc clean.
var descDirectory = rpc.InterfaceDesc{
	Name:    "Directory",
	PkgPath: "v.io/x/ref/lib/discovery",
	Doc:     "// Directory is the interface for advertisement directory service.",
	Methods: []rpc.MethodDesc{
		{
			Name: "Lookup",
			Doc:  "// Lookup returns the advertisement of the given service instance.\n//\n// The returned advertisement may not include all attachments.",
			InArgs: []rpc.ArgDesc{
				{"id", ``}, // discovery.AdId
			},
			OutArgs: []rpc.ArgDesc{
				{"", ``}, // AdInfo
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Read"))},
		},
		{
			Name: "GetAttachment",
			Doc:  "// GetAttachment returns the named attachment. Accessing non-existent attachment\n// is not an error - nil data is returned if not found.\n//\n// TODO(jhahn): Consider to return an error if not found.",
			InArgs: []rpc.ArgDesc{
				{"id", ``},   // discovery.AdId
				{"name", ``}, // string
			},
			OutArgs: []rpc.ArgDesc{
				{"", ``}, // []byte
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Read"))},
		},
	},
}

// Hold type definitions in package-level variables, for better performance.
var (
	__VDLType_list_1   *vdl.Type
	__VDLType_int32_2  *vdl.Type
	__VDLType_list_3   *vdl.Type
	__VDLType_byte_4   *vdl.Type
	__VDLType_array_5  *vdl.Type
	__VDLType_struct_6 *vdl.Type
	__VDLType_struct_7 *vdl.Type
	__VDLType_list_8   *vdl.Type
	__VDLType_list_9   *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((*Uuid)(nil))
	vdl.Register((*EncryptionAlgorithm)(nil))
	vdl.Register((*EncryptionKey)(nil))
	vdl.Register((*AdStatus)(nil))
	vdl.Register((*AdHash)(nil))
	vdl.Register((*AdInfo)(nil))

	// Initialize type definitions.
	__VDLType_list_1 = vdl.TypeOf((*Uuid)(nil))
	__VDLType_int32_2 = vdl.TypeOf((*EncryptionAlgorithm)(nil))
	__VDLType_list_3 = vdl.TypeOf((*EncryptionKey)(nil))
	__VDLType_byte_4 = vdl.TypeOf((*AdStatus)(nil))
	__VDLType_array_5 = vdl.TypeOf((*AdHash)(nil))
	__VDLType_struct_6 = vdl.TypeOf((*AdInfo)(nil)).Elem()
	__VDLType_struct_7 = vdl.TypeOf((*discovery.Advertisement)(nil)).Elem()
	__VDLType_list_8 = vdl.TypeOf((*[]EncryptionKey)(nil))
	__VDLType_list_9 = vdl.TypeOf((*[]string)(nil))

	// Set error format strings.
	i18n.Cat().SetWithBase(i18n.LangID("en"), i18n.MsgID(ErrAdvertisementNotFound.ID), "{1:}{2:} advertisement not found: {3}")
	i18n.Cat().SetWithBase(i18n.LangID("en"), i18n.MsgID(ErrAlreadyBeingAdvertised.ID), "{1:}{2:} already being advertised: {3}")
	i18n.Cat().SetWithBase(i18n.LangID("en"), i18n.MsgID(ErrBadAdvertisement.ID), "{1:}{2:} invalid advertisement: {3}")
	i18n.Cat().SetWithBase(i18n.LangID("en"), i18n.MsgID(ErrBadQuery.ID), "{1:}{2:} invalid query: {3}")
	i18n.Cat().SetWithBase(i18n.LangID("en"), i18n.MsgID(ErrDiscoveryClosed.ID), "{1:}{2:} discovery closed")
	i18n.Cat().SetWithBase(i18n.LangID("en"), i18n.MsgID(ErrNoDiscoveryPlugin.ID), "{1:}{2:} no discovery plugin")
	i18n.Cat().SetWithBase(i18n.LangID("en"), i18n.MsgID(ErrTooManyPlugins.ID), "{1:}{2:} too many plugins ({3}), support at most {4}")

	return struct{}{}
}
