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

// +build reflectdecoder

// This code is expected to be deleted. It is here temporarily until
// we know whether it will actually be needed.

package vdl

import (
	"fmt"
	"reflect"
)

func NewReflectDecoder(rv reflect.Value) *reflectDecoder {
	return &reflectDecoder{initialRv: rv}
}

type reflectDecoder struct {
	initialRv         reflect.Value
	ignoreNext        bool
	stack             []rdStackEntry
	InnerDecoderDepth int
	InnerDecoder      Decoder
}

type rdStackEntry struct {
	Type             *Type
	ReflectValue     reflect.Value
	OrigReflectValue reflect.Value // if the type is native / error, hold the original rv to fill in FinishValue()
	Index            int
	NumStarted       int
	IsAny            bool
	IsOptional       bool
	IsNil            bool
	Keys             []reflect.Value
}

func (d *reflectDecoder) StartValue() error {
	if d.ignoreNext {
		d.ignoreNext = false
		return nil
	}
	if d.InnerDecoderDepth > 0 {
		d.InnerDecoderDepth++
		return d.InnerDecoder.StartValue()
	}
	var rv reflect.Value
	var tt *Type
	if top := d.top(); top == nil {
		rv = d.initialRv
		var err error
		if rv.IsValid() {
			tt, err = TypeFromReflect(rv.Type())
			if err != nil {
				return err
			}
		}
	} else {
		switch top.Type.Kind() {
		case Array, List:
			rv = top.ReflectValue.Index(top.Index)
			tt = top.Type.Elem()
		case Map:
			switch top.NumStarted % 2 {
			case 0:
				rv = top.Keys[top.Index]
				tt = top.Type.Key()
			case 1:
				rv = top.ReflectValue.MapIndex(top.Keys[top.Index])
				tt = top.Type.Elem()
			}
			top.NumStarted++
		case Set:
			rv = top.Keys[top.Index]
			tt = top.Type.Key()
		case Struct:
			fld := top.Type.Field(top.Index)
			rv = top.ReflectValue.FieldByName(fld.Name)
			tt = fld.Type
		case Union:
			unionRv := top.ReflectValue
			if top.ReflectValue.Kind() == reflect.Interface && !top.ReflectValue.IsNil() {
				unionRv = unionRv.Elem()
			}
			ri, _, err := deriveReflectInfo(unionRv.Type())
			if err != nil {
				return err
			}
			if unionRv.Type() == ri.Type {
				rv = reflect.Zero(ri.UnionFields[0].Type).FieldByName("Value")
				tt = tt.Field(0).Type
			} else {
				rv = unionRv.FieldByName("Value")
				unionIndex := -1
				for index, field := range ri.UnionFields {
					if field.RepType == unionRv.Type() {
						unionIndex = index
					}
				}
				if unionIndex < 0 {
					return fmt.Errorf("vdl: union field not found")
				}
				tt = top.Type.Field(unionIndex).Type
			}
		default:
			return fmt.Errorf("unknown composite kind: %v", top.Type.Kind())
		}
	}

	// ptrRv will be set to a single level of ptr around the inner value.
	// rv will be dereferenced entirely.
	var ptrRv reflect.Value
	for rv.IsValid() && (rv.Kind() == reflect.Ptr || rv.Kind() == reflect.Interface) {
		if rv.Kind() == reflect.Ptr {
			ptrRv = rv
		} else {
			ptrRv = reflect.Value{}
		}
		rv = rv.Elem()
	}

	if ptrRv.IsValid() {
		if dec, ok := ptrRv.Interface().(HasDecoder); ok {
			d.InnerDecoderDepth++
			d.InnerDecoder = dec.Decoder()
			return d.InnerDecoder.StartValue()
		}
	}

	if !rv.IsValid() || (tt.Kind() == Any && rv.IsNil()) {
		d.stack = append(d.stack, rdStackEntry{
			ReflectValue: rv,
			Type:         tt,
			IsAny:        true,
			IsNil:        true,
			Index:        -1,
		})
		return nil
	}

	if dec, ok := rv.Interface().(HasDecoder); ok {
		d.InnerDecoderDepth++
		d.InnerDecoder = dec.Decoder()
		return d.InnerDecoder.StartValue()
	}

	if ni := nativeInfoFromNative(rv.Type()); ni != nil {
		ptrRv = reflect.New(ni.WireType)
		if err := ni.FromNative(ptrRv, rv); err != nil {
			return err
		}
		rv = ptrRv.Elem()
	}

	var isAny, isOptional, isNil bool
	if tt.Kind() == Any {
		isAny = true
		var err error
		tt, err = TypeFromReflect(rv.Type())
		if err != nil {
			return err
		}
	}
	if tt.Kind() == Optional {
		switch {
		case !ptrRv.IsValid() || ptrRv.IsNil():
			isNil = true
		default:
			isOptional = true
			tt = tt.Elem()
		}
	}
	if tt.Kind() == TypeObject {
		rv = ptrRv
	}
	entry := rdStackEntry{
		ReflectValue: rv,
		Type:         tt,
		IsAny:        isAny,
		IsOptional:   isOptional,
		IsNil:        isNil,
		Index:        -1,
	}
	if tt.Kind() == Map || tt.Kind() == Set {
		entry.Keys = rv.MapKeys()
	}
	d.stack = append(d.stack, entry)
	return nil
}

