// 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.

package vom

import (
	"v.io/v23/vdl"
	"v.io/v23/verror"
)

// TODO(toddw): Merge this file with xdecoder.go

var (
	errDecodeZeroTypeID         = verror.Register(pkgPath+".errDecodeZeroTypeID", verror.NoRetry, "{1:}{2:} vom: zero type id{:_}")
	errIndexOutOfRange          = verror.Register(pkgPath+".errIndexOutOfRange", verror.NoRetry, "{1:}{2:} vom: index out of range{:_}")
	errLeftOverBytes            = verror.Register(pkgPath+".errLeftOverBytes", verror.NoRetry, "{1:}{2:} vom: {3} leftover bytes{:_}")
	errUnexpectedControlByte    = verror.Register(pkgPath+".errUnexpectedControlByte", verror.NoRetry, "{1:}{2:} vom: unexpected control byte {3}{:_}")
	errDecodeValueUnhandledType = verror.Register(pkgPath+".errDecodeValueUnhandledType", verror.NoRetry, "{1:}{2:} vom: decodeValue unhandled type {3}{:_}")
	errIgnoreValueUnhandledType = verror.Register(pkgPath+".errIgnoreValueUnhandledType", verror.NoRetry, "{1:}{2:} vom: ignoreValue unhandled type {3}{:_}")
	errInvalidTypeIdIndex       = verror.Register(pkgPath+".errInvalidTypeIdIndex", verror.NoRetry, "{1:}{2:} vom: value referenced invalid index into type id table {:_}")
	errInvalidAnyIndex          = verror.Register(pkgPath+".errInvalidAnyIndex", verror.NoRetry, "{1:}{2:} vom: value referenced invalid index into anyLen table {:_}")
)

func (d *decoder81) decodeTypeDefs() error {
	for {
		typeNext, err := d.typeIsNext()
		if err != nil {
			return err
		}
		if !typeNext {
			return nil
		}
		if err := d.typeDec.readSingleType(); err != nil {
			return err
		}
	}
}

// peekValueByteLen returns the byte length of the next value.
func (d *decoder81) peekValueByteLen(tt *vdl.Type) (int, error) {
	if hasChunkLen(tt) {
		// Use the explicit message length.
		return d.buf.lim, nil
	}
	// No explicit message length, but the length can be computed.
	switch {
	case tt.Kind() == vdl.Byte:
		if d.buf.version == Version80 {
			return 1, nil
		} else {
			return binaryPeekUintByteLen(d.buf)
		}
	case tt.Kind() == vdl.Array && tt.IsBytes():
		// Byte arrays are exactly their length and encoded with 1-byte header.
		return tt.Len() + 1, nil
	case tt.Kind() == vdl.String || tt.IsBytes():
		// Strings and byte lists are encoded with a length header.
		strlen, bytelen, err := binaryPeekUint(d.buf)
		switch {
		case err != nil:
			return 0, err
		case strlen > maxBinaryMsgLen:
			return 0, verror.New(errMsgLen, nil)
		}
		return int(strlen) + bytelen, nil
	default:
		// Must be a primitive, which is encoded as an underlying uint.
		return binaryPeekUintByteLen(d.buf)
	}
}

func (d *decoder81) decodeRaw(tt *vdl.Type, valLen int, raw *RawBytes) error {
	raw.Version = d.buf.version
	raw.Type = tt
	raw.Data = make([]byte, valLen)
	if err := d.buf.ReadIntoBuf(raw.Data); err != nil {
		return err
	}
	refTypeLen := len(d.refTypes.tids)
	if cap(raw.RefTypes) >= refTypeLen {
		raw.RefTypes = raw.RefTypes[:refTypeLen]
	} else {
		raw.RefTypes = make([]*vdl.Type, refTypeLen)
	}
	for i, tid := range d.refTypes.tids {
		var err error
		if raw.RefTypes[i], err = d.typeDec.lookupType(tid); err != nil {
			return err
		}
	}
	raw.AnyLengths = d.refAnyLens.lens
	return nil
}

func (d *decoder81) readAnyHeader() (*vdl.Type, int, error) {
	// Read either WireCtrlNil or the index of the referenced type id.
	typeIndex, ctrl, err := binaryDecodeUintWithControl(d.buf)
	switch {
	case err != nil:
		return nil, 0, err
	case ctrl == WireCtrlNil:
		return nil, 0, nil // nil any
	case ctrl != 0:
		return nil, 0, verror.New(errUnexpectedControlByte, nil, ctrl)
	}
	var tid TypeId
	if d.buf.version == Version80 {
		tid = TypeId(typeIndex)
	} else if tid, err = d.refTypes.ReferencedTypeId(typeIndex); err != nil {
		return nil, 0, err
	}
	// Look up the referenced type id.
	ttElem, err := d.typeDec.lookupType(tid)
	if err != nil {
		return nil, 0, err
	}
	var anyLen int
	if d.buf.version != Version80 {
		// Read and lookup the index of the any byte length.  Reference the any len,
		// even if it isn't used, to report missing references.
		lenIndex, err := binaryDecodeUint(d.buf)
		if err != nil {
			return nil, 0, err
		}
		if anyLen, err = d.refAnyLens.ReferencedAnyLen(lenIndex); err != nil {
			return nil, 0, err
		}
	}
	return ttElem, anyLen, nil
}

