// Copyright 2016-2019 Alex Stocks, Wongoo
//
// Licensed 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"
	"strconv"
	"strings"
	"sync"
	"time"
)

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

var (
	listTypeNameMapper = &sync.Map{}
	listTypeMapper     = map[string]reflect.Type{
		"string":           reflect.TypeOf(""),
		"java.lang.String": reflect.TypeOf(""),
		"char":             reflect.TypeOf(""),
		"short":            reflect.TypeOf(int32(0)),
		"int":              reflect.TypeOf(int32(0)),
		"long":             reflect.TypeOf(int64(0)),
		"float":            reflect.TypeOf(float64(0)),
		"double":           reflect.TypeOf(float64(0)),
		"boolean":          reflect.TypeOf(true),
		"java.util.Date":   reflect.TypeOf(time.Time{}),
		"date":             reflect.TypeOf(time.Time{}),
		"object":           reflect.TypeOf([]Object{}).Elem(),
		"java.lang.Object": reflect.TypeOf([]Object{}).Elem(),
	}
)

func init() {
	listTypeNameMapper.Store("string", "[string")
	listTypeNameMapper.Store("int8", "[short")
	listTypeNameMapper.Store("int16", "[short")
	listTypeNameMapper.Store("uint16", "[short")
	listTypeNameMapper.Store("int32", "[int")
	listTypeNameMapper.Store("uint32", "[int")
	listTypeNameMapper.Store("int", "[long")
	listTypeNameMapper.Store("uint", "[long")
	listTypeNameMapper.Store("int64", "[long")
	listTypeNameMapper.Store("uint64", "[long")
	listTypeNameMapper.Store("float32", "[float")
	listTypeNameMapper.Store("float64", "[double")
	listTypeNameMapper.Store("bool", "[boolean")
	listTypeNameMapper.Store("time.Time", "[date")
	listTypeNameMapper.Store("java_exception.Throwabler", "[java.lang.Throwable")

	listTypeNameMapper.Store("hessian.Object", "[object")
}

func registerTypeName(gotype, javatype string) {
	listTypeNameMapper.Store(gotype, "["+javatype)
}

func getListTypeName(gotype string) string {
	buf := strings.Builder{}
	count := strings.Count(gotype, "[]")
	for i := 0; i < count; i++ {
		buf.WriteString("[")
	}
	gotype = strings.Replace(gotype, "[]", "", -1)
	v, ok := listTypeNameMapper.Load(strings.TrimPrefix(gotype, "*"))
	if ok {
		buf.WriteString(v.(string))
		return buf.String()
	}
	return ""
}

func getListType(javalistname string) reflect.Type {
	javaname := javalistname
	if strings.Index(javaname, "[") == 0 {
		javaname = javaname[1:]
	}
	if strings.Index(javaname, "[") == 0 {
		lt := getListType(javaname)
		if lt == nil {
			return nil
		}
		return reflect.SliceOf(lt)
	}

	var sliceTy reflect.Type
	ltm := listTypeMapper[javaname]
	if ltm != nil {
		sliceTy = reflect.SliceOf(ltm)
	}

	if sliceTy == nil {
		tpStructInfo, _ := getStructInfo(javaname)
		tp := tpStructInfo.typ
		if tp == nil {
			return nil
		}
		if tp.Kind() != reflect.Ptr {
			tp = reflect.New(tp).Type()
		}
		sliceTy = reflect.SliceOf(tp)
	}
	return sliceTy
}

// Object is equal to Object of java When encoding
type Object interface{}

/////////////////////////////////////////
// List
/////////////////////////////////////////

// encList write list
func (e *Encoder) encList(v interface{}) error {
	if !strings.Contains(reflect.TypeOf(v).String(), "interface {}") {
		return e.writeTypedList(v)
	}
	return e.writeUntypedList(v)
}