func (d *reflectDecoder) StackDepth() int {
	return len(d.stack) + d.InnerDecoderDepth
}

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

func (d *reflectDecoder) FinishValue() error {
	if d.InnerDecoderDepth > 0 {
		d.InnerDecoderDepth--
		return d.InnerDecoder.FinishValue()
	}
	top := d.top()
	if top == nil {
		return errEmptyDecoderStack
	}
	d.stack = d.stack[:len(d.stack)-1]
	return nil
}

func (d *reflectDecoder) SkipValue() error {
	if d.InnerDecoderDepth > 0 {
		return d.InnerDecoder.SkipValue()
	}
	return nil
}

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

func (d *reflectDecoder) NextField() (string, error) {
	if d.InnerDecoderDepth > 0 {
		return d.InnerDecoder.NextField()
	}
	top := d.top()
	if top == nil {
		return "", errEmptyDecoderStack
	}
	max := top.Type.NumField()
	if top.Type.Kind() == Union {
		max = 1
	}
	top.Index++
	if top.Index == max {
		return "", nil
	} else if top.Index > max {
		return "", fmt.Errorf("vdl: NextField called after done, stack: %+v", d.stack)
	}

	if top.Type.Kind() == Union {
		unionRv := top.ReflectValue
		if top.ReflectValue.Kind() == reflect.Interface && !top.ReflectValue.IsNil() {
			unionRv = unionRv.Elem()
		}
		ri, _, err := deriveReflectInfo(unionRv.Type())
		if err != nil {
			return "", err
		}
		if unionRv.Type() == ri.Type {
			// Uninitialized union.
			return ri.UnionFields[0].Name, nil
		}
		for _, field := range ri.UnionFields {
			if field.RepType == unionRv.Type() {
				return field.Name, nil
			}
		}
		return "", fmt.Errorf("invalid union field type")
	}
	return top.Type.Field(top.Index).Name, nil
}

func (d *reflectDecoder) Type() *Type {
	if d.InnerDecoderDepth > 0 {
		return d.InnerDecoder.Type()
	}
	if top := d.top(); top != nil {
		return top.Type
	}
	return nil
}

func (d *reflectDecoder) IsAny() bool {
	if d.InnerDecoderDepth > 0 {
		return d.InnerDecoder.IsAny()
	}
	if top := d.top(); top != nil {
		return top.IsAny
	}
	return false
}