func (d *decoder81) skipValue(tt *vdl.Type) error {
	if tt.IsBytes() {
		len, err := binaryDecodeLenOrArrayLen(d.buf, tt)
		if err != nil {
			return err
		}
		return d.buf.Skip(len)
	}
	switch kind := tt.Kind(); kind {
	case vdl.Bool:
		return d.buf.Skip(1)
	case vdl.Byte, vdl.Uint16, vdl.Uint32, vdl.Uint64, vdl.Int8, vdl.Int16, vdl.Int32, vdl.Int64, vdl.Float32, vdl.Float64, vdl.Enum, vdl.TypeObject:
		// The underlying encoding of all these types is based on uint.
		return binaryIgnoreUint(d.buf)
	case vdl.String:
		return binaryIgnoreString(d.buf)
	case vdl.Array, vdl.List, vdl.Set, vdl.Map:
		len, err := binaryDecodeLenOrArrayLen(d.buf, tt)
		if err != nil {
			return err
		}
		for ix := 0; ix < len; ix++ {
			if kind == vdl.Set || kind == vdl.Map {
				if err := d.skipValue(tt.Key()); err != nil {
					return err
				}
			}
			if kind == vdl.Array || kind == vdl.List || kind == vdl.Map {
				if err := d.skipValue(tt.Elem()); err != nil {
					return err
				}
			}
		}
		return nil
	case vdl.Struct:
		// Loop through decoding the 0-based field index and corresponding field.
		for {
			switch index, ctrl, err := binaryDecodeUintWithControl(d.buf); {
			case err != nil:
				return err
			case ctrl == WireCtrlEnd:
				return nil
			case ctrl != 0:
				return verror.New(errUnexpectedControlByte, nil, ctrl)
			case index >= uint64(tt.NumField()):
				return verror.New(errIndexOutOfRange, nil)
			default:
				ttfield := tt.Field(int(index))
				if err := d.skipValue(ttfield.Type); err != nil {
					return err
				}
			}
		}
	case vdl.Union:
		switch index, err := binaryDecodeUint(d.buf); {
		case err != nil:
			return err
		case index >= uint64(tt.NumField()):
			return verror.New(errIndexOutOfRange, nil)
		default:
			ttfield := tt.Field(int(index))
			return d.skipValue(ttfield.Type)
		}
	case vdl.Optional:
		// Read the WireCtrlNil code, but if it's not WireCtrlNil we need to keep
		// the buffer as-is, since it's the first byte of the value, which may
		// itself be another control code.
		switch ctrl, err := binaryPeekControl(d.buf); {
		case err != nil:
			return err
		case ctrl == WireCtrlNil:
			d.buf.Skip(1) // nil optional
			return nil
		default:
			return d.skipValue(tt.Elem()) // non-nil optional
		}
	case vdl.Any:
		switch index, ctrl, err := binaryDecodeUintWithControl(d.buf); {
		case err != nil:
			return err
		case ctrl == WireCtrlNil:
			return nil
		case ctrl != 0:
			return verror.New(errUnexpectedControlByte, nil, ctrl)
		default:
			tid, err := d.refTypes.ReferencedTypeId(index)
			if err != nil {
				return err
			}
			ttElem, err := d.typeDec.lookupType(tid)
			if err != nil {
				return err
			}
			return d.skipValue(ttElem)
		}
	default:
		return verror.New(errIgnoreValueUnhandledType, nil, tt)
	}
}