// writeTypedList write typed list
// Include 3 formats:
// ::= x55 type value* 'Z'   # variable-length list
// ::= 'V' type int value*   # fixed-length list
// ::= [x70-77] type value*  # fixed-length typed list
func (e *Encoder) writeTypedList(v interface{}) error {
	var (
		err error
	)

	value := reflect.ValueOf(v)

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

	value = UnpackPtrValue(value)
	totype := UnpackPtrType(value.Type().Elem()).String()
	var typeName = getListTypeName(totype)
	if typeName == "" {
		return perrors.New("no this type name: " + totype)
	}

	e.buffer = encByte(e.buffer, BC_LIST_FIXED) // 'V'
	e.buffer = encString(e.buffer, typeName)
	e.buffer = encInt32(e.buffer, int32(value.Len()))
	for i := 0; i < value.Len(); i++ {
		if err = e.Encode(value.Index(i).Interface()); err != nil {
			return err
		}
	}

	return nil
}

// writeUntypedList write untyped list
// Include 3 formats:
// ::= x57 value* 'Z'        # variable-length untyped list
// ::= x58 int value*        # fixed-length untyped list
// ::= [x78-7f] value*       # fixed-length untyped list
func (e *Encoder) writeUntypedList(v interface{}) error {
	var (
		err error
	)

	value := reflect.ValueOf(v)

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

	value = UnpackPtrValue(value)

	e.buffer = encByte(e.buffer, BC_LIST_FIXED_UNTYPED) // x58
	e.buffer = encInt32(e.buffer, int32(value.Len()))
	for i := 0; i < value.Len(); i++ {
		if err = e.Encode(value.Index(i).Interface()); err != nil {
			return err
		}
	}

	return nil
}

/////////////////////////////////////////
// List
/////////////////////////////////////////

// # list/vector
// ::= x55 type value* 'Z'   # variable-length list
// ::= 'V' type int value*   # fixed-length list
// ::= x57 value* 'Z'        # variable-length untyped list
// ::= x58 int value*        # fixed-length untyped list
// ::= [x70-77] type value*  # fixed-length typed list
// ::= [x78-7f] value*       # fixed-length untyped list

func (d *Decoder) readBufByte() (byte, error) {
	var (
		err error
		buf [1]byte
	)

	_, err = io.ReadFull(d.reader, buf[:1])
	if err != nil {
		return 0, perrors.WithStack(err)
	}

	return buf[0], nil
}

func listFixedTypedLenTag(tag byte) bool {
	return tag >= _listFixedTypedLenTagMin && tag <= _listFixedTypedLenTagMax
}

// Include 3 formats:
// list ::= x55 type value* 'Z'   # variable-length list
//      ::= 'V' type int value*   # fixed-length list
//      ::= [x70-77] type value*  # fixed-length typed list
func typedListTag(tag byte) bool {
	return tag == BC_LIST_FIXED || tag == BC_LIST_VARIABLE || listFixedTypedLenTag(tag)
}

func listFixedUntypedLenTag(tag byte) bool {
	return tag >= _listFixedUntypedLenTagMin && tag <= _listFixedUntypedLenTagMax
}

// Include 3 formats:
//      ::= x57 value* 'Z'        # variable-length untyped list
//      ::= x58 int value*        # fixed-length untyped list
//      ::= [x78-7f] value*       # fixed-length untyped list
func untypedListTag(tag byte) bool {
	return tag == BC_LIST_FIXED_UNTYPED || tag == BC_LIST_VARIABLE_UNTYPED || listFixedUntypedLenTag(tag)
}

//decList read list
func (d *Decoder) decList(flag int32) (interface{}, error) {
	var (
		err error
		tag byte
	)

	if flag != TAG_READ {
		tag = byte(flag)
	} else {
		tag, err = d.readByte()
		if err != nil {
			return nil, perrors.WithStack(err)
		}
	}

	switch {
	case tag == BC_NULL:
		return nil, nil
	case tag == BC_REF:
		return d.decRef(int32(tag))
	case typedListTag(tag):
		return d.readTypedList(tag)
	case untypedListTag(tag):
		return d.readUntypedList(tag)
	default:
		return nil, perrors.Errorf("error list tag: 0x%x", tag)
	}
}