func (d *reflectDecoder) IsOptional() bool {
	if d.InnerDecoderDepth > 0 {
		return d.InnerDecoder.IsOptional()
	}
	if top := d.top(); top != nil {
		return top.IsOptional
	}
	return false
}

func (d *reflectDecoder) IsNil() bool {
	if d.InnerDecoderDepth > 0 {
		return d.InnerDecoder.IsNil()
	}
	if top := d.top(); top != nil {
		return top.IsNil
	}
	return false
}

func (d *reflectDecoder) Index() int {
	if d.InnerDecoderDepth > 0 {
		return d.InnerDecoder.Index()
	}
	if top := d.top(); top != nil {
		return top.Index
	}
	return -1
}

func (d *reflectDecoder) LenHint() int {
	if d.InnerDecoderDepth > 0 {
		return d.InnerDecoder.LenHint()
	}
	top := d.top()
	switch top.Type.Kind() {
	case List, Map, Set:
		return top.ReflectValue.Len()
	case Array:
		return top.Type.Len()
	}
	return -1
}

func (d *reflectDecoder) DecodeBool() (bool, error) {
	if d.InnerDecoderDepth > 0 {
		return d.InnerDecoder.DecodeBool()
	}
	top := d.top()
	if top == nil {
		return false, errEmptyDecoderStack
	}
	if top.Type.Kind() != Bool {
		return false, fmt.Errorf("vdl: type mismatch, got %v, want bool", top.Type)
	}
	return top.ReflectValue.Bool(), nil
}

func (d *reflectDecoder) DecodeUint(bitlen uint) (uint64, error) {
	if d.InnerDecoderDepth > 0 {
		return d.InnerDecoder.DecodeUint(bitlen)
	}
	const errFmt = "vom: %#v conversion to uint%d loses precision: %v"
	top := d.top()
	switch top.Type.Kind() {
	case Byte, Uint16, Uint32, Uint64:
		x := top.ReflectValue.Uint()
		if shift := 64 - bitlen; x != (x<<shift)>>shift {
			return 0, fmt.Errorf(errFmt, top.ReflectValue, bitlen, x)
		}
		return x, nil
	case Int8, Int16, Int32, Int64:
		x := top.ReflectValue.Int()
		ux := uint64(x)
		if shift := 64 - bitlen; x < 0 || ux != (ux<<shift)>>shift {
			return 0, fmt.Errorf(errFmt, top.ReflectValue, bitlen, x)
		}
		return ux, nil
	case Float32, Float64:
		x := top.ReflectValue.Float()
		ux := uint64(x)
		if shift := 64 - bitlen; x != float64(ux) || ux != (ux<<shift)>>shift {
			return 0, fmt.Errorf(errFmt, top.ReflectValue, bitlen, x)
		}
		return ux, nil
	default:
		return 0, fmt.Errorf("invalid kind for DecodeUint(): %v", top.Type.Kind())
	}
}

func (d *reflectDecoder) DecodeInt(bitlen uint) (int64, error) {
	if d.InnerDecoderDepth > 0 {
		return d.InnerDecoder.DecodeInt(bitlen)
	}
	const errFmt = "vom: %#v conversion to int%d loses precision: %v"
	top := d.top()
	switch top.Type.Kind() {
	case Byte, Uint16, Uint32, Uint64:
		x := top.ReflectValue.Uint()
		ix := int64(x)
		if shift := 64 - bitlen; ix < 0 || x != (x<<shift)>>shift {
			return 0, fmt.Errorf(errFmt, top.ReflectValue, bitlen, x)
		}
		return ix, nil
	case Int8, Int16, Int32, Int64:
		x := top.ReflectValue.Int()
		if shift := 64 - bitlen; x != (x<<shift)>>shift {
			return 0, fmt.Errorf(errFmt, top.ReflectValue, bitlen, x)
		}
		return x, nil
	case Float32, Float64:
		x := top.ReflectValue.Float()
		ix := int64(x)
		if shift := 64 - bitlen; x != float64(ix) || ix != (ix<<shift)>>shift {
			return 0, fmt.Errorf(errFmt, top.ReflectValue, bitlen, x)
		}
		return ix, nil
	default:
		return 0, fmt.Errorf("invalid kind for DecodeInt(): %v", top.Type.Kind())
	}
}

