package jsoniter

import (
	"encoding/json"
	"io"
	"math/big"
	"strconv"
	"strings"
	"unsafe"
)

var floatDigits []int8

const invalidCharForNumber = int8(-1)
const endOfNumber = int8(-2)
const dotInNumber = int8(-3)

func init() {
	floatDigits = make([]int8, 256)
	for i := 0; i < len(floatDigits); i++ {
		floatDigits[i] = invalidCharForNumber
	}
	for i := int8('0'); i <= int8('9'); i++ {
		floatDigits[i] = i - int8('0')
	}
	floatDigits[','] = endOfNumber
	floatDigits[']'] = endOfNumber
	floatDigits['}'] = endOfNumber
	floatDigits[' '] = endOfNumber
	floatDigits['\t'] = endOfNumber
	floatDigits['\n'] = endOfNumber
	floatDigits['.'] = dotInNumber
}

// ReadBigFloat read big.Float
func (iter *Iterator) ReadBigFloat() (ret *big.Float) {
	str := iter.readNumberAsString()
	if iter.Error != nil && iter.Error != io.EOF {
		return nil
	}
	prec := 64
	if len(str) > prec {
		prec = len(str)
	}
	val, _, err := big.ParseFloat(str, 10, uint(prec), big.ToZero)
	if err != nil {
		iter.Error = err
		return nil
	}
	return val
}

// ReadBigInt read big.Int
func (iter *Iterator) ReadBigInt() (ret *big.Int) {
	str := iter.readNumberAsString()
	if iter.Error != nil && iter.Error != io.EOF {
		return nil
	}
	ret = big.NewInt(0)
	var success bool
	ret, success = ret.SetString(str, 10)
	if !success {
		iter.ReportError("ReadBigInt", "invalid big int")
		return nil
	}
	return ret
}

//ReadFloat32 read float32
func (iter *Iterator) ReadFloat32() (ret float32) {
	c := iter.nextToken()
	if c == '-' {
		return -iter.readPositiveFloat32()
	}
	iter.unreadByte()
	return iter.readPositiveFloat32()
}

func (iter *Iterator) readPositiveFloat32() (ret float32) {
	value := uint64(0)
	c := byte(' ')
	i := iter.head
	// first char
	if i == iter.tail {
		return iter.readFloat32SlowPath()
	}
	c = iter.buf[i]
	i++
	ind := floatDigits[c]
	switch ind {
	case invalidCharForNumber:
		return iter.readFloat32SlowPath()
	case endOfNumber:
		iter.ReportError("readFloat32", "empty number")
		return
	case dotInNumber:
		iter.ReportError("readFloat32", "leading dot is invalid")
		return
	case 0:
		if i == iter.tail {
			return iter.readFloat32SlowPath()
		}
		c = iter.buf[i]
		switch c {
		case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
			iter.ReportError("readFloat32", "leading zero is invalid")
			return
		}
	}
	value = uint64(ind)
	// chars before dot
non_decimal_loop:
	for ; i < iter.tail; i++ {
		c = iter.buf[i]
		ind := floatDigits[c]
		switch ind {
		case invalidCharForNumber:
			return iter.readFloat32SlowPath()
		case endOfNumber:
			iter.head = i
			return float32(value)
		case dotInNumber:
			break non_decimal_loop
		}
		if value > uint64SafeToMultiple10 {
			return iter.readFloat32SlowPath()
		}
		value = (value << 3) + (value << 1) + uint64(ind) // value = value * 10 + ind;
	}
	// chars after dot
	if c == '.' {
		i++
		decimalPlaces := 0
		if i == iter.tail {
			return iter.readFloat32SlowPath()
		}
		for ; i < iter.tail; i++ {
			c = iter.buf[i]
			ind := floatDigits[c]
			switch ind {
			case endOfNumber:
				if decimalPlaces > 0 && decimalPlaces < len(pow10) {
					iter.head = i
					return float32(float64(value) / float64(pow10[decimalPlaces]))
				}
				// too many decimal places
				return iter.readFloat32SlowPath()
			case invalidCharForNumber:
				fallthrough
			case dotInNumber:
				return iter.readFloat32SlowPath()
			}
			decimalPlaces++
			if value > uint64SafeToMultiple10 {
				return iter.readFloat32SlowPath()
			}
			value = (value << 3) + (value << 1) + uint64(ind)
		}
	}
	return iter.readFloat32SlowPath()
}

