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

import (
	"errors"
	"fmt"
	"math"
)

var (
	errEmptyDecoderStack = errors.New("vdl: empty decoder stack")
)

// Decoder returns a decoder that traverses vv.
func (vv *Value) Decoder() Decoder {
	return &valueDecoder{initial: vv}
}

// ValueDecoder is an implementation of Decoder for vdl Value.
type valueDecoder struct {
	initial    *Value
	ignoreNext bool
	stack      []vdStackEntry
}

type vdStackEntry struct {
	Value      *Value   // the vdl Value
	Index      int      // next index or field (index into Keys for map/set)
	NumStarted int      // hold state for multiple StartValue() calls
	IsAny      bool     // true iff this value is within an any value
	IsOptional bool     // true iff this value is within an optional value
	Keys       []*Value // keys for set/map
}

func (d *valueDecoder) StartValue(want *Type) error {
	if d.ignoreNext {
		d.ignoreNext = false
		return nil
	}
	var vv *Value
	if top := d.top(); top == nil {
		vv = d.initial
	} else {
		switch top.Value.Kind() {
		case Array, List:
			vv = top.Value.Index(top.Index)
		case Set:
			vv = top.Keys[top.Index]
		case Map:
			switch top.NumStarted % 2 {
			case 0:
				vv = top.Keys[top.Index]
			case 1:
				vv = top.Value.MapIndex(top.Keys[top.Index])
			}
		case Struct:
			vv = top.Value.StructField(top.Index)
		case Union:
			_, vv = top.Value.UnionField()
		default:
			return fmt.Errorf("vdl: can't StartValue on %v", top.Value.Type())
		}
		top.NumStarted++
	}
	var isAny, isOptional bool
	if vv.Kind() == Any {
		isAny = true
		if !vv.IsNil() {
			vv = vv.Elem()
		}
	}
	if vv.Kind() == Optional {
		isOptional = true
		if !vv.IsNil() {
			vv = vv.Elem()
		}
	}
	// Check compatibility between the actual type and the want type.  Since
	// compatibility applies to the entire static type, we only need to perform
	// this check for top-level decoded values, and subsequently for decoded any
	// values.  We skip checking non-composite want types, since those will be
	// naturally caught by the Decode* calls anyways.
	if len(d.stack) == 0 || isAny {
		switch want.Kind() {
		case Optional, Array, List, Set, Map, Struct, Union:
			if !Compatible2(vv.Type(), want) {
				return fmt.Errorf("vdl: incompatible decode from %v into %v", vv.Type(), want)
			}
		}
	}
	entry := vdStackEntry{
		Value:      vv,
		IsAny:      isAny,
		IsOptional: isOptional,
		Index:      -1,
	}
	if vv.Kind() == Map || vv.Kind() == Set {
		entry.Keys = vv.Keys()
	}
	d.stack = append(d.stack, entry)
	return nil
}

func (d *valueDecoder) IgnoreNextStartValue() {
	d.ignoreNext = true
}

func (d *valueDecoder) FinishValue() error {
	if len(d.stack) == 0 {
		return errEmptyDecoderStack
	}
	d.stack = d.stack[:len(d.stack)-1]
	d.ignoreNext = false
	return nil
}

func (d *valueDecoder) SkipValue() error {
	d.ignoreNext = false
	return nil
}

func (d *valueDecoder) NextEntry() (bool, error) {
	top := d.top()
	if top == nil {
		return false, errEmptyDecoderStack
	}
	top.Index++
	switch top.Value.Kind() {
	case Array, List, Set, Map:
		switch {
		case top.Index == top.Value.Len():
			return true, nil
		case top.Index > top.Value.Len():
			return false, fmt.Errorf("vdl: NextEntry called after done, stack: %+v", d.stack)
		}
	}
	return false, nil
}