func (d *decoder81) nextMessage() (TypeId, error) {
	if leftover := d.buf.RemoveLimit(); leftover > 0 {
		return 0, verror.New(errLeftOverBytes, nil, leftover)
	}

	if d.buf.version == 0 {
		version, err := d.buf.ReadByte()
		if err != nil {
			return 0, verror.New(errEndedBeforeVersionByte, nil, err)
		}
		d.buf.version = Version(version)
		if !isAllowedVersion(d.buf.version) {
			return 0, verror.New(errBadVersionByte, nil, d.buf.version)
		}
	}

	mid, cr, err := binaryDecodeIntWithControl(d.buf)
	if err != nil {
		return 0, err
	}

	if cr == WireCtrlTypeIncomplete {
		mid, cr, err = binaryDecodeIntWithControl(d.buf)
		if err != nil {
			return 0, err
		}

		if cr != 0 || mid >= 0 {
			// only can have incomplete types on new type messages
			return 0, verror.New(errInvalid, nil)
		}

		d.flag = d.flag.Set(decFlagTypeIncomplete)
	} else if mid < 0 {
		d.flag = d.flag.Clear(decFlagTypeIncomplete)
	}

	if cr != 0 {
		return 0, verror.New(errBadControlCode, nil)
	}

	var tid TypeId
	var hasAny, hasTypeObject bool
	var hasLength bool
	switch {
	case mid < 0:
		tid = TypeId(-mid)
		hasLength = true
		hasAny = false
		hasTypeObject = false
	case mid > 0:
		tid = TypeId(mid)
		t, err := d.typeDec.lookupType(tid)
		if err != nil {
			return 0, err
		}
		hasLength = hasChunkLen(t)
		hasAny = containsAny(t)
		hasTypeObject = containsTypeObject(t)
	default:
		return 0, verror.New(errDecodeZeroTypeID, nil)
	}

	if (hasAny || hasTypeObject) && d.buf.version != Version80 {
		l, err := binaryDecodeUint(d.buf)
		if err != nil {
			return 0, err
		}
		for i := 0; i < int(l); i++ {
			refId, err := binaryDecodeUint(d.buf)
			if err != nil {
				return 0, err
			}
			d.refTypes.AddTypeID(TypeId(refId))
		}
	}
	if hasAny && d.buf.version != Version80 {
		l, err := binaryDecodeUint(d.buf)
		if err != nil {
			return 0, err
		}
		for i := 0; i < int(l); i++ {
			refAnyLen, err := binaryDecodeLen(d.buf)
			if err != nil {
				return 0, err
			}
			d.refAnyLens.AddAnyLen(refAnyLen)
		}
	}

	if hasLength {
		chunkLen, err := binaryDecodeUint(d.buf)
		if err != nil {
			return 0, err
		}
		d.buf.SetLimit(int(chunkLen))
	}

	return tid, nil
}

func (d *decoder81) typeIsNext() (bool, error) {
	if d.buf.version == 0 {
		version, err := d.buf.ReadByte()
		if err != nil {
			return false, verror.New(errEndedBeforeVersionByte, nil, err)
		}
		d.buf.version = Version(version)
		if !isAllowedVersion(d.buf.version) {
			return false, verror.New(errBadVersionByte, nil, d.buf.version)
		}
	}
	mid, cr, _, err := binaryPeekIntWithControl(d.buf)
	if err != nil {
		return false, err
	}
	return mid < 0 || cr == WireCtrlTypeIncomplete, nil
}

func (d *decoder81) endMessage() error {
	if leftover := d.buf.RemoveLimit(); leftover > 0 {
		return verror.New(errLeftOverBytes, nil, leftover)
	}
	if err := d.refTypes.Reset(); err != nil {
		return err
	}
	if err := d.refAnyLens.Reset(); err != nil {
		return err
	}
	return nil
}

type referencedTypes struct {
	tids   []TypeId
	marker int
}

func (refTypes *referencedTypes) Reset() (err error) {
	refTypes.tids = refTypes.tids[:0]
	refTypes.marker = 0
	return
}

func (refTypes *referencedTypes) AddTypeID(tid TypeId) {
	refTypes.tids = append(refTypes.tids, tid)
}

func (refTypes *referencedTypes) ReferencedTypeId(index uint64) (TypeId, error) {
	if index >= uint64(len(refTypes.tids)) {
		return 0, verror.New(errInvalidTypeIdIndex, nil)
	}
	return refTypes.tids[index], nil
}

func (refTypes *referencedTypes) Mark() {
	refTypes.marker = len(refTypes.tids)
}

type referencedAnyLens struct {
	lens   []int
	marker int
}

func (refAnys *referencedAnyLens) Reset() (err error) {
	refAnys.lens = refAnys.lens[:0]
	return
}

func (refAnys *referencedAnyLens) AddAnyLen(len int) {
	refAnys.lens = append(refAnys.lens, len)
}

func (refAnys *referencedAnyLens) ReferencedAnyLen(index uint64) (int, error) {
	if index >= uint64(len(refAnys.lens)) {
		return 0, verror.New(errInvalidAnyIndex, nil)
	}
	return refAnys.lens[index], nil
}

func (refAnys *referencedAnyLens) Mark() {
	refAnys.marker = len(refAnys.lens)
}
