/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package hessian

import (
	"io"
	"reflect"
	"strings"
	"sync"
)

import (
	perrors "github.com/pkg/errors"
)

// get @v go struct name
func typeof(v interface{}) string {
	return reflect.TypeOf(v).String()
}

/////////////////////////////////////////
// map/object
/////////////////////////////////////////

//class-def  ::= 'C' string int string* //  mandatory type string, the number of fields, and the field names.
//object     ::= 'O' int value* // class-def id, value list
//           ::= [x60-x6f] value* // class-def id, value list
//
//Object serialization
//
//class Car {
//  String color;
//  String model;
//}
//
//out.writeObject(new Car("red", "corvette"));
//out.writeObject(new Car("green", "civic"));
//
//---
//
//C                        # object definition (#0)
//  x0b example.Car        # type is example.Car
//  x92                    # two fields
//  x05 color              # color field name
//  x05 model              # model field name
//
//O                        # object def (long form)
//  x90                    # object definition #0
//  x03 red                # color field value
//  x08 corvette           # model field value
//
//x60                      # object def #0 (short form)
//  x05 green              # color field value
//  x05 civic              # model field value
//
//enum Color {
//  RED,
//  GREEN,
//  BLUE,
//}
//
//out.writeObject(Color.RED);
//out.writeObject(Color.GREEN);
//out.writeObject(Color.BLUE);
//out.writeObject(Color.GREEN);
//
//---
//
//C                         # class definition #0
//  x0b example.Color       # type is example.Color
//  x91                     # one field
//  x04 name                # enumeration field is "name"
//
//x60                       # object #0 (class def #0)
//  x03 RED                 # RED value
//
//x60                       # object #1 (class def #0)
//  x90                     # object definition ref #0
//  x05 GREEN               # GREEN value
//
//x60                       # object #2 (class def #0)
//  x04 BLUE                # BLUE value
//
//x51 x91                   # object ref #1, i.e. Color.GREEN
func (e *Encoder) encObject(v interface{}) error {
	var (
		i      int
		idx    int
		num    int
		err    error
		clsDef *classInfo
	)
	pojo, isPojo := v.(POJO)
	vv := reflect.ValueOf(v)

	// get none pojo JavaClassName
	var nonePojoJavaName string
	if !isPojo {
		s, ok := loadPOJORegistry(vv.Type().String())
		if !ok {
			return perrors.Errorf("non-pojo obj %s has not being registered before!", typeof(v))
		}
		nonePojoJavaName = s.javaName
	}

	// check ref
	if n, ok := e.checkRefMap(vv); ok {
		e.buffer = encRef(e.buffer, n)
		return nil
	}

	vv = UnpackPtr(vv)
	// check nil pointer
	if !vv.IsValid() {
		e.buffer = EncNull(e.buffer)
		return nil
	}

	// write object definition
	idx = -1
	for i = range e.classInfoList {
		if isPojo && pojo.JavaClassName() == e.classInfoList[i].javaName || !isPojo && nonePojoJavaName == e.classInfoList[i].javaName {
			idx = i
			break
		}
	}

	var ok bool
	if idx == -1 {
		idx, ok = checkPOJORegistry(typeof(v))
		if !ok {
			if reflect.TypeOf(v).Implements(javaEnumType) {
				idx = RegisterJavaEnum(v.(POJOEnum))
			} else if isPojo {
				idx = RegisterPOJO(pojo)
			} else {
				return perrors.Errorf("non-pojo obj %s has not being registered before!", typeof(v))
			}
		}
		_, clsDef, err = getStructDefByIndex(idx)
		if err != nil {
			return perrors.WithStack(err)
		}

		idx = len(e.classInfoList)
		e.classInfoList = append(e.classInfoList, clsDef)
		e.buffer = append(e.buffer, clsDef.buffer...)
	}

	// write object instance
	if byte(idx) <= OBJECT_DIRECT_MAX {
		e.buffer = encByte(e.buffer, byte(idx)+BC_OBJECT_DIRECT)
	} else {
		e.buffer = encByte(e.buffer, BC_OBJECT)
		e.buffer = encInt32(e.buffer, int32(idx))
	}

	if reflect.TypeOf(v).Implements(javaEnumType) {
		e.buffer = encString(e.buffer, v.(POJOEnum).String())
		return nil
	}

	structs := []reflect.Value{vv}
	for len(structs) > 0 {
		vv := structs[0]
		vvt := vv.Type()
		num = vv.NumField()
		for i = 0; i < num; i++ {
			tf := vvt.Field(i)
			// skip unexported anonymous field
			if tf.PkgPath != "" {
				continue
			}

			// skip ignored field
			if tag, _ := tf.Tag.Lookup(tagIdentifier); tag == `-` {
				continue
			}

			field := vv.Field(i)
			if tf.Anonymous && field.Kind() == reflect.Struct {
				structs = append(structs, field)
				continue
			}

			if err = e.Encode(field.Interface()); err != nil {
				fieldName := field.Type().String()
				return perrors.Wrapf(err, "failed to encode field: %s, %+v", fieldName, field.Interface())
			}
		}

		structs = structs[1:]
	}

	return nil
}

