package transcoder

import (
	"fmt"
	"reflect"

	"mojo/public/go/bindings"

	"v.io/v23/vdl"
)

// Decode decodes the mojom-encoded data into valptr, which must be a pointer to
// the desired value.  The datatype describes the type of the encoded data.
// Returns an error if the data cannot be decoded into valptr, based on the VDL
// value conversion rules.
func MojomToVdl(data []byte, datatype *vdl.Type, valptr interface{}) error {
	target, err := vdl.ReflectTarget(reflect.ValueOf(valptr))
	if err != nil {
		return err
	}
	mtv := &mojomToVdlTranscoder{modec: bindings.NewDecoder(data, nil)}
	return mtv.transcodeValue(datatype, target, true, false)
}

type mojomToVdlTranscoder struct {
	modec *bindings.Decoder
	typeStack []*vdl.Type
}

func (mtv *mojomToVdlTranscoder) transcodeValue(vt *vdl.Type, target vdl.Target, isTopType, isNullable bool) error {
	switch vt.Kind() {
	case vdl.Bool:
		value, err := mtv.modec.ReadBool()
		if err != nil {
			return err
		}
		return target.FromBool(value, vt)
	case vdl.Int16:
		value, err := mtv.modec.ReadInt16()
		if err != nil {
			return err
		}
		return target.FromInt(int64(value), vt)
	case vdl.Int32:
		value, err := mtv.modec.ReadInt32()
		if err != nil {
			return err
		}
		return target.FromInt(int64(value), vt)
	case vdl.Int64:
		value, err := mtv.modec.ReadInt64()
		if err != nil {
			return err
		}
		return target.FromInt(value, vt)
	case vdl.Byte:
		value, err := mtv.modec.ReadUint8()
		if err != nil {
			return err
		}
		return target.FromUint(uint64(value), vt)
	case vdl.Uint16:
		value, err := mtv.modec.ReadUint16()
		if err != nil {
			return err
		}
		return target.FromUint(uint64(value), vt)
	case vdl.Uint32:
		value, err := mtv.modec.ReadUint32()
		if err != nil {
			return err
		}
		return target.FromUint(uint64(value), vt)
	case vdl.Uint64:
		value, err := mtv.modec.ReadUint64()
		if err != nil {
			return err
		}
		return target.FromUint(value, vt)
	case vdl.Float32:
		value, err := mtv.modec.ReadFloat32()
		if err != nil {
			return err
		}
		return target.FromFloat(float64(value), vt)
	case vdl.Float64:
		value, err := mtv.modec.ReadFloat64()
		if err != nil {
			return err
		}
		return target.FromFloat(value, vt)
	case vdl.String:
		switch ptr, err := mtv.modec.ReadPointer(); {
		case err != nil:
			return err
		case ptr == 0:
			return fmt.Errorf("invalid null string pointer")
		default:
			value, err := mtv.modec.ReadString()
			if err != nil {
				return err
			}
			return target.FromString(value, vt)
		}
		return nil
	case vdl.Enum:
		index, err := mtv.modec.ReadInt32()
		if err != nil {
			return err
		}
		if int(index) >= vt.NumEnumLabel() || index < 0 {
			return fmt.Errorf("enum label out of range")
		}
		target.FromEnumLabel(vt.EnumLabel(int(index)), vt)
		return nil
	case vdl.Complex64:
		panic("unimplemented")
	case vdl.Complex128:
		panic("unimplemented")
	case vdl.Array, vdl.List:
		switch ptr, err := mtv.modec.ReadPointer(); {
		case err != nil:
			return err
		case ptr == 0 && isNullable:
			return target.FromNil(vdl.OptionalType(vt))
		case ptr == 0 && !isNullable:
			return fmt.Errorf("invalid null struct pointer")
		}

		if vt.IsBytes() {
			str, err := mtv.modec.ReadString()
			if err != nil {
				return err
			}
			return target.FromBytes([]byte(str), vt)
		} else {
			elemBitSize := baseTypeSizeBits(vt.Elem())
			numElems, err := mtv.modec.StartArray(elemBitSize)
			if err != nil {
				return err
			}
			listTarget, err := target.StartList(vt, int(numElems))
			if err != nil {
				return err
			}
			for i := 0; i < int(numElems); i++ {
				elemTarget, err := listTarget.StartElem(i)
				if err != nil {
					return err
				}
				if err := mtv.transcodeValue(vt.Elem(), elemTarget, false, false); err != nil {
					return err
				}
				if err := listTarget.FinishElem(elemTarget); err != nil {
					return err
				}
			}
			if err := target.FinishList(listTarget); err != nil {
				return err
			}
		}
		return mtv.modec.Finish()
	case vdl.Set:
		panic("unimplemented")
		/*switch ptr, err := d.dec.ReadPointer(); {
		case err != nil:
			return err
		case ptr == 0 && isNullable:
			return target.FromNil(vdl.OptionalType(vt))
		case ptr == 0 && !isNullable:
			return fmt.Errorf("invalid null struct pointer")
		}
		keyBitSize := baseTypeSizeBits(vt.Key())
		numKeys, err := d.dec.StartArray(keyBitSize)
		if err != nil {
			return err
		}
		setTarget, err := target.StartSet(vt, int(numKeys))
		if err != nil {
			return err
		}
		for i := 0; i < int(numKeys); i++ {
			keyTarget, err := setTarget.StartKey()
			if err != nil {
				return err
			}
			if err := d.decodeValue(mt.Key, keyTarget, false, false); err != nil {
				return err
			}
			if err := setTarget.FinishKey(keyTarget); err != nil {
				return err
			}
		}
		if err := target.FinishSet(setTarget); err != nil {
			return err
		}
		return d.dec.Finish()*/
	case vdl.Map:
		switch ptr, err := mtv.modec.ReadPointer(); {
		case err != nil:
			return err
		case ptr == 0 && isNullable:
			return target.FromNil(vdl.OptionalType(vt))
		case ptr == 0 && !isNullable:
			return fmt.Errorf("invalid null struct pointer")
		}
		if err := mtv.modec.StartMap(); err != nil {
			return err
		}
		var keys, values []*vdl.Value
		keysTarget, err := vdl.ReflectTarget(reflect.ValueOf(&keys))
		if err != nil {
			return err
		}
		keysListType := vdl.ListType(vt.Key())
		if err := mtv.transcodeValue(keysListType, keysTarget, false, false); err != nil {
			return err
		}
		valuesTarget, err := vdl.ReflectTarget(reflect.ValueOf(&values))
		if err != nil {
			return err
		}
		valuesListType := vdl.ListType(vt.Elem())
		if err := mtv.transcodeValue(valuesListType, valuesTarget, false, false); err != nil {
			return err
		}

		if len(keys) != len(values) {
			return fmt.Errorf("values don't match keys")
		}
		mapTarget, err := target.StartMap(vt, len(keys))
		if err != nil {
			return err
		}
		for i, key := range keys {
			value := values[i]

			keyTarget, err := mapTarget.StartKey()
			if err != nil {
				return err
			}
			if err := vdl.FromValue(keyTarget, key); err != nil {
				return err
			}
			fieldTarget, err := mapTarget.FinishKeyStartField(keyTarget)
			if err != nil {
				return err
			}
			if err := vdl.FromValue(fieldTarget, value); err != nil {
				return err
			}
			if err := mapTarget.FinishField(keyTarget, fieldTarget); err != nil {
				return err
			}
		}
		if err := target.FinishMap(mapTarget); err != nil {
			return err
		}

		return mtv.modec.Finish()
	case vdl.Struct:
		// TODO(toddw): See the comment in encoder.mojomStructSize; we rely on the
		// fields to be presented in the canonical mojom field ordering.
		if !isTopType {
			switch ptr, err := mtv.modec.ReadPointer(); {
			case err != nil:
				return err
			case ptr == 0 && isNullable:
				return target.FromNil(vdl.OptionalType(vt))
			case ptr == 0 && !isNullable:
				return fmt.Errorf("invalid null struct pointer")
			}
		}
		_, err := mtv.modec.StartStruct()
		if err != nil {
			return err
		}
		targetFields, err := target.StartFields(vt)
		if err != nil {
			return err
		}
		for i := 0; i < vt.NumField(); i++ {
			mfield := vt.Field(i)
			switch vkey, vfield, err := targetFields.StartField(mfield.Name); {
			// TODO(toddw): Handle err == vdl.ErrFieldNoExist case?
			case err != nil:
				return err
			default:
				if err := mtv.transcodeValue(mfield.Type, vfield, false, false); err != nil {
					return err
				}
				if err := targetFields.FinishField(vkey, vfield); err != nil {
					return err
				}
			}
		}
		// TODO(toddw): Fill in fields that weren't decoded with their zero value.
		if err := target.FinishFields(targetFields); err != nil {
			return err
		}
		return mtv.modec.Finish()
	case vdl.Union:
		size, tag, err := mtv.modec.ReadUnionHeader()
		if err != nil {
			return err
		}
		if size == 0 {
			mtv.modec.SkipUnionValue()
			return target.FromNil(vdl.OptionalType(vt))
		}
		if int(tag) >= vt.NumField() {
			return fmt.Errorf("union tag out of bounds")
		}
		fld := vt.Field(int(tag))
		targetFields, err := target.StartFields(vt)
		if err != nil {
			return err
		}
		vKey, vField, err := targetFields.StartField(fld.Name)
		if err != nil {
			return err
		}
		if fld.Type.Kind() == vdl.Union {
			switch ptr, err := mtv.modec.ReadPointer(); {
			case err != nil:
				return err
			case ptr == 0 && isNullable:
				return target.FromNil(vdl.OptionalType(fld.Type))
			case ptr == 0 && !isNullable:
				return fmt.Errorf("invalid null union pointer")
			}
			if err := mtv.modec.StartNestedUnion(); err != nil {
				return err
			}
		}
		if err := mtv.transcodeValue(fld.Type, vField, false, false); err != nil {
			return err
		}
		if fld.Type.Kind() == vdl.Union {
			if err := mtv.modec.Finish(); err != nil {
				return err
			}
		}
		if err := targetFields.FinishField(vKey, vField); err != nil {
			return err
		}
		if err := target.FinishFields(targetFields); err != nil {
			return err
		}
		mtv.modec.FinishReadingUnionValue()
		return nil
	case vdl.Optional:
		return mtv.transcodeValue(vt.Elem(), target, false, true)
	case vdl.Any:
		panic("unimplemented")
	//case vdl.TypeObject:
	//	panic("unimplemented")
	default:
		panic(fmt.Errorf("decodeValue unhandled vdl type: %v", vt))
	}
}