func (d *valueDecoder) NextField() (string, error) {
	top := d.top()
	if top == nil {
		return "", errEmptyDecoderStack
	}
	top.Index++
	index, max := top.Index, top.Value.Type().NumField()
	if top.Value.Kind() == Union {
		max = 1
		index, _ = top.Value.UnionField()
	}
	if top.Index == max {
		return "", nil
	} else if top.Index > max {
		return "", fmt.Errorf("vdl: NextField called after done, stack: %+v", d.stack)
	}
	return top.Value.Type().Field(index).Name, nil
}

func (d *valueDecoder) topValue() *Value {
	if top := d.top(); top != nil {
		return top.Value
	}
	return nil
}

func (d *valueDecoder) Type() *Type {
	if top := d.top(); top != nil {
		return top.Value.Type()
	}
	return nil
}

func (d *valueDecoder) IsAny() bool {
	if top := d.top(); top != nil {
		return top.IsAny
	}
	return false
}

func (d *valueDecoder) IsOptional() bool {
	if top := d.top(); top != nil {
		return top.IsOptional
	}
	return false
}

func (d *valueDecoder) IsNil() bool {
	if top := d.top(); top != nil {
		return top.Value.IsNil()
	}
	return false
}

func (d *valueDecoder) Index() int {
	if top := d.top(); top != nil {
		return top.Index
	}
	return -1
}

func (d *valueDecoder) LenHint() int {
	if top := d.top(); top != nil {
		switch top.Value.Kind() {
		case List, Map, Set, Array:
			return top.Value.Len()
		}
	}
	return -1
}

func (d *valueDecoder) DecodeBool() (bool, error) {
	topV := d.topValue()
	if topV == nil {
		return false, errEmptyDecoderStack
	}
	if topV.Kind() == Bool {
		return topV.Bool(), nil
	}
	return false, fmt.Errorf("vdl: incompatible decode from %v into bool", topV.Type())
}

func (d *valueDecoder) DecodeUint(bitlen int) (uint64, error) {
	const errFmt = "vdl: conversion from %v into uint%d loses precision: %v"
	topV, ubitlen := d.topValue(), uint(bitlen)
	if topV == nil {
		return 0, errEmptyDecoderStack
	}
	switch topV.Kind() {
	case Byte, Uint16, Uint32, Uint64:
		x := topV.Uint()
		if shift := 64 - ubitlen; x != (x<<shift)>>shift {
			return 0, fmt.Errorf(errFmt, topV.Type(), bitlen, x)
		}
		return x, nil
	case Int8, Int16, Int32, Int64:
		x := topV.Int()
		ux := uint64(x)
		if shift := 64 - ubitlen; x < 0 || ux != (ux<<shift)>>shift {
			return 0, fmt.Errorf(errFmt, topV.Type(), bitlen, x)
		}
		return ux, nil
	case Float32, Float64:
		x := topV.Float()
		ux := uint64(x)
		if shift := 64 - ubitlen; x != float64(ux) || ux != (ux<<shift)>>shift {
			return 0, fmt.Errorf(errFmt, topV.Type(), bitlen, x)
		}
		return ux, nil
	default:
		return 0, fmt.Errorf("vdl: incompatible decode from %v into uint%d", topV.Type(), bitlen)
	}
}

