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

import (
	"fmt"
	"reflect"
)

// Target represents a generic conversion target; objects that implement this
// interface may be used as the target of a value conversion.  E.g.
// ReflectTarget and ValueTarget create targets based on an underlying
// reflect.Value or Value respectively.  Other implementations of this
// interface include vom encoding targets, that produce binary and JSON vom
// encodings.
type Target interface {
	// FromBool converts from the src bool to the target, where tt represents the
	// concrete type of bool.
	FromBool(src bool, tt *Type) error
	// FromUint converts from the src uint to the target, where tt represents the
	// concrete type of uint.
	FromUint(src uint64, tt *Type) error
	// FromInt converts from the src int to the target, where tt represents the
	// concrete type of int.
	FromInt(src int64, tt *Type) error
	// FromFloat converts from the src float to the target, where tt represents
	// the concrete type of float.
	FromFloat(src float64, tt *Type) error
	// FromBytes converts from the src bytes to the target, where tt represents
	// the concrete type of bytes.
	FromBytes(src []byte, tt *Type) error
	// FromString converts from the src string to the target, where tt represents
	// the concrete type of string.
	FromString(src string, tt *Type) error
	// FromEnumLabel converts from the src enum label to the target, where tt
	// represents the concrete type of enum.
	FromEnumLabel(src string, tt *Type) error
	// FromTypeObject converts from the src type to the target.
	FromTypeObject(src *Type) error
	// FromNil converts from a nil (nonexistent) value of type tt, where tt must
	// be of kind Optional or Any.
	FromNil(tt *Type) error

	// StartList prepares conversion from a list or array of type tt, with the
	// given len.  FinishList must be called to finish the list.
	StartList(tt *Type, len int) (ListTarget, error)
	// FinishList finishes a prior StartList call.
	FinishList(x ListTarget) error

	// StartSet prepares conversion from a set of type tt, with the given len.
	// FinishSet must be called to finish the set.
	StartSet(tt *Type, len int) (SetTarget, error)
	// FinishSet finishes a prior StartSet call.
	FinishSet(x SetTarget) error

	// StartMap prepares conversion from a map of type tt, with the given len.
	// FinishMap must be called to finish the map.
	StartMap(tt *Type, len int) (MapTarget, error)
	// FinishMap finishes a prior StartMap call.
	FinishMap(x MapTarget) error

	// StartFields prepares conversion from a struct or union of type tt.
	// FinishFields must be called to finish the fields.
	StartFields(tt *Type) (FieldsTarget, error)
	// FinishFields finishes a prior StartFields call.
	FinishFields(x FieldsTarget) error
}

// Targeter represents an underlying data object that provides its own target
// making and filling operations.  During conversions, types that implement
// Targeter skip the reflection-based codepath and instead make and fill the
// target directly.  This is used during vdl code generation to provide
// high-performance encoders and decoders.
type Targeter interface {
	// MakeVDLTarget returns the target corresponding to the underlying data.
	MakeVDLTarget() Target
	// FillVDLTarget fills target with the contents of the underlying data.
	FillVDLTarget(target Target, expectedType *Type) error
}

// ListTarget represents conversion from a list or array.
type ListTarget interface {
	// StartElem prepares conversion of the next list elem.  The given index must
	// start at 0, and be incremented by one by each successive StartElem call.
	// FinishElem must be called to finish the elem.
	//
	// TODO(toddw): Remove index?
	StartElem(index int) (elem Target, _ error)
	// FinishElem finishes a prior StartElem call.
	FinishElem(elem Target) error
}

// SetTarget represents conversion from a set.
type SetTarget interface {
	// StartKey prepares conversion of the next set key.  FinishKey must be called
	// to finish the key.
	StartKey() (key Target, _ error)
	// FinishKey finishes a prior StartKey call.  ErrFieldNoExist indicates the
	// key doesn't exist on the target.
	FinishKey(key Target) error
}

