// Copyright 2016 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 (
	"strconv"

	"v.io/v23/vdl"
)

// This file contains the ReadValue* methods.  The semantics of these methods is
// the same as if StartValue, Decode*, FinishValue were called in sequence.  The
// implementation is faster than actually calling that sequence, because we can
// avoid pushing and popping the decoder stack and also avoid unnecessary
// compatibility checks.  We also get a minor improvement by avoiding extra
// method calls indirected through the Decoder interface.
//
// Each method has the same pattern:
//
// StartValue:
//   If IgnoreNextStarValue is set, the type is already on the stack.  Otherwise
//   setup the type to process Any and Optional headers.  We pass nil to
//   d.setupType to avoid the compatibility check, since the decode step will
//   naturally let us perform that check.
// Decode:
//   We implement common-case fastpaths; e.g. avoiding unnecessary conversions.
// FinishValue:
//   Mirrors StartValue, only pop the stack if necessary.

func (d *decoder81) ReadValueBool() (value bool, err error) {
	// StartValue
	isOnStack := d.flag.IgnoreNextStartValue()
	var tt *vdl.Type
	if isOnStack {
		tt = d.stack[len(d.stack)-1].Type
	} else {
		if tt, err = d.dfsNextType(); err != nil {
			return false, err
		}
		if tt, _, _, err = d.setupType(tt, nil); err != nil {
			return false, err
		}
	}
	// Decode
	switch tt.Kind() {
	case vdl.Bool:
		value, err = binaryDecodeBool(d.buf)
	default:
		return false, errIncompatibleDecode(tt, "bool")
	}
	// FinishValue
	if isOnStack {
		if err := d.FinishValue(); err != nil {
			return false, err
		}
	} else {
		d.flag = d.flag.Clear(decFlagFinishValue)
		if len(d.stack) == 0 {
			if err := d.endMessage(); err != nil {
				return false, err
			}
		}
	}
	return value, err
}

func (d *decoder81) ReadValueString() (value string, err error) {
	// StartValue
	isOnStack := d.flag.IgnoreNextStartValue()
	var tt *vdl.Type
	if isOnStack {
		tt = d.stack[len(d.stack)-1].Type
	} else {
		if tt, err = d.dfsNextType(); err != nil {
			return "", err
		}
		if tt, _, _, err = d.setupType(tt, nil); err != nil {
			return "", err
		}
	}
	// Decode
	switch tt.Kind() {
	case vdl.String:
		value, err = binaryDecodeString(d.buf)
	case vdl.Enum:
		value, err = d.binaryDecodeEnum(tt)
	default:
		return "", errIncompatibleDecode(tt, "string")
	}
	// FinishValue
	if isOnStack {
		if err := d.FinishValue(); err != nil {
			return "", err
		}
	} else {
		d.flag = d.flag.Clear(decFlagFinishValue)
		if len(d.stack) == 0 {
			if err := d.endMessage(); err != nil {
				return "", err
			}
		}
	}
	return value, err
}

func (d *decoder81) ReadValueUint(bitlen int) (value uint64, err error) {
	// StartValue
	isOnStack := d.flag.IgnoreNextStartValue()
	var tt *vdl.Type
	if isOnStack {
		tt = d.stack[len(d.stack)-1].Type
	} else {
		if tt, err = d.dfsNextType(); err != nil {
			return 0, err
		}
		if tt, _, _, err = d.setupType(tt, nil); err != nil {
			return 0, err
		}
	}
	// Decode, avoiding unnecessary number conversions.
	switch kind := tt.Kind(); kind {
	case vdl.Uint16, vdl.Uint32, vdl.Uint64:
		if kind.BitLen() <= bitlen {
			value, err = binaryDecodeUint(d.buf)
		} else {
			value, err = d.decodeUint(tt, uint(bitlen))
		}
	case vdl.Int8, vdl.Int16, vdl.Int32, vdl.Int64, vdl.Float32, vdl.Float64:
		value, err = d.decodeUint(tt, uint(bitlen))
	case vdl.Byte:
		var b byte
		b, err = d.binaryDecodeByte()
		value = uint64(b)
	default:
		return 0, errIncompatibleDecode(tt, "uint"+strconv.Itoa(bitlen))
	}
	// FinishValue
	if isOnStack {
		if err := d.FinishValue(); err != nil {
			return 0, err
		}
	} else {
		d.flag = d.flag.Clear(decFlagFinishValue)
		if len(d.stack) == 0 {
			if err := d.endMessage(); err != nil {
				return 0, err
			}
		}
	}
	return value, err
}

func (d *decoder81) ReadValueInt(bitlen int) (value int64, err error) {
	// StartValue
	isOnStack := d.flag.IgnoreNextStartValue()
	var tt *vdl.Type
	if isOnStack {
		tt = d.stack[len(d.stack)-1].Type
	} else {
		if tt, err = d.dfsNextType(); err != nil {
			return 0, err
		}
		if tt, _, _, err = d.setupType(tt, nil); err != nil {
			return 0, err
		}
	}
	// Decode, avoiding unnecessary number conversions.
	switch kind := tt.Kind(); kind {
	case vdl.Int8, vdl.Int16, vdl.Int32, vdl.Int64:
		if kind.BitLen() <= bitlen {
			value, err = binaryDecodeInt(d.buf)
		} else {
			value, err = d.decodeInt(tt, uint(bitlen))
		}
	case vdl.Byte, vdl.Uint16, vdl.Uint32, vdl.Uint64, vdl.Float32, vdl.Float64:
		value, err = d.decodeInt(tt, uint(bitlen))
	default:
		return 0, errIncompatibleDecode(tt, "int"+strconv.Itoa(bitlen))
	}
	// FinishValue
	if isOnStack {
		if err := d.FinishValue(); err != nil {
			return 0, err
		}
	} else {
		d.flag = d.flag.Clear(decFlagFinishValue)
		if len(d.stack) == 0 {
			if err := d.endMessage(); err != nil {
				return 0, err
			}
		}
	}
	return value, err
}

