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

package bcrypter

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

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

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

// WireCiphertext represents the wire format of the ciphertext
// generated by a Crypter.
type WireCiphertext struct {
	// PatternId is an identifier of the blessing pattern that this
	// ciphertext is for. It is represented by a 16 byte truncated
	// SHA256 hash of the pattern.
	PatternId string
	// Bytes is a map from an identifier of the public IBE params to
	// the ciphertext bytes that were generated using those params.
	//
	// The params identifier is a 16 byte truncated SHA256 hash
	// of the marshaled form of the IBE params.
	Bytes map[string][]byte
}

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

func (x WireCiphertext) VDLIsZero() bool {
	if x.PatternId != "" {
		return false
	}
	if len(x.Bytes) != 0 {
		return false
	}
	return true
}

func (x WireCiphertext) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(__VDLType_struct_1); err != nil {
		return err
	}
	if x.PatternId != "" {
		if err := enc.NextFieldValueString("PatternId", vdl.StringType, x.PatternId); err != nil {
			return err
		}
	}
	if len(x.Bytes) != 0 {
		if err := enc.NextField("Bytes"); err != nil {
			return err
		}
		if err := __VDLWriteAnon_map_1(enc, x.Bytes); err != nil {
			return err
		}
	}
	if err := enc.NextField(""); err != nil {
		return err
	}
	return enc.FinishValue()
}

func __VDLWriteAnon_map_1(enc vdl.Encoder, x map[string][]byte) error {
	if err := enc.StartValue(__VDLType_map_2); err != nil {
		return err
	}
	if err := enc.SetLenHint(len(x)); err != nil {
		return err
	}
	for key, elem := range x {
		if err := enc.NextEntryValueString(vdl.StringType, key); err != nil {
			return err
		}
		if err := enc.WriteValueBytes(__VDLType_list_3, elem); err != nil {
			return err
		}
	}
	if err := enc.NextEntry(true); err != nil {
		return err
	}
	return enc.FinishValue()
}

func (x *WireCiphertext) VDLRead(dec vdl.Decoder) error {
	*x = WireCiphertext{}
	if err := dec.StartValue(__VDLType_struct_1); err != nil {
		return err
	}
	for {
		f, err := dec.NextField()
		if err != nil {
			return err
		}
		switch f {
		case "":
			return dec.FinishValue()
		case "PatternId":
			switch value, err := dec.ReadValueString(); {
			case err != nil:
				return err
			default:
				x.PatternId = value
			}
		case "Bytes":
			if err := __VDLReadAnon_map_1(dec, &x.Bytes); err != nil {
				return err
			}
		default:
			if err := dec.SkipValue(); err != nil {
				return err
			}
		}
	}
}

func __VDLReadAnon_map_1(dec vdl.Decoder, x *map[string][]byte) error {
	if err := dec.StartValue(__VDLType_map_2); err != nil {
		return err
	}
	var tmpMap map[string][]byte
	if len := dec.LenHint(); len > 0 {
		tmpMap = make(map[string][]byte, len)
	}
	for {
		switch done, key, err := dec.NextEntryValueString(); {
		case err != nil:
			return err
		case done:
			*x = tmpMap
			return dec.FinishValue()
		default:
			var elem []byte
			if err := dec.ReadValueBytes(-1, &elem); err != nil {
				return err
			}
			if tmpMap == nil {
				tmpMap = make(map[string][]byte)
			}
			tmpMap[key] = elem
		}
	}
}

// WireParams represents the wire format of the public parameters
// of an identity provider (aka Root).
type WireParams struct {
	// Blessing is the blessing name of the identity provider. The identity
	// provider  can extract private keys for blessings that are extensions
	// of this blessing name.
	Blessing string
	// Params is the marshaled form of the public IBE params of the
	// the identity provider.
	Params []byte
}

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

func (x WireParams) VDLIsZero() bool {
	if x.Blessing != "" {
		return false
	}
	if len(x.Params) != 0 {
		return false
	}
	return true
}

func (x WireParams) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(__VDLType_struct_4); err != nil {
		return err
	}
	if x.Blessing != "" {
		if err := enc.NextFieldValueString("Blessing", vdl.StringType, x.Blessing); err != nil {
			return err
		}
	}
	if len(x.Params) != 0 {
		if err := enc.NextFieldValueBytes("Params", __VDLType_list_3, x.Params); err != nil {
			return err
		}
	}
	if err := enc.NextField(""); err != nil {
		return err
	}
	return enc.FinishValue()
}

func (x *WireParams) VDLRead(dec vdl.Decoder) error {
	*x = WireParams{}
	if err := dec.StartValue(__VDLType_struct_4); err != nil {
		return err
	}
	for {
		f, err := dec.NextField()
		if err != nil {
			return err
		}
		switch f {
		case "":
			return dec.FinishValue()
		case "Blessing":
			switch value, err := dec.ReadValueString(); {
			case err != nil:
				return err
			default:
				x.Blessing = value
			}
		case "Params":
			if err := dec.ReadValueBytes(-1, &x.Params); err != nil {
				return err
			}
		default:
			if err := dec.SkipValue(); err != nil {
				return err
			}
		}
	}
}