// MapTarget represents conversion from a map.
type MapTarget interface {
	// StartKey prepares conversion of the next map key.  FinishKeyStartField must
	// be called to finish the key.
	StartKey() (key Target, _ error)
	// FinishKeyStartField finishes a prior StartKey call, and starts the
	// associated field.  ErrFieldNoExist indicates the key doesn't exist on the
	// target.
	FinishKeyStartField(key Target) (field Target, _ error)
	// FinishField finishes a prior FinishKeyStartField call.
	FinishField(key, field Target) error
}

// FieldsTarget represents conversion from struct or union fields.
type FieldsTarget interface {
	// StartField prepares conversion of the field with the given name.
	// FinishField must be called to finish the field.  ErrFieldNoExist indicates
	// the field name doesn't exist on the target.
	StartField(name string) (key, field Target, _ error)
	// FinishField finishes a prior StartField call.
	FinishField(key, field Target) error
	// ZeroField writes a zero-valued field.
	// This is a no-op in the encoder for struct fields.
	ZeroField(name string) error
}

// Convert converts from src to dst - it is a helper for calling
// ReflectTarget(reflect.ValueOf(dst)).FromReflect(reflect.ValueOf(src)).
func Convert(dst, src interface{}) error {
	target, err := ReflectTarget(reflect.ValueOf(dst))
	if err != nil {
		return err
	}
	return FromReflect(target, reflect.ValueOf(src))
}

// ValueOf returns the value corresponding to v.  It's a helper for calling
// ValueFromReflect, and panics on any errors.
func ValueOf(v interface{}) *Value {
	vv, err := ValueFromReflect(reflect.ValueOf(v))
	if err != nil {
		panic(err)
	}
	return vv
}

// ValueFromReflect returns the value corresponding to rv.
func ValueFromReflect(rv reflect.Value) (*Value, error) {
	var result *Value
	target, err := ReflectTarget(reflect.ValueOf(&result))
	if err != nil {
		return nil, err
	}
	if err := FromReflect(target, rv); err != nil {
		return nil, err
	}
	return result, nil
}