func (iter *Iterator) readNumberAsString() (ret string) {
	strBuf := [16]byte{}
	str := strBuf[0:0]
load_loop:
	for {
		for i := iter.head; i < iter.tail; i++ {
			c := iter.buf[i]
			switch c {
			case '+', '-', '.', 'e', 'E', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
				str = append(str, c)
				continue
			default:
				iter.head = i
				break load_loop
			}
		}
		if !iter.loadMore() {
			break
		}
	}
	if iter.Error != nil && iter.Error != io.EOF {
		return
	}
	if len(str) == 0 {
		iter.ReportError("readNumberAsString", "invalid number")
	}
	return *(*string)(unsafe.Pointer(&str))
}

func (iter *Iterator) readFloat32SlowPath() (ret float32) {
	str := iter.readNumberAsString()
	if iter.Error != nil && iter.Error != io.EOF {
		return
	}
	errMsg := validateFloat(str)
	if errMsg != "" {
		iter.ReportError("readFloat32SlowPath", errMsg)
		return
	}
	val, err := strconv.ParseFloat(str, 32)
	if err != nil {
		iter.Error = err
		return
	}
	return float32(val)
}

// ReadFloat64 read float64
func (iter *Iterator) ReadFloat64() (ret float64) {
	c := iter.nextToken()
	if c == '-' {
		return -iter.readPositiveFloat64()
	}
	iter.unreadByte()
	return iter.readPositiveFloat64()
}

func (iter *Iterator) readPositiveFloat64() (ret float64) {
	value := uint64(0)
	c := byte(' ')
	i := iter.head
	// first char
	if i == iter.tail {
		return iter.readFloat64SlowPath()
	}
	c = iter.buf[i]
	i++
	ind := floatDigits[c]
	switch ind {
	case invalidCharForNumber:
		return iter.readFloat64SlowPath()
	case endOfNumber:
		iter.ReportError("readFloat64", "empty number")
		return
	case dotInNumber:
		iter.ReportError("readFloat64", "leading dot is invalid")
		return
	case 0:
		if i == iter.tail {
			return iter.readFloat64SlowPath()
		}
		c = iter.buf[i]
		switch c {
		case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
			iter.ReportError("readFloat64", "leading zero is invalid")
			return
		}
	}
	value = uint64(ind)
	// chars before dot
non_decimal_loop:
	for ; i < iter.tail; i++ {
		c = iter.buf[i]
		ind := floatDigits[c]
		switch ind {
		case invalidCharForNumber:
			return iter.readFloat64SlowPath()
		case endOfNumber:
			iter.head = i
			return float64(value)
		case dotInNumber:
			break non_decimal_loop
		}
		if value > uint64SafeToMultiple10 {
			return iter.readFloat64SlowPath()
		}
		value = (value << 3) + (value << 1) + uint64(ind) // value = value * 10 + ind;
	}
	// chars after dot
	if c == '.' {
		i++
		decimalPlaces := 0
		if i == iter.tail {
			return iter.readFloat64SlowPath()
		}
		for ; i < iter.tail; i++ {
			c = iter.buf[i]
			ind := floatDigits[c]
			switch ind {
			case endOfNumber:
				if decimalPlaces > 0 && decimalPlaces < len(pow10) {
					iter.head = i
					return float64(value) / float64(pow10[decimalPlaces])
				}
				// too many decimal places
				return iter.readFloat64SlowPath()
			case invalidCharForNumber:
				fallthrough
			case dotInNumber:
				return iter.readFloat64SlowPath()
			}
			decimalPlaces++
			if value > uint64SafeToMultiple10 {
				return iter.readFloat64SlowPath()
			}
			value = (value << 3) + (value << 1) + uint64(ind)
		}
	}
	return iter.readFloat64SlowPath()
}

func (iter *Iterator) readFloat64SlowPath() (ret float64) {
	str := iter.readNumberAsString()
	if iter.Error != nil && iter.Error != io.EOF {
		return
	}
	errMsg := validateFloat(str)
	if errMsg != "" {
		iter.ReportError("readFloat64SlowPath", errMsg)
		return
	}
	val, err := strconv.ParseFloat(str, 64)
	if err != nil {
		iter.Error = err
		return
	}
	return val
}

func validateFloat(str string) string {
	// strconv.ParseFloat is not validating `1.` or `1.e1`
	if len(str) == 0 {
		return "empty number"
	}
	if str[0] == '-' {
		return "-- is not valid"
	}
	dotPos := strings.IndexByte(str, '.')
	if dotPos != -1 {
		if dotPos == len(str)-1 {
			return "dot can not be last character"
		}
		switch str[dotPos+1] {
		case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
		default:
			return "missing digit after dot"
		}
	}
	return ""
}

// ReadNumber read json.Number
func (iter *Iterator) ReadNumber() (ret json.Number) {
	return json.Number(iter.readNumberAsString())
}