/////////////////////////////////////////
// Object
/////////////////////////////////////////

//class-def  ::= 'C' string int string* //  mandatory type string, the number of fields, and the field names.
//object     ::= 'O' int value* // class-def id, value list
//           ::= [x60-x6f] value* // class-def id, value list
//
//Object serialization
//
//class Car {
//  String color;
//  String model;
//}
//
//out.writeObject(new Car("red", "corvette"));
//out.writeObject(new Car("green", "civic"));
//
//---
//
//C                        # object definition (#0)
//  x0b example.Car        # type is example.Car
//  x92                    # two fields
//  x05 color              # color field name
//  x05 model              # model field name
//
//O                        # object def (long form)
//  x90                    # object definition #0
//  x03 red                # color field value
//  x08 corvette           # model field value
//
//x60                      # object def #0 (short form)
//  x05 green              # color field value
//  x05 civic              # model field value
//
//
//
//
//
//enum Color {
//  RED,
//  GREEN,
//  BLUE,
//}
//
//out.writeObject(Color.RED);
//out.writeObject(Color.GREEN);
//out.writeObject(Color.BLUE);
//out.writeObject(Color.GREEN);
//
//---
//
//C                         # class definition #0
//  x0b example.Color       # type is example.Color
//  x91                     # one field
//  x04 name                # enumeration field is "name"
//
//x60                       # object #0 (class def #0)
//  x03 RED                 # RED value
//
//x60                       # object #1 (class def #0)
//  x90                     # object definition ref #0
//  x05 GREEN               # GREEN value
//
//x60                       # object #2 (class def #0)
//  x04 BLUE                # BLUE value
//
//x51 x91                   # object ref #1, i.e. Color.GREEN

func (d *Decoder) decClassDef() (interface{}, error) {
	var (
		err       error
		clsName   string
		fieldNum  int32
		fieldName string
		fieldList []string
	)

	clsName, err = d.decString(TAG_READ)
	if err != nil {
		return nil, perrors.WithStack(err)
	}
	fieldNum, err = d.decInt32(TAG_READ)
	if err != nil {
		return nil, perrors.WithStack(err)
	}
	fieldList = make([]string, fieldNum)
	for i := 0; i < int(fieldNum); i++ {
		fieldName, err = d.decString(TAG_READ)
		if err != nil {
			return nil, perrors.Wrapf(err, "decClassDef->decString, field num:%d, index:%d", fieldNum, i)
		}
		fieldList[i] = fieldName
	}

	return &classInfo{javaName: clsName, fieldNameList: fieldList}, nil
}

type fieldInfo struct {
	indexes []int
	field   *reflect.StructField
}

// map[rType][fieldName]indexes
var fieldIndexCache sync.Map