// FromReflect converts from rv to the target, by walking through rv and calling
// the appropriate methods on the target.
func FromReflect(target Target, rv reflect.Value) error {
	// Special-case to treat interface{}(nil) as any(nil).
	if !rv.IsValid() {
		return target.FromNil(AnyType)
	}

	// Flatten pointers and interfaces in rv, and handle special-cases.  We track
	// whether the final flattened value had any pointers via hasPtr, in order to
	// track optional types correctly.
	hasPtr := false
	for rv.Kind() == reflect.Ptr || rv.Kind() == reflect.Interface {
		// Handle special-case for errors.
		if rv.Type().ConvertibleTo(rtError) && !rv.IsNil() {
			return fromError(target, rv)
		}
		// Handle marshaling from native type to wire type.
		if ni := nativeInfoFromNative(rv.Type()); ni != nil {
			newWire := reflect.New(ni.WireType)
			if err := ni.FromNative(newWire, rv); err != nil {
				return err
			}
			if hasPtr {
				return FromReflect(target, newWire)
			}
			return FromReflect(target, newWire.Elem())
		}
		hasPtr = rv.Kind() == reflect.Ptr
		switch rt := rv.Type(); {
		case rv.IsNil():
			tt, err := TypeFromReflect(rv.Type())
			if err != nil {
				return err
			}
			switch {
			case tt.Kind() == TypeObject:
				// Treat nil *Type as AnyType.
				return target.FromTypeObject(AnyType)
			case tt.Kind() == Union && rt.Kind() == reflect.Interface:
				// Treat nil Union interface as the value of the type at index 0.
				return FromValue(target, ZeroValue(tt))
			}
			return target.FromNil(tt)
		case rt.ConvertibleTo(rtPtrToType):
			// If rv is convertible to *Type, fill from it directly.
			return target.FromTypeObject(rv.Convert(rtPtrToType).Interface().(*Type))
		case rt.ConvertibleTo(rtPtrToValue):
			// If rv is convertible to *Value, fill from it directly.
			return FromValue(target, rv.Convert(rtPtrToValue).Interface().(*Value))
		case rt.Implements(rtTargeter):
			tt, err := TypeFromReflect(rt)
			if err != nil {
				return err
			}
			return rv.Interface().(Targeter).FillVDLTarget(target, tt)
		}
		rv = rv.Elem()
	}
	if reflect.PtrTo(rv.Type()).Implements(rtTargeter) {
		rvPtr := reflect.New(rv.Type())
		rvPtr.Elem().Set(rv)
		tt, err := TypeFromReflect(rv.Type())
		if err != nil {
			return err
		}
		return rvPtr.Interface().(Targeter).FillVDLTarget(target, tt)
	}

	// Handle special-case for errors.
	if rv.Type().ConvertibleTo(rtError) {
		return fromError(target, rv)
	}
	// Handle marshaling from native type to wire type.
	if ni := nativeInfoFromNative(rv.Type()); ni != nil {
		newWire := reflect.New(ni.WireType)
		if err := ni.FromNative(newWire, rv); err != nil {
			return err
		}
		if hasPtr {
			return FromReflect(target, newWire)
		}
		return FromReflect(target, newWire.Elem())
	}
	// Initialize type information.  The optionality is a bit tricky.  Both rt and
	// rv refer to the flattened value, with no pointers or interfaces.  But tt
	// refers to the optional type, iff the original value had a pointer.  This is
	// required so that each of the Target.From* methods can get full type
	// information, including optionality.
	rt := rv.Type()
	tt, err := TypeFromReflect(rv.Type())
	if err != nil {
		return err
	}
	ttFrom := tt
	if tt.CanBeOptional() && hasPtr {
		ttFrom = OptionalType(tt)
	}
	// Recursive walk through the reflect value to fill in target.
	//
	// First handle special-cases enum and union.  Note that TypeFromReflect
	// has already validated the methods, so we can call without error checking.
	switch tt.Kind() {
	case Enum:
		label := rv.Interface().(stringer).String()
		return target.FromEnumLabel(label, ttFrom)
	case Union:
		// We're guaranteed rv is the concrete field struct.
		name := rv.Interface().(namer).Name()
		fieldsTarget, err := target.StartFields(ttFrom)
		if err != nil {
			return err
		}
		key, field, err := fieldsTarget.StartField(name)
		if err != nil {
			return err // no ErrFieldNoExist special-case; union field is required
		}
		// Grab the "Value" field of the concrete field struct.
		rvFieldValue := rv.Field(0)
		if err := FromReflect(field, rvFieldValue); err != nil {
			return err
		}
		if err := fieldsTarget.FinishField(key, field); err != nil {
			return err
		}
		return target.FinishFields(fieldsTarget)
	}
	// Now handle special-case bytes.
	if isRTBytes(rt) {
		return target.FromBytes(rtBytes(rv), ttFrom)
	}
	// Handle standard kinds.
	switch rt.Kind() {
	case reflect.Bool:
		return target.FromBool(rv.Bool(), ttFrom)
	case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint, reflect.Uintptr:
		return target.FromUint(rv.Uint(), ttFrom)
	case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int:
		return target.FromInt(rv.Int(), ttFrom)
	case reflect.Float32, reflect.Float64:
		return target.FromFloat(rv.Float(), ttFrom)
	case reflect.String:
		return target.FromString(rv.String(), ttFrom)
	case reflect.Array, reflect.Slice:
		listTarget, err := target.StartList(ttFrom, rv.Len())
		if err != nil {
			return err
		}
		for ix := 0; ix < rv.Len(); ix++ {
			elem, err := listTarget.StartElem(ix)
			if err != nil {
				return err
			}
			if err := FromReflect(elem, rv.Index(ix)); err != nil {
				return err
			}
			if err := listTarget.FinishElem(elem); err != nil {
				return err
			}
		}
		return target.FinishList(listTarget)
	case reflect.Map:
		if tt.Kind() == Set {
			setTarget, err := target.StartSet(ttFrom, rv.Len())
			if err != nil {
				return err
			}
			for _, rvkey := range rv.MapKeys() {
				key, err := setTarget.StartKey()
				if err != nil {
					return err
				}
				if err := FromReflect(key, rvkey); err != nil {
					return err
				}
				switch err := setTarget.FinishKey(key); {
				case err == ErrFieldNoExist:
					continue // silently drop unknown fields
				case err != nil:
					return err
				}
			}
			return target.FinishSet(setTarget)
		}
		mapTarget, err := target.StartMap(ttFrom, rv.Len())
		if err != nil {
			return err
		}
		for _, rvkey := range rv.MapKeys() {
			key, err := mapTarget.StartKey()
			if err != nil {
				return err
			}
			if err := FromReflect(key, rvkey); err != nil {
				return err
			}
			field, err := mapTarget.FinishKeyStartField(key)
			switch {
			case err == ErrFieldNoExist:
				continue // silently drop unknown fields
			case err != nil:
				return err
			}
			if err := FromReflect(field, rv.MapIndex(rvkey)); err != nil {
				return err
			}
			if err := mapTarget.FinishField(key, field); err != nil {
				return err
			}
		}
		return target.FinishMap(mapTarget)
	case reflect.Struct:
		fieldsTarget, err := target.StartFields(ttFrom)
		if err != nil {
			return err
		}
		// Loop through tt fields rather than rt fields, since the VDL type tt might
		// have ignored some of the fields in rt, e.g. unexported fields.
		for fx := 0; fx < tt.NumField(); fx++ {
			name := tt.Field(fx).Name
			key, field, err := fieldsTarget.StartField(name)
			switch {
			case err == ErrFieldNoExist:
				continue // silently drop unknown fields
			case err != nil:
				return err
			}
			rvField := rv.FieldByName(name)
			if !rvField.IsValid() {
				// This case occurs if the VDL type tt has a field name that doesn't
				// eixst in the Go reflect.Type rt.  This should never occur; it
				// indicates a bug in the TypeOf logic.  Panic here to give us a
				// stack trace to make it easier to debug.
				panic(fmt.Errorf("missing struct field %q, tt: %v, rt: %v", name, tt, rt))
			}
			if err := FromReflect(field, rvField); err != nil {
				return err
			}
			if err := fieldsTarget.FinishField(key, field); err != nil {
				return err
			}
		}
		return target.FinishFields(fieldsTarget)
	default:
		return fmt.Errorf("FromReflect invalid type %v", rt)
	}
}