func (d *valueDecoder) DecodeInt(bitlen int) (int64, error) {
	const errFmt = "vdl: conversion from %v into int%d loses precision: %v"
	topV, ubitlen := d.topValue(), uint(bitlen)
	if topV == nil {
		return 0, errEmptyDecoderStack
	}
	switch topV.Kind() {
	case Byte, Uint16, Uint32, Uint64:
		x := topV.Uint()
		ix := int64(x)
		// The shift uses 65 since the topmost bit is the sign bit.  I.e. 32 bit
		// numbers should be shifted by 33 rather than 32.
		if shift := 65 - ubitlen; ix < 0 || x != (x<<shift)>>shift {
			return 0, fmt.Errorf(errFmt, topV.Type(), bitlen, x)
		}
		return ix, nil
	case Int8, Int16, Int32, Int64:
		x := topV.Int()
		if shift := 64 - ubitlen; x != (x<<shift)>>shift {
			return 0, fmt.Errorf(errFmt, topV.Type(), bitlen, x)
		}
		return x, nil
	case Float32, Float64:
		x := topV.Float()
		ix := int64(x)
		if shift := 64 - ubitlen; x != float64(ix) || ix != (ix<<shift)>>shift {
			return 0, fmt.Errorf(errFmt, topV.Type(), bitlen, x)
		}
		return ix, nil
	default:
		return 0, fmt.Errorf("vdl: incompatible decode from %v into int%d", topV.Type(), bitlen)
	}
}

func (d *valueDecoder) DecodeFloat(bitlen int) (float64, error) {
	const errFmt = "vdl: conversion from %v into float%d loses precision: %v"
	topV := d.topValue()
	if topV == nil {
		return 0, errEmptyDecoderStack
	}
	switch topV.Kind() {
	case Byte, Uint16, Uint32, Uint64:
		x := topV.Uint()
		var max uint64
		if bitlen > 32 {
			max = float64MaxInt
		} else {
			max = float32MaxInt
		}
		if x > max {
			return 0, fmt.Errorf(errFmt, topV.Type(), bitlen, x)
		}
		return float64(x), nil
	case Int8, Int16, Int32, Int64:
		x := topV.Int()
		var min, max int64
		if bitlen > 32 {
			min, max = float64MinInt, float64MaxInt
		} else {
			min, max = float32MinInt, float32MaxInt
		}
		if x < min || x > max {
			return 0, fmt.Errorf(errFmt, topV.Type(), bitlen, x)
		}
		return float64(x), nil
	case Float32, Float64:
		x := topV.Float()
		if bitlen <= 32 && (x < -math.MaxFloat32 || x > math.MaxFloat32) {
			return 0, fmt.Errorf(errFmt, topV.Type(), bitlen, x)
		}
		return x, nil
	default:
		return 0, fmt.Errorf("vdl: incompatible decode from %v into float%d", topV.Type(), bitlen)
	}
}

func (d *valueDecoder) DecodeBytes(fixedlen int, v *[]byte) error {
	topV := d.topValue()
	if topV == nil {
		return errEmptyDecoderStack
	}
	if !topV.Type().IsBytes() {
		return DecodeConvertedBytes(d, fixedlen, v)
	}
	if fixedlen >= 0 && fixedlen != topV.Len() {
		return fmt.Errorf("vdl: %v got %d bytes, want fixed len %d", topV.Type(), topV.Len(), fixedlen)
	}
	if cap(*v) >= topV.Len() {
		*v = (*v)[:topV.Len()]
	} else {
		*v = make([]byte, topV.Len())
	}
	copy(*v, topV.Bytes())
	return nil
}

func (d *valueDecoder) DecodeString() (string, error) {
	topV := d.topValue()
	if topV == nil {
		return "", errEmptyDecoderStack
	}
	switch topV.Kind() {
	case String:
		return topV.RawString(), nil
	case Enum:
		return topV.EnumLabel(), nil
	}
	return "", fmt.Errorf("vdl: incompatible decode from %v into string", topV.Type())
}

func (d *valueDecoder) DecodeTypeObject() (*Type, error) {
	topV := d.topValue()
	if topV == nil {
		return nil, errEmptyDecoderStack
	}
	if topV.Type() == TypeObjectType {
		return topV.TypeObject(), nil
	}
	return nil, fmt.Errorf("vdl: incompatible decode from %v into typeobject", topV.Type())
}

func (d *valueDecoder) top() *vdStackEntry {
	if len(d.stack) > 0 {
		return &d.stack[len(d.stack)-1]
	}
	return nil
}
