/*
 * 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 (
	"bufio"
	"bytes"
	"fmt"
	"io"
	"reflect"
	"strconv"
	"unicode/utf8"
	"unsafe"
)

import (
	gxbytes "github.com/dubbogo/gost/bytes"
	perrors "github.com/pkg/errors"
)

/////////////////////////////////////////
// String
/////////////////////////////////////////

// Slice convert string to byte slice
func Slice(s string) (b []byte) {
	pbytes := (*reflect.SliceHeader)(unsafe.Pointer(&b))
	pstring := (*reflect.StringHeader)(unsafe.Pointer(&s))
	pbytes.Data = pstring.Data
	pbytes.Len = pstring.Len
	pbytes.Cap = pstring.Len
	return
}

// NOTE: The length of hessian string is the number of 16-bit characters,
// which may be different than the number of bytes.
// String chunks may not split surrogate pairs.
//
// While golang support ucs-4, a rune may exceed 16-bit, which need convert to ucs-2.
//
// ref:
// - https://en.wikipedia.org/wiki/UTF-16
// - https://en.wikipedia.org/wiki/UCS-4
// - http://www.unicode.org/glossary/#code_point
func encodeUcs4Rune(b []byte, r rune) (int, int) {
	if r >= 0x10000 && r <= 0x10FFFF {
		t := uint32(r) - 0x10000
		n := encodeUcs2Rune(b, t>>10+0xD800)
		n += encodeUcs2Rune(b[n:], t&0x3FF+0xDC00)
		return n, 2
	}

	// in fact, a rune over 0x10FFFF can't be encoded by hessian, ignore it currently
	return utf8.EncodeRune(b, r), 1
}

func encodeUcs2Rune(b []byte, ch uint32) int {
	if ch < 0x80 {
		b[0] = byte(ch)
		return 1
	}

	if ch < 0x800 {
		b[0] = byte(0xc0 + ((ch >> 6) & 0x1f))
		b[1] = byte(0x80 + (ch & 0x3f))
		return 2
	}

	b[0] = byte(0xe0 + ((ch >> 12) & 0x0f))
	b[1] = byte(0x80 + ((ch >> 6) & 0x3f))
	b[2] = byte(0x80 + (ch & 0x3f))

	return 3
}

// # UTF-8 encoded character string split into 64k chunks
// ::= x52 b1 b0 <utf8-data> string  # non-final chunk
// ::= 'S' b1 b0 <utf8-data>         # string of length 0-65535
// ::= [x00-x1f] <utf8-data>         # string of length 0-31
// ::= [x30-x34] <utf8-data>         # string of length 0-1023
func encString(b []byte, v string) []byte {
	if v == "" {
		return encByte(b, BC_STRING_DIRECT)
	}

	var (
		byteLen int
		charLen int
		vBuf    = *bytes.NewBufferString(v)

		byteRead  int
		charCount int
		byteCount int
	)

	bufp := gxbytes.AcquireBytes(CHUNK_SIZE * 3)
	defer gxbytes.ReleaseBytes(bufp)
	buf := *bufp

	byteRead = 0
	for {
		if vBuf.Len() <= 0 {
			break
		}

		charCount = 0
		byteCount = 0
		for charCount < CHUNK_SIZE {
			r, _, err := vBuf.ReadRune()
			if err != nil {
				break
			}

			byteLen, charLen = encodeUcs4Rune(buf[byteCount:], r)
			charCount += charLen
			byteCount += byteLen
		}

		if charCount == 0 {
			break
		}

		switch {
		case vBuf.Len() > 0 && charCount >= CHUNK_SIZE:
			b = encByte(b, BC_STRING_CHUNK)
			b = encByte(b, PackUint16(uint16(charCount))...)
		case charCount <= int(STRING_DIRECT_MAX):
			b = encByte(b, byte(charCount+int(BC_STRING_DIRECT)))
		case charCount <= STRING_SHORT_MAX:
			b = encByte(b, byte((charCount>>8)+int(BC_STRING_SHORT)), byte(charCount))
		default:
			b = encByte(b, BC_STRING)
			b = encByte(b, PackUint16(uint16(charCount))...)
		}

		b = append(b, buf[:byteCount]...)

		byteRead = byteRead + byteCount
	}

	return b
}

/////////////////////////////////////////
// String
/////////////////////////////////////////

// # UTF-8 encoded character string split into 64k chunks
// ::= x52 b1 b0 <utf8-data> string  # non-final chunk
// ::= 'S' b1 b0 <utf8-data>         # string of length 0-65535
// ::= [x00-x1f] <utf8-data>         # string of length 0-31
// ::= [x30-x34] <utf8-data>         # string of length 0-1023
func (d *Decoder) getStringLength(tag byte) (int, error) {
	var length int

	switch {
	case tag >= BC_STRING_DIRECT && tag <= STRING_DIRECT_MAX:
		return int(tag - 0x00), nil

	case tag >= 0x30 && tag <= 0x33:
		b, err := d.ReadByte()
		if err != nil {
			return -1, perrors.WithStack(err)
		}

		length = int(tag-0x30)<<8 + int(b)
		return length, nil

	case tag == BC_STRING_CHUNK || tag == BC_STRING:
		b0, err := d.ReadByte()
		if err != nil {
			return -1, perrors.WithStack(err)
		}

		b1, err := d.ReadByte()
		if err != nil {
			return -1, perrors.WithStack(err)
		}

		length = int(b0)<<8 + int(b1)
		return length, nil

	default:
		return -1, perrors.Errorf("string decode: unknown tag %b", tag)
	}
}

func (d *Decoder) decString(flag int32) (string, error) {
	var (
		tag byte
		s   string
	)

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

	switch {
	case tag == BC_NULL:
		return STRING_NIL, nil

	case tag == BC_TRUE:
		return STRING_TRUE, nil

	case tag == BC_FALSE:
		return STRING_FALSE, nil

	case (0x80 <= tag && tag <= 0xbf) || (0xc0 <= tag && tag <= 0xcf) ||
		(0xd0 <= tag && tag <= 0xd7) || tag == BC_INT ||
		(tag >= 0xd8 && tag <= 0xef) || (tag >= 0xf0 && tag <= 0xff) ||
		(tag >= 0x38 && tag <= 0x3f) || (tag == BC_LONG_INT) || (tag == BC_LONG):
		i64, err := d.decInt64(int32(tag))
		if err != nil {
			return "", perrors.Wrapf(err, "tag:%+v", tag)
		}

		return strconv.Itoa(int(i64)), nil

	case tag == BC_DOUBLE_ZERO:
		return STRING_ZERO, nil

	case tag == BC_DOUBLE_ONE:
		return STRING_ONE, nil

	case tag == BC_DOUBLE_BYTE || tag == BC_DOUBLE_SHORT:
		f, err := d.decDouble(int32(tag))
		if err != nil {
			return "", perrors.Wrapf(err, "tag:%+v", tag)
		}

		return strconv.FormatFloat(f.(float64), 'E', -1, 64), nil
	}

	if (tag >= BC_STRING_DIRECT && tag <= STRING_DIRECT_MAX) ||
		(tag >= 0x30 && tag <= 0x33) ||
		(tag == BC_STRING_CHUNK || tag == BC_STRING) {

		if tag != BC_STRING_CHUNK {
			data, err := d.readStringChunkData(tag)
			if err != nil {
				return "", err
			}
			return *(*string)(unsafe.Pointer(&data)), nil
		}

		var chunkDataSlice [][]byte
		dataLength := 0

		for {
			data, err := d.readStringChunkData(tag)
			if err != nil {
				return "", err
			}

			chunkDataSlice = append(chunkDataSlice, data)
			dataLength += len(data)

			// last chunk
			if tag != BC_STRING_CHUNK {
				allData := make([]byte, dataLength)
				index := 0
				for _, b := range chunkDataSlice {
					copy(allData[index:], b)
					index += len(b)
				}
				return *(*string)(unsafe.Pointer(&allData)), nil
			}

			// read next string chunk tag
			tag, _ = d.ReadByte()
			switch {
			case (tag >= BC_STRING_DIRECT && tag <= STRING_DIRECT_MAX) ||
				(tag >= 0x30 && tag <= 0x33) ||
				(tag == BC_STRING_CHUNK || tag == BC_STRING):

			default:
				return s, perrors.New("expect string tag")
			}
		}

	}

	return s, perrors.Errorf("unknown string tag %#x\n", tag)
}

// readStringChunkData read one string chunk data as a utf8 buffer
func (d *Decoder) readStringChunkData(tag byte) ([]byte, error) {
	charTotal, err := d.getStringLength(tag)
	if err != nil {
		return nil, perrors.WithStack(err)
	}

	data := make([]byte, charTotal*3)

	start := 0
	end := 0

	charCount := 0
	charRead := 0

	for charCount < charTotal {
		_, err = io.ReadFull(d.reader, data[end:end+charTotal-charCount])
		if err != nil {
			return nil, err
		}

		end += charTotal - charCount

		start, end, charRead, err = decode2utf8(d.reader, data, start, end)
		if err != nil {
			return nil, err
		}

		charCount += charRead
	}

	return data[:end], nil
}

// decode2utf8 decode hessian2 buffer to utf8 buffer
// parameters:
// - r : the input buffer
// - data: the buffer already read
// - start: the decoding index
// - end: the already read buffer index
// response: updated start, updated end, read char count, error.
func decode2utf8(r *bufio.Reader, data []byte, start, end int) (int, int, int, error) {
	var err error

	charCount := 0

	for start < end {
		ch := data[start]
		if ch < 0x80 {
			start++
			charCount++
			continue
		}

		if start+1 == end {
			data[end], err = r.ReadByte()
			if err != nil {
				return start, end, 0, err
			}
			end++
		}

		if (ch & 0xe0) == 0xc0 {
			start += 2
			charCount++
			continue
		}

		if start+2 == end {
			data[end], err = r.ReadByte()
			if err != nil {
				return start, end, 0, err
			}
			end++
		}

		if (ch & 0xf0) == 0xe0 {
			c1 := ((uint32(ch) & 0x0f) << 12) + ((uint32(data[start+1]) & 0x3f) << 6) + (uint32(data[start+2]) & 0x3f)

			if c1 >= 0xD800 && c1 <= 0xDBFF {
				if start+6 >= end {
					_, err = io.ReadFull(r, data[end:start+6])
					if err != nil {
						return start, end, 0, err
					}
					end = start + 6
				}

				c2 := ((uint32(data[start+3]) & 0x0f) << 12) + ((uint32(data[start+4]) & 0x3f) << 6) + (uint32(data[start+5]) & 0x3f)
				c := (c1-0xD800)<<10 + (c2 - 0xDC00) + 0x10000

				n := utf8.EncodeRune(data[start:], rune(c))
				copy(data[start+n:], data[start+6:end])
				start, end = start+n, end-6+n

				charCount += 2
				continue
			}

			start += 3
			charCount++
			continue
		}

		return start, end, 0, fmt.Errorf("bad utf-8 encoding at %x", ch)
	}

	return start, end, charCount, nil
}