// fromError handles all rv values that implement the error interface.
func fromError(target Target, rv reflect.Value) error {
	// Convert to the WireError representation of rv.
	ni, err := nativeInfoForError()
	if err != nil {
		return err
	}
	newWire := reflect.New(ni.WireType)
	if err := ni.FromNative(newWire, rv); err != nil {
		return err
	}
	// We know that rv is convertible to error; ensure we end up with the right
	// optionality, in case target is an interface.
	if rt := rv.Type(); rt.Kind() == reflect.Ptr && rt.Elem().ConvertibleTo(rtError) {
		return FromReflect(target, newWire)
	}
	return FromReflect(target, newWire.Elem())
}

// FromValue converts from vv to the target, by walking through vv and calling
// the appropriate methods on the target.
func FromValue(target Target, vv *Value) error {
	tt := vv.Type()
	if tt.Kind() == Any {
		if vv.IsNil() {
			return target.FromNil(tt)
		}
		// Non-nil any simply converts from the elem.
		vv = vv.Elem()
		tt = vv.Type()
	}
	if tt.Kind() == Optional {
		if vv.IsNil() {
			return target.FromNil(tt)
		}
		// Non-nil optional is special - we keep tt as the optional type, but use
		// the elem value for the actual value below.
		vv = vv.Elem()
	}
	if vv.Type().IsBytes() {
		return target.FromBytes(vv.Bytes(), tt)
	}
	switch vv.Kind() {
	case Bool:
		return target.FromBool(vv.Bool(), tt)
	case Byte, Uint16, Uint32, Uint64:
		return target.FromUint(vv.Uint(), tt)
	case Int8, Int16, Int32, Int64:
		return target.FromInt(vv.Int(), tt)
	case Float32, Float64:
		return target.FromFloat(vv.Float(), tt)
	case String:
		return target.FromString(vv.RawString(), tt)
	case Enum:
		return target.FromEnumLabel(vv.EnumLabel(), tt)
	case TypeObject:
		return target.FromTypeObject(vv.TypeObject())
	case Array, List:
		listTarget, err := target.StartList(tt, vv.Len())
		if err != nil {
			return err
		}
		for ix := 0; ix < vv.Len(); ix++ {
			elem, err := listTarget.StartElem(ix)
			if err != nil {
				return err
			}
			if err := FromValue(elem, vv.Index(ix)); err != nil {
				return err
			}
			if err := listTarget.FinishElem(elem); err != nil {
				return err
			}
		}
		return target.FinishList(listTarget)
	case Set:
		setTarget, err := target.StartSet(tt, vv.Len())
		if err != nil {
			return err
		}
		for _, vvkey := range vv.Keys() {
			key, err := setTarget.StartKey()
			if err != nil {
				return err
			}
			if err := FromValue(key, vvkey); err != nil {
				return err
			}
			switch err := setTarget.FinishKey(key); {
			case err == ErrFieldNoExist:
				continue // silently drop unknown fields
			case err != nil:
				return err
			}
		}
		return target.FinishSet(setTarget)
	case Map:
		mapTarget, err := target.StartMap(tt, vv.Len())
		if err != nil {
			return err
		}
		for _, vvkey := range vv.Keys() {
			key, err := mapTarget.StartKey()
			if err != nil {
				return err
			}
			if err := FromValue(key, vvkey); err != nil {
				return err
			}
			field, err := mapTarget.FinishKeyStartField(key)
			switch {
			case err == ErrFieldNoExist:
				continue // silently drop unknown fields
			case err != nil:
				return err
			}
			if err := FromValue(field, vv.MapIndex(vvkey)); err != nil {
				return err
			}
			if err := mapTarget.FinishField(key, field); err != nil {
				return err
			}
		}
		return target.FinishMap(mapTarget)
	case Struct:
		fieldsTarget, err := target.StartFields(tt)
		if err != nil {
			return err
		}
		for fx := 0; fx < vv.Type().NumField(); fx++ {
			if vv.StructField(fx).IsZero() {
				err := fieldsTarget.ZeroField(vv.Type().Field(fx).Name)
				if err != nil && err != ErrFieldNoExist {
					return err
				}
				continue
			}
			key, field, err := fieldsTarget.StartField(vv.Type().Field(fx).Name)
			switch {
			case err == ErrFieldNoExist:
				continue // silently drop unknown fields
			case err != nil:
				return err
			}
			if err := FromValue(field, vv.StructField(fx)); err != nil {
				return err
			}
			if err := fieldsTarget.FinishField(key, field); err != nil {
				return err
			}
		}
		return target.FinishFields(fieldsTarget)
	case Union:
		fieldsTarget, err := target.StartFields(tt)
		if err != nil {
			return err
		}
		fx, vvFieldValue := vv.UnionField()
		key, field, err := fieldsTarget.StartField(vv.Type().Field(fx).Name)
		if err != nil {
			return err // no ErrFieldNoExist special-case; union field is required
		}
		if err := FromValue(field, vvFieldValue); err != nil {
			return err
		}
		if err := fieldsTarget.FinishField(key, field); err != nil {
			return err
		}
		return target.FinishFields(fieldsTarget)
	default:
		panic(fmt.Errorf("FromValue unhandled %v %v", vv.Kind(), tt))
	}
}
