/*
 * 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 (
	"encoding/binary"
	"math"
	"strconv"
)

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

/////////////////////////////////////////
// Double
/////////////////////////////////////////

// # 64-bit IEEE double
// ::= 'D' b7 b6 b5 b4 b3 b2 b1 b0
// ::= x5b                   # 0.0
// ::= x5c                   # 1.0
// ::= x5d b0                # byte cast to double (-128.0 to 127.0)
// ::= x5e b1 b0             # short cast to double
// ::= x5f b3 b2 b1 b0       # 32-bit float cast to double
func encFloat(b []byte, v float64) []byte {
	fv := float64(int64(v))
	if fv == v {
		iv := int64(v)
		switch iv {
		case 0:
			return encByte(b, BC_DOUBLE_ZERO)
		case 1:
			return encByte(b, BC_DOUBLE_ONE)
		}
		if iv >= -0x80 && iv < 0x80 {
			return encByte(b, BC_DOUBLE_BYTE, byte(iv))
		} else if iv >= -0x8000 && iv < 0x8000 {
			return encByte(b, BC_DOUBLE_SHORT, byte(iv>>8), byte(iv))
		}

		goto END
	}

END:
	bits := math.Float64bits(v)
	return encByte(b, BC_DOUBLE, byte(bits>>56), byte(bits>>48), byte(bits>>40),
		byte(bits>>32), byte(bits>>24), byte(bits>>16), byte(bits>>8), byte(bits))
}

func encFloat32(b []byte, v float32) []byte {
	fv := float32(int32(v))
	if fv == v {
		iv := int32(v)
		switch iv {
		case 0:
			return encByte(b, BC_DOUBLE_ZERO)
		case 1:
			return encByte(b, BC_DOUBLE_ONE)
		}
		if iv >= -0x80 && iv < 0x80 {
			return encByte(b, BC_DOUBLE_BYTE, byte(iv))
		} else if iv >= -0x8000 && iv < 0x8000 {
			return encByte(b, BC_DOUBLE_SHORT, byte(iv>>8), byte(iv))
		}

		goto END
	}

END:
	if float32(int32(v*1000)) == v*1000 {
		iv := int32(v * 1000)
		return encByte(b, BC_DOUBLE_MILL, byte(iv>>24), byte(iv>>16), byte(iv>>8), byte(iv))
	} else {
		str := strconv.FormatFloat(float64(v), 'f', -1, 32)
		d, _ := strconv.ParseFloat(str, 64)
		bits := math.Float64bits(d)
		return encByte(b, BC_DOUBLE, byte(bits>>56), byte(bits>>48), byte(bits>>40),
			byte(bits>>32), byte(bits>>24), byte(bits>>16), byte(bits>>8), byte(bits))
	}
}

/////////////////////////////////////////
// Double
/////////////////////////////////////////

// # 64-bit IEEE double
// ::= 'D' b7 b6 b5 b4 b3 b2 b1 b0
// ::= x5b                   # 0.0
// ::= x5c                   # 1.0
// ::= x5d b0                # byte cast to double (-128.0 to 127.0)
// ::= x5e b1 b0             # short cast to double
// ::= x5f b3 b2 b1 b0       # 32-bit float cast to double
func (d *Decoder) decDouble(flag int32) (interface{}, error) {
	var (
		err error
		tag byte
	)

	if flag != TAG_READ {
		tag = byte(flag)
	} else {
		tag, _ = d.ReadByte()
	}
	switch tag {
	case BC_LONG_INT:
		return d.decInt32(TAG_READ)

	case BC_DOUBLE_ZERO:
		return float64(0), nil

	case BC_DOUBLE_ONE:
		return float64(1), nil

	case BC_DOUBLE_BYTE:
		var i8 int8
		err = binary.Read(d.reader, binary.BigEndian, &i8)
		return float64(i8), perrors.WithStack(err)

	case BC_DOUBLE_SHORT:
		var i16 int16
		err = binary.Read(d.reader, binary.BigEndian, &i16)
		return float64(i16), perrors.WithStack(err)

	case BC_DOUBLE_MILL:
		var i32 int32
		err = binary.Read(d.reader, binary.BigEndian, &i32)
		return float64(i32) / 1000, perrors.WithStack(err)

	case BC_DOUBLE:
		var f64 float64
		err = binary.Read(d.reader, binary.BigEndian, &f64)
		return f64, perrors.WithStack(err)
	}

	return nil, perrors.Errorf("decDouble parse double wrong tag:%d-%#x", int(tag), tag)
}