// WirePrivateKey represents the wire format of the private key corresponding
// to a blessing.
type WirePrivateKey struct {
	// Blessing is the blessing for which this private key was extracted for.
	Blessing string
	// Params are the public parameters of the identity provider that extracted
	// this private key.
	Params WireParams
	// Keys contain the extracted IBE private keys for each pattern that is
	// matched by the blessing and is an extension of the identity provider's
	// name. The keys are enumerated in increasing order of the lengths of the
	// corresponding patterns.
	//
	// For example, if the blessing is "google:u:alice:phone" and the identity
	// provider's name is "google:u" then the keys are extracted for the patterns
	// - "google:u"
	// - "google:u:alice"
	// - "google:u:alice:phone"
	// - "google:u:alice:phone:$"
	//
	// The private keys are listed in increasing order of the lengths of the
	// corresponding patterns.
	Keys [][]byte
}

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

func (x WirePrivateKey) VDLIsZero() bool {
	if x.Blessing != "" {
		return false
	}
	if !x.Params.VDLIsZero() {
		return false
	}
	if len(x.Keys) != 0 {
		return false
	}
	return true
}

func (x WirePrivateKey) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(__VDLType_struct_5); err != nil {
		return err
	}
	if x.Blessing != "" {
		if err := enc.NextFieldValueString("Blessing", vdl.StringType, x.Blessing); err != nil {
			return err
		}
	}
	if !x.Params.VDLIsZero() {
		if err := enc.NextField("Params"); err != nil {
			return err
		}
		if err := x.Params.VDLWrite(enc); err != nil {
			return err
		}
	}
	if len(x.Keys) != 0 {
		if err := enc.NextField("Keys"); err != nil {
			return err
		}
		if err := __VDLWriteAnon_list_2(enc, x.Keys); err != nil {
			return err
		}
	}
	if err := enc.NextField(""); err != nil {
		return err
	}
	return enc.FinishValue()
}

func __VDLWriteAnon_list_2(enc vdl.Encoder, x [][]byte) error {
	if err := enc.StartValue(__VDLType_list_6); 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, elem); err != nil {
			return err
		}
	}
	if err := enc.NextEntry(true); err != nil {
		return err
	}
	return enc.FinishValue()
}

func (x *WirePrivateKey) VDLRead(dec vdl.Decoder) error {
	*x = WirePrivateKey{}
	if err := dec.StartValue(__VDLType_struct_5); err != nil {
		return err
	}
	for {
		f, err := dec.NextField()
		if err != nil {
			return err
		}
		switch f {
		case "":
			return dec.FinishValue()
		case "Blessing":
			switch value, err := dec.ReadValueString(); {
			case err != nil:
				return err
			default:
				x.Blessing = value
			}
		case "Params":
			if err := x.Params.VDLRead(dec); err != nil {
				return err
			}
		case "Keys":
			if err := __VDLReadAnon_list_2(dec, &x.Keys); err != nil {
				return err
			}
		default:
			if err := dec.SkipValue(); err != nil {
				return err
			}
		}
	}
}

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

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

var (
	ErrInternal           = verror.Register("v.io/x/ref/lib/security/bcrypter.Internal", verror.NoRetry, "{1:}{2:} internal error: {3}")
	ErrNoParams           = verror.Register("v.io/x/ref/lib/security/bcrypter.NoParams", verror.NoRetry, "{1:}{2:} no public parameters available for encrypting for pattern: {3}")
	ErrPrivateKeyNotFound = verror.Register("v.io/x/ref/lib/security/bcrypter.PrivateKeyNotFound", verror.NoRetry, "{1:}{2:} no private key found for decrypting ciphertext")
	ErrInvalidPrivateKey  = verror.Register("v.io/x/ref/lib/security/bcrypter.InvalidPrivateKey", verror.NoRetry, "{1:}{2:} private key is invalid: {3}")
)

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

// NewErrNoParams returns an error with the ErrNoParams ID.
func NewErrNoParams(ctx *context.T, pattern security.BlessingPattern) error {
	return verror.New(ErrNoParams, ctx, pattern)
}

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

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

// Hold type definitions in package-level variables, for better performance.
var (
	__VDLType_struct_1 *vdl.Type
	__VDLType_map_2    *vdl.Type
	__VDLType_list_3   *vdl.Type
	__VDLType_struct_4 *vdl.Type
	__VDLType_struct_5 *vdl.Type
	__VDLType_list_6   *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((*WireCiphertext)(nil))
	vdl.Register((*WireParams)(nil))
	vdl.Register((*WirePrivateKey)(nil))

	// Initialize type definitions.
	__VDLType_struct_1 = vdl.TypeOf((*WireCiphertext)(nil)).Elem()
	__VDLType_map_2 = vdl.TypeOf((*map[string][]byte)(nil))
	__VDLType_list_3 = vdl.TypeOf((*[]byte)(nil))
	__VDLType_struct_4 = vdl.TypeOf((*WireParams)(nil)).Elem()
	__VDLType_struct_5 = vdl.TypeOf((*WirePrivateKey)(nil)).Elem()
	__VDLType_list_6 = vdl.TypeOf((*[][]byte)(nil))

	// Set error format strings.
	i18n.Cat().SetWithBase(i18n.LangID("en"), i18n.MsgID(ErrInternal.ID), "{1:}{2:} internal error: {3}")
	i18n.Cat().SetWithBase(i18n.LangID("en"), i18n.MsgID(ErrNoParams.ID), "{1:}{2:} no public parameters available for encrypting for pattern: {3}")
	i18n.Cat().SetWithBase(i18n.LangID("en"), i18n.MsgID(ErrPrivateKeyNotFound.ID), "{1:}{2:} no private key found for decrypting ciphertext")
	i18n.Cat().SetWithBase(i18n.LangID("en"), i18n.MsgID(ErrInvalidPrivateKey.ID), "{1:}{2:} private key is invalid: {3}")

	return struct{}{}
}