func findFieldWithCache(name string, typ reflect.Type) ([]int, *reflect.StructField, error) {
	typCache, _ := fieldIndexCache.Load(typ)
	if typCache == nil {
		typCache = &sync.Map{}
		fieldIndexCache.Store(typ, typCache)
	}

	iindexes, existCache := typCache.(*sync.Map).Load(name)
	if existCache && iindexes != nil {
		finfo := iindexes.(*fieldInfo)
		var err error
		if len(finfo.indexes) == 0 {
			err = perrors.Errorf("failed to find field %s", name)
		}
		return finfo.indexes, finfo.field, err
	}

	indexes, field, err := findField(name, typ)
	typCache.(*sync.Map).Store(name, &fieldInfo{indexes: indexes, field: field})
	return indexes, field, err
}

// findField find structField in rType
//
// return
// 	indexes []int
// 	field reflect.StructField
// 	err error
func findField(name string, typ reflect.Type) ([]int, *reflect.StructField, error) {
	for i := 0; i < typ.NumField(); i++ {
		// matching tag first, then lowerCamelCase, SameCase, lowerCase

		typField := typ.Field(i)

		tagVal, hasTag := typField.Tag.Lookup(tagIdentifier)

		fieldName := typField.Name
		if hasTag && tagVal == name ||
			fieldName == name ||
			lowerCamelCase(fieldName) == name ||
			strings.ToLower(fieldName) == name {

			return []int{i}, &typField, nil
		}

		if typField.Anonymous && typField.Type.Kind() == reflect.Struct {
			next, field, _ := findField(name, typField.Type)
			if len(next) > 0 {
				indexes := []int{i}
				indexes = append(indexes, next...)

				return indexes, field, nil
			}
		}
	}

	return []int{}, nil, perrors.Errorf("failed to find field %s", name)
}