func (d *decoder81) ReadValueFloat(bitlen int) (value float64, err error) {
	// StartValue
	isOnStack := d.flag.IgnoreNextStartValue()
	var tt *vdl.Type
	if isOnStack {
		tt = d.stack[len(d.stack)-1].Type
	} else {
		if tt, err = d.dfsNextType(); err != nil {
			return 0, err
		}
		if tt, _, _, err = d.setupType(tt, nil); err != nil {
			return 0, err
		}
	}
	// Decode, avoiding unnecessary number conversions.
	switch kind := tt.Kind(); kind {
	case vdl.Byte, vdl.Uint16, vdl.Uint32, vdl.Uint64, vdl.Int8, vdl.Int16, vdl.Int32, vdl.Int64, vdl.Float32, vdl.Float64:
		value, err = d.decodeFloat(tt, uint(bitlen))
	default:
		return 0, errIncompatibleDecode(tt, "float"+strconv.Itoa(bitlen))
	}
	// FinishValue
	if isOnStack {
		if err := d.FinishValue(); err != nil {
			return 0, err
		}
	} else {
		d.flag = d.flag.Clear(decFlagFinishValue)
		if len(d.stack) == 0 {
			if err := d.endMessage(); err != nil {
				return 0, err
			}
		}
	}
	return value, err
}

func (d *decoder81) ReadValueTypeObject() (value *vdl.Type, err error) {
	// StartValue
	isOnStack := d.flag.IgnoreNextStartValue()
	var tt *vdl.Type
	if isOnStack {
		tt = d.stack[len(d.stack)-1].Type
	} else {
		if tt, err = d.dfsNextType(); err != nil {
			return nil, err
		}
		if tt, _, _, err = d.setupType(tt, nil); err != nil {
			return nil, err
		}
	}
	// Decode
	switch tt.Kind() {
	case vdl.TypeObject:
		value, err = d.binaryDecodeType()
	default:
		return nil, errIncompatibleDecode(tt, "typeobject")
	}
	// FinishValue
	if isOnStack {
		if err := d.FinishValue(); err != nil {
			return nil, err
		}
	} else {
		d.flag = d.flag.Clear(decFlagFinishValue)
		if len(d.stack) == 0 {
			if err := d.endMessage(); err != nil {
				return nil, err
			}
		}
	}
	return value, err
}

// ReadValueBytes is more complicated than the other ReadValue* methods, since
// []byte lists and [n]byte arrays aren't scalar, and may need more complicated
// conversions
func (d *decoder81) ReadValueBytes(fixedLen int, x *[]byte) (err error) {
	// StartValue.  Initialize tt and lenHint, and track whether the []byte type
	// is already on the stack via isOnStack.
	isOnStack := d.flag.IgnoreNextStartValue()
	d.flag = d.flag.Clear(decFlagIgnoreNextStartValue)
	var tt *vdl.Type
	var lenHint int
	if isOnStack {
		top := d.top()
		tt, lenHint = top.Type, top.LenHint
	} else {
		if tt, err = d.dfsNextType(); err != nil {
			return err
		}
		var flag decStackFlag
		if tt, lenHint, flag, err = d.setupType(tt, nil); err != nil {
			return err
		}
		// If tt isn't []byte or [n]byte (or a named variant of these), we need to
		// perform conversion byte-by-byte.  This is complicated, and can't be
		// really fast, so we just push an entry onto the stack and handle this via
		// DecodeConvertedBytes below.
		//
		// We also need to perform the compatibility check, to make sure tt is
		// compatible with []byte.  The check is fairly expensive, so skipping it
		// when tt is actually a bytes type makes the the common case faster.
		if !tt.IsBytes() {
			if !vdl.Compatible(tt, ttByteList) {
				return errIncompatibleDecode(tt, "bytes")
			}
			d.stack = append(d.stack, decStackEntry{
				Type:    tt,
				Index:   -1,
				LenHint: lenHint,
				Flag:    flag,
			})
			isOnStack = true
		}
	}
	// Decode.  The common-case fastpath reads directly from the buffer.
	if tt.IsBytes() {
		if err := d.decodeBytes(tt, lenHint, fixedLen, x); err != nil {
			return err
		}
	} else {
		if err := vdl.DecodeConvertedBytes(d, fixedLen, x); err != nil {
			return err
		}
	}
	// FinishValue
	if isOnStack {
		if err := d.FinishValue(); err != nil {
			return err
		}
	} else {
		d.flag = d.flag.Clear(decFlagIsParentBytes)
		if len(d.stack) == 0 {
			if err := d.endMessage(); err != nil {
				return err
			}
		}
	}
	return nil
}

var ttByteList = vdl.ListType(vdl.ByteType)