func (d *reflectDecoder) DecodeFloat(bitlen uint) (float64, error) {
	if d.InnerDecoderDepth > 0 {
		return d.InnerDecoder.DecodeFloat(bitlen)
	}
	const errFmt = "vom: %#v conversion to float%d loses precision: %v"
	top := d.top()
	switch top.Type.Kind() {
	case Byte, Uint16, Uint32, Uint64:
		x := top.ReflectValue.Uint()
		var max uint64
		if bitlen > 32 {
			max = float64MaxInt
		} else {
			max = float32MaxInt
		}
		if x > max {
			return 0, fmt.Errorf(errFmt, top.ReflectValue, bitlen, x)
		}
		return float64(x), nil
	case Int8, Int16, Int32, Int64:
		x := top.ReflectValue.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, top.ReflectValue, bitlen, x)
		}
		return float64(x), nil
	case Float32, Float64:
		return top.ReflectValue.Float(), nil
	default:
		return 0, fmt.Errorf("invalid kind for DecodeFloat(): %v", top.Type.Kind())
	}
}

func (d *reflectDecoder) DecodeBytes(fixedlen int, v *[]byte) error {
	if d.InnerDecoderDepth > 0 {
		return d.InnerDecoder.DecodeBytes(fixedlen, v)
	}
	if (d.StackDepth() == 1 || d.IsAny()) && !Compatible(TypeOf(*v), d.Type()) {
		return fmt.Errorf("incompatible bytes %T, from %v", *v, d.Type())
	}
	top := d.top()
	if top == nil {
		return errEmptyDecoderStack
	}
	if fixedlen >= 0 && top.ReflectValue.Len() != fixedlen {
		return fmt.Errorf("vdl: %v got %v bytes, want fixed len %v", top.Type, top.ReflectValue.Len(), fixedlen)
	}
	if !top.Type.IsBytes() {
		return bytesVDLRead(fixedlen, v, d)
	}
	if cap(*v) < top.ReflectValue.Len() {
		*v = make([]byte, top.ReflectValue.Len())
	} else {
		*v = (*v)[:top.ReflectValue.Len()]
	}
	reflect.Copy(reflect.ValueOf(*v), top.ReflectValue)
	return nil
}

func (d *reflectDecoder) DecodeString() (string, error) {
	if d.InnerDecoderDepth > 0 {
		return d.InnerDecoder.DecodeString()
	}
	top := d.top()
	if top == nil {
		return "", errEmptyDecoderStack
	}
	switch top.Type.Kind() {
	case String:
		return top.ReflectValue.String(), nil
	case Enum:
		if top.ReflectValue.Int() < 0 || int(top.ReflectValue.Int()) >= top.Type.NumEnumLabel() {
			return "", fmt.Errorf("vdl: %v enum index %d out of range", top.Type, top.ReflectValue.Int())
		}
		return top.Type.EnumLabel(int(top.ReflectValue.Int())), nil
	default:
		return "", fmt.Errorf("vdl: type mismatch, got %v, want string", top.Type)
	}
}

func (d *reflectDecoder) DecodeTypeObject() (*Type, error) {
	if d.InnerDecoderDepth > 0 {
		return d.InnerDecoder.DecodeTypeObject()
	}
	top := d.top()
	if top == nil {
		return nil, errEmptyDecoderStack
	}
	if top.Type != TypeObjectType {
		return nil, fmt.Errorf("vdl: type mismatch, got %v, want typeobject", top.Type)
	}
	return top.ReflectValue.Interface().(*Type), nil
}

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