func (d *Decoder) decInstance(typ reflect.Type, cls *classInfo) (interface{}, error) {
	if typ.Kind() != reflect.Struct {
		return nil, perrors.Errorf("wrong type expect Struct but get:%s", typ.String())
	}

	vRef := reflect.New(typ)
	// add pointer ref so that ref the same object
	d.appendRefs(vRef.Interface())

	vv := vRef.Elem()
	for i := 0; i < len(cls.fieldNameList); i++ {
		fieldName := cls.fieldNameList[i]

		index, fieldStruct, err := findFieldWithCache(fieldName, typ)
		if err != nil {
			d.DecodeValue()
			continue
		}

		// skip unexported anonymous field
		if fieldStruct.PkgPath != "" {
			continue
		}

		field := vv.FieldByIndex(index)
		if !field.CanSet() {
			return nil, perrors.Errorf("decInstance CanSet false for field %s", fieldName)
		}

		// get field type from type object, not do that from value
		fldTyp := UnpackPtrType(field.Type())

		// unpack pointer to enable value setting
		fldRawValue := UnpackPtrValue(field)
		kind := fldTyp.Kind()

		switch kind {
		case reflect.String:
			str, err := d.decString(TAG_READ)
			if err != nil {
				return nil, perrors.Wrapf(err, "decInstance->ReadString: %s", fieldName)
			}
			fldRawValue.SetString(str)

		case reflect.Int32, reflect.Int16, reflect.Int8:
			num, err := d.decInt32(TAG_READ)
			if err != nil {
				// java enum
				if fldRawValue.Type().Implements(javaEnumType) {
					d.unreadByte() // Enum parsing, decInt64 above has read a byte, so you need to return a byte here
					s, decErr := d.DecodeValue()
					if decErr != nil {
						return nil, perrors.Wrapf(decErr, "decInstance->decObject field name:%s", fieldName)
					}
					enumValue, _ := s.(JavaEnum)
					num = int32(enumValue)
				} else {
					return nil, perrors.Wrapf(err, "decInstance->decInt32, field name:%s", fieldName)
				}
			}
			fldRawValue.SetInt(int64(num))
		case reflect.Uint16, reflect.Uint8:
			num, err := d.decInt32(TAG_READ)
			if err != nil {
				return nil, perrors.Wrapf(err, "decInstance->decInt32, field name:%s", fieldName)
			}
			fldRawValue.SetUint(uint64(num))
		case reflect.Uint, reflect.Int, reflect.Int64:
			num, err := d.decInt64(TAG_READ)
			if err != nil {
				if fldTyp.Implements(javaEnumType) {
					d.unreadByte() // Enum parsing, decInt64 above has read a byte, so you need to return a byte here
					s, decErr := d.Decode()
					if decErr != nil {
						return nil, perrors.Wrapf(decErr, "decInstance->decObject field name:%s", fieldName)
					}
					enumValue, _ := s.(JavaEnum)
					num = int64(enumValue)
				} else {
					return nil, perrors.Wrapf(err, "decInstance->decInt64 field name:%s", fieldName)
				}
			}

			fldRawValue.SetInt(num)
		case reflect.Uint32, reflect.Uint64:
			num, err := d.decInt64(TAG_READ)
			if err != nil {
				return nil, perrors.Wrapf(err, "decInstance->decInt64, field name:%s", fieldName)
			}
			fldRawValue.SetUint(uint64(num))
		case reflect.Bool:
			b, err := d.Decode()
			if err != nil {
				return nil, perrors.Wrapf(err, "decInstance->Decode field name:%s", fieldName)
			}
			v, ok := b.(bool)
			if !ok {
				return nil, perrors.Wrapf(err, "value convert to bool failed, field name:%s", fieldName)
			}

			if fldRawValue.Kind() == reflect.Ptr && fldRawValue.CanSet() {
				if b != nil {
					field.Set(reflect.ValueOf(&v))
				}
			} else if fldRawValue.Kind() != reflect.Ptr {
				fldRawValue.SetBool(v)
			}

		case reflect.Float32, reflect.Float64:
			num, err := d.decDouble(TAG_READ)
			if err != nil {
				return nil, perrors.Wrapf(err, "decInstance->decDouble field name:%s", fieldName)
			}
			fldRawValue.SetFloat(num.(float64))

		case reflect.Map:
			// decode map should use the original field value for correct value setting
			err := d.decMapByValue(field)
			if err != nil {
				return nil, perrors.Wrapf(err, "decInstance->decMapByValue field name: %s", fieldName)
			}

		case reflect.Slice, reflect.Array:
			m, err := d.decList(TAG_READ)
			if err != nil {
				if err == io.EOF {
					break
				}
				return nil, perrors.WithStack(err)
			}

			// set slice separately
			err = SetSlice(fldRawValue, m)
			if err != nil {
				return nil, err
			}
		case reflect.Struct:
			var (
				err error
				s   interface{}
			)
			fldType := UnpackPtrType(fldRawValue.Type())
			if fldType.String() == "time.Time" {
				s, err = d.decDate(TAG_READ)
				if err != nil {
					return nil, perrors.WithStack(err)
				}
				SetValue(fldRawValue, EnsurePackValue(s))
			} else {
				s, err = d.decObject(TAG_READ)
				if err != nil {
					return nil, perrors.WithStack(err)
				}
				if s != nil {
					// set value which accepting pointers
					SetValue(fldRawValue, EnsurePackValue(s))
				}
			}
		case reflect.Interface:
			s, err := d.DecodeValue()
			if err != nil {
				return nil, perrors.WithStack(err)
			}
			if s != nil {
				if ref, ok := s.(*_refHolder); ok {
					_ = unpackRefHolder(fldRawValue, fldTyp, ref)
				} else {
					// set value which accepting pointers
					SetValue(fldRawValue, EnsurePackValue(s))
				}
			}
		default:
			return nil, perrors.Errorf("unknown struct member type: %v %v", kind, typ.Name()+"."+fieldStruct.Name)
		}
	} // end for

	return vRef.Interface(), nil
}

