/*
 * 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 (
	"reflect"
	"time"
	"unsafe"
)

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

// nil bool int8 int32 int64 float32 float64 time.Time
// string []byte []interface{} map[interface{}]interface{}
// array object struct

// Encoder struct
type Encoder struct {
	classInfoList []classInfo
	buffer        []byte
	refMap        map[unsafe.Pointer]_refElem
}

// NewEncoder generate an encoder instance
func NewEncoder() *Encoder {
	var buffer = make([]byte, 64)

	return &Encoder{
		buffer: buffer[:0],
		refMap: make(map[unsafe.Pointer]_refElem, 7),
	}
}

// Buffer returns byte buffer
func (e *Encoder) Buffer() []byte {
	return e.buffer[:]
}

// Append byte arr to encoder buffer
func (e *Encoder) Append(buf []byte) {
	e.buffer = append(e.buffer, buf[:]...)
}

// Encode If @v can not be encoded, the return value is nil. At present only struct may can not be encoded.
func (e *Encoder) Encode(v interface{}) error {
	if v == nil {
		e.buffer = EncNull(e.buffer)
		return nil
	}

	switch val := v.(type) {
	case nil:
		e.buffer = EncNull(e.buffer)
		return nil

	case bool:
		e.buffer = encBool(e.buffer, val)

	case uint8:
		e.buffer = encInt32(e.buffer, int32(val))
	case int8:
		e.buffer = encInt32(e.buffer, int32(val))
	case int16:
		e.buffer = encInt32(e.buffer, int32(val))
	case uint16:
		e.buffer = encInt32(e.buffer, int32(val))
	case int32:
		e.buffer = encInt32(e.buffer, int32(val))
	case uint32:
		e.buffer = encInt64(e.buffer, int64(val))

	case int:
		// if v.(int) >= -2147483648 && v.(int) <= 2147483647 {
		// 	b = encInt32(int32(v.(int)), b)
		// } else {
		// 	b = encInt64(int64(v.(int)), b)
		// }
		// use int64 type to handle int, to avoid  panic like :  reflect: Call using int32 as type int64 [recovered]
		// when decode
		e.buffer = encInt64(e.buffer, int64(val))
	case uint:
		e.buffer = encInt64(e.buffer, int64(val))

	case int64:
		e.buffer = encInt64(e.buffer, val)
	case uint64:
		e.buffer = encInt64(e.buffer, int64(val))

	case time.Time:
		if ZeroDate == val {
			e.buffer = EncNull(e.buffer)
		} else {
			e.buffer = encDateInMs(e.buffer, &val)
			// e.buffer = encDateInMimute(v.(time.Time), e.buffer)
		}

	case float32:
		e.buffer = encFloat32(e.buffer, val)

	case float64:
		e.buffer = encFloat(e.buffer, val)

	case string:
		e.buffer = encString(e.buffer, val)

	case []byte:
		e.buffer = encBinary(e.buffer, val)

	case map[interface{}]interface{}:
		return e.encUntypedMap(val)

	case POJOEnum:
		if p, ok := v.(POJOEnum); ok {
			return e.encObject(p)
		}

	default:
		t := UnpackPtrType(reflect.TypeOf(v))
		switch t.Kind() {
		case reflect.Struct:
			vv := reflect.ValueOf(v)
			vv = UnpackPtr(vv)
			if !vv.IsValid() {
				e.buffer = EncNull(e.buffer)
				return nil
			}
			if vv.Type().String() == "time.Time" {
				e.buffer = encDateInMs(e.buffer, v)
				return nil
			}
			if p, ok := v.(POJO); ok {
				var clazz string
				clazz = p.JavaClassName()
				if c, ok := GetSerializer(clazz); ok {
					return c.EncObject(e, p)
				}
				return e.encObject(p)
			}

			return perrors.Errorf("struct type not Support! %s[%v] is not a instance of POJO!", t.String(), v)
		case reflect.Slice, reflect.Array:
			return e.encList(v)
		case reflect.Map: // the type must be map[string]int
			return e.encMap(v)
		case reflect.Bool:
			vv := v.(*bool)
			if vv != nil {
				e.buffer = encBool(e.buffer, *vv)
			} else {
				e.buffer = encBool(e.buffer, false)
			}
		case reflect.Int32:
			var err error
			e.buffer, err = e.encTypeInt32(e.buffer, v)
			if err != nil {
				return err
			}
		default:
			return perrors.Errorf("type not supported! %s", t.Kind().String())
		}
	}

	return nil
}