// readTypedList read typed list
// Include 3 formats:
// list ::= x55 type value* 'Z'   # variable-length list
//      ::= 'V' type int value*   # fixed-length list
//      ::= [x70-77] type value*  # fixed-length typed list
func (d *Decoder) readTypedList(tag byte) (interface{}, error) {
	listTyp, err := d.decString(TAG_READ)
	if err != nil {
		return nil, perrors.Errorf("error to read list type[%s]: %v", listTyp, err)
	}

	isVariableArr := tag == BC_LIST_VARIABLE

	length := -1
	if listFixedTypedLenTag(tag) {
		length = int(tag - _listFixedTypedLenTagMin)
	} else if tag == BC_LIST_FIXED {
		ii, err := d.decInt32(TAG_READ)
		if err != nil {
			return nil, perrors.WithStack(err)
		}
		length = int(ii)
	} else if isVariableArr {
		length = 0
	} else {
		return nil, perrors.Errorf("error typed list tag: 0x%x", tag)
	}

	// return when no element
	if length < 0 {
		return nil, nil
	}

	var (
		aryValue reflect.Value
		arrType  reflect.Type
	)
	t, err := strconv.Atoi(listTyp)
	if err == nil {
		arrType = d.typeRefs.Get(t)
	} else {
		arrType = getListType(listTyp)
	}

	if arrType != nil {
		aryValue = reflect.MakeSlice(arrType, length, length)
		d.typeRefs.appendTypeRefs(arrType.String(), arrType)
	} else {
		aryValue = reflect.ValueOf(make([]interface{}, length, length))
		d.typeRefs.appendTypeRefs(strings.Replace(listTyp, "[", "", -1), aryValue.Type())
	}
	holder := d.appendRefs(aryValue)
	for j := 0; j < length || isVariableArr; j++ {
		it, err := d.DecodeValue()
		if err != nil {
			if err == io.EOF && isVariableArr {
				break
			}
			return nil, perrors.WithStack(err)
		}

		if isVariableArr {
			if it != nil {
				aryValue = reflect.Append(aryValue, EnsureRawValue(it))
			} else {
				aryValue = reflect.Append(aryValue, reflect.Zero(aryValue.Type().Elem()))
			}
			holder.change(aryValue)
		} else {
			if it != nil {
				aryValue.Index(j).Set(EnsureRawValue(it))
			} else {
				SetValue(aryValue.Index(j), EnsureRawValue(it))
			}
		}
	}

	return holder, nil
}

//readUntypedList read untyped list
// Include 3 formats:
//      ::= x57 value* 'Z'        # variable-length untyped list
//      ::= x58 int value*        # fixed-length untyped list
//      ::= [x78-7f] value*       # fixed-length untyped list
func (d *Decoder) readUntypedList(tag byte) (interface{}, error) {
	isVariableArr := tag == BC_LIST_VARIABLE_UNTYPED

	var length int
	if listFixedUntypedLenTag(tag) {
		length = int(tag - _listFixedUntypedLenTagMin)
	} else if tag == BC_LIST_FIXED_UNTYPED {
		ii, err := d.decInt32(TAG_READ)
		if err != nil {
			return nil, perrors.WithStack(err)
		}
		length = int(ii)
	} else if isVariableArr {
		length = 0
	} else {
		return nil, perrors.Errorf("error untyped list tag: %x", tag)
	}

	ary := make([]interface{}, length)
	aryValue := reflect.ValueOf(ary)
	holder := d.appendRefs(aryValue)

	for j := 0; j < length || isVariableArr; j++ {
		it, err := d.DecodeValue()
		if err != nil {
			if err == io.EOF && isVariableArr {
				break
			}
			return nil, perrors.WithStack(err)
		}

		if isVariableArr {
			if it != nil {
				aryValue = reflect.Append(aryValue, EnsureRawValue(it))
			} else {
				aryValue = reflect.Append(aryValue, reflect.Zero(aryValue.Type().Elem()))
			}
			holder.change(aryValue)
		} else {
			ary[j] = it
		}
	}

	return holder, nil
}