func (d *Decoder) appendClsDef(cd *classInfo) {
	d.classInfoList = append(d.classInfoList, cd)
}

func (d *Decoder) getStructDefByIndex(idx int) (reflect.Type, *classInfo, error) {
	var (
		ok  bool
		cls *classInfo
		s   *structInfo
		err error
	)

	if len(d.classInfoList) <= idx || idx < 0 {
		return nil, cls, perrors.Errorf("illegal class index @idx %d", idx)
	}
	cls = d.classInfoList[idx]
	s, ok = getStructInfo(cls.javaName)
	if !ok {
		// exception
		if s, ok = checkAndGetException(cls); ok {
			return s.typ, cls, nil
		}
		if !d.isSkip {
			err = perrors.Errorf("can not find go type name %s in registry", cls.javaName)
		}
		return nil, cls, err
	}

	return s.typ, cls, nil
}

func (d *Decoder) decEnum(javaName string, flag int32) (JavaEnum, error) {
	var (
		err       error
		enumName  string
		ok        bool
		info      *structInfo
		enumValue JavaEnum
	)
	enumName, err = d.decString(TAG_READ) // java enum class member is "name"
	if err != nil {
		return InvalidJavaEnum, perrors.Wrap(err, "decString for decJavaEnum")
	}
	info, ok = getStructInfo(javaName)
	if !ok {
		return InvalidJavaEnum, perrors.Errorf("getStructInfo(javaName:%s) = false", javaName)
	}

	enumValue = info.inst.(POJOEnum).EnumValue(enumName)
	d.appendRefs(enumValue)
	return enumValue, nil
}

// skip this object
func (d *Decoder) skip(cls *classInfo) error {
	len := len(cls.fieldNameList)
	if len < 1 {
		return nil
	}

	for i := 0; i < len; i++ {
		// skip class fields.
		if _, err := d.DecodeValue(); err != nil {
			return err
		}
	}

	return nil
}

func (d *Decoder) decObject(flag int32) (interface{}, error) {
	var (
		tag byte
		idx int32
		err error
		typ reflect.Type
		cls *classInfo
	)

	if flag != TAG_READ {
		tag = byte(flag)
	} else {
		tag, _ = d.ReadByte()
	}

	switch {
	case tag == BC_NULL:
		return nil, nil
	case tag == BC_REF:
		return d.decRef(int32(tag))
	case tag == BC_OBJECT_DEF:
		clsDef, decErr := d.decClassDef()
		if decErr != nil {
			return nil, perrors.Wrap(decErr, "decObject->decClassDef byte double")
		}
		cls, _ = clsDef.(*classInfo)
		// add to slice
		d.appendClsDef(cls)

		return d.DecodeValue()

	case tag == BC_OBJECT:
		idx, err = d.decInt32(TAG_READ)
		if err != nil {
			return nil, err
		}

		typ, cls, err = d.getStructDefByIndex(int(idx))
		if err != nil {
			return nil, err
		}
		if typ == nil {
			return nil, d.skip(cls)
		}
		if typ.Implements(javaEnumType) {
			return d.decEnum(cls.javaName, TAG_READ)
		}

		if c, ok := GetSerializer(cls.javaName); ok {
			return c.DecObject(d, typ, cls)
		}

		return d.decInstance(typ, cls)

	case BC_OBJECT_DIRECT <= tag && tag <= (BC_OBJECT_DIRECT+OBJECT_DIRECT_MAX):
		typ, cls, err = d.getStructDefByIndex(int(tag - BC_OBJECT_DIRECT))
		if err != nil {
			return nil, err
		}
		if typ == nil {
			return nil, d.skip(cls)
		}
		if typ.Implements(javaEnumType) {
			return d.decEnum(cls.javaName, TAG_READ)
		}

		if c, ok := GetSerializer(cls.javaName); ok {
			return c.DecObject(d, typ, cls)
		}

		return d.decInstance(typ, cls)

	default:
		return nil, perrors.Errorf("decObject illegal object type tag:%+v", tag)
	}
}
