// Copyright 2017 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package number

import (
	"strconv"
	"unicode/utf8"

	"golang.org/x/text/language"
)

// TODO:
// - grouping of fractions
// - allow user-defined superscript notation (such as <sup>4</sup>)
// - same for non-breaking spaces, like &nbsp;

// Formatting proceeds along the following lines:
// 0) Compose rounding information from format and context.
// 1) Convert a number into a Decimal.
// 2) Sanitize Decimal by adding trailing zeros, removing leading digits, and
//    (non-increment) rounding. The Decimal that results from this is suitable
//    for determining the plural form.
// 3) Render the Decimal in the localized form.

// Formatter contains all the information needed to render a number.
type Formatter struct {
	Pattern
	Info
	RoundingContext
}

func (f *Formatter) init(t language.Tag, index []uint8) {
	f.Info = InfoFromTag(t)
	for ; ; t = t.Parent() {
		if ci, ok := language.CompactIndex(t); ok {
			f.Pattern = formats[index[ci]]
			break
		}
	}
}

// InitPattern initializes a Formatter for the given Pattern.
func (f *Formatter) InitPattern(t language.Tag, pat *Pattern) {
	f.Info = InfoFromTag(t)
	f.Pattern = *pat
}

// InitDecimal initializes a Formatter using the default Pattern for the given
// language.
func (f *Formatter) InitDecimal(t language.Tag) {
	f.init(t, tagToDecimal)
}

// InitScientific initializes a Formatter using the default Pattern for the
// given language.
func (f *Formatter) InitScientific(t language.Tag) {
	f.init(t, tagToScientific)
}

// InitEngineering initializes a Formatter using the default Pattern for the
// given language.
func (f *Formatter) InitEngineering(t language.Tag) {
	f.init(t, tagToScientific)
	f.Pattern.MaxIntegerDigits = 3
	f.Pattern.MinIntegerDigits = 1
}

// InitPercent initializes a Formatter using the default Pattern for the given
// language.
func (f *Formatter) InitPercent(t language.Tag) {
	f.init(t, tagToPercent)
}

// InitPerMille initializes a Formatter using the default Pattern for the given
// language.
func (f *Formatter) InitPerMille(t language.Tag) {
	f.init(t, tagToPercent)
	f.Pattern.DigitShift = 3
}

func (f *Formatter) Append(dst []byte, x interface{}) []byte {
	var d Decimal
	d.Convert(&f.RoundingContext, x)
	return f.Format(dst, &d)
}

func (f *Formatter) Format(dst []byte, d *Decimal) []byte {
	var result []byte
	var postPrefix, preSuffix int
	if f.MinExponentDigits > 0 {
		result, postPrefix, preSuffix = appendScientific(dst, f, d)
	} else {
		result, postPrefix, preSuffix = appendDecimal(dst, f, d)
	}
	if f.PadRune == 0 {
		return result
	}
	width := int(f.FormatWidth)
	if count := utf8.RuneCount(result); count < width {
		insertPos := 0
		switch f.Flags & PadMask {
		case PadAfterPrefix:
			insertPos = postPrefix
		case PadBeforeSuffix:
			insertPos = preSuffix
		case PadAfterSuffix:
			insertPos = len(result)
		}
		num := width - count
		pad := [utf8.UTFMax]byte{' '}
		sz := 1
		if r := f.PadRune; r != 0 {
			sz = utf8.EncodeRune(pad[:], r)
		}
		extra := sz * num
		if n := len(result) + extra; n < cap(result) {
			result = result[:n]
			copy(result[insertPos+extra:], result[insertPos:])
		} else {
			buf := make([]byte, n)
			copy(buf, result[:insertPos])
			copy(buf[insertPos+extra:], result[insertPos:])
			result = buf
		}
		for ; num > 0; num-- {
			insertPos += copy(result[insertPos:], pad[:sz])
		}
	}
	return result
}

// appendDecimal appends a formatted number to dst. It returns two possible
// insertion points for padding.
func appendDecimal(dst []byte, f *Formatter, d *Decimal) (b []byte, postPre, preSuf int) {
	if dst, ok := f.renderSpecial(dst, d); ok {
		return dst, 0, len(dst)
	}
	n := d.normalize()
	if maxSig := int(f.MaxSignificantDigits); maxSig > 0 {
		n.round(ToZero, maxSig)
	}
	digits := n.Digits
	exp := n.Exp
	exp += int32(f.Pattern.DigitShift)

	// Split in integer and fraction part.
	var intDigits, fracDigits []byte
	var numInt, numFrac int
	if exp > 0 {
		numInt = int(exp)
		if int(exp) >= len(digits) { // ddddd | ddddd00
			intDigits = digits
		} else { // ddd.dd
			intDigits = digits[:exp]
			fracDigits = digits[exp:]
			numFrac = len(fracDigits)
		}
	} else {
		fracDigits = digits
		numFrac = -int(exp) + len(digits)
	}
	// Cap integer digits. Remove *most-significant* digits.
	if f.MaxIntegerDigits > 0 && numInt > int(f.MaxIntegerDigits) {
		offset := numInt - int(f.MaxIntegerDigits)
		if offset > len(intDigits) {
			numInt = 0
			intDigits = nil
		} else {
			numInt = int(f.MaxIntegerDigits)
			intDigits = intDigits[offset:]
			// for keeping track of significant digits
			digits = digits[offset:]
		}
		// Strip leading zeros. Resulting number of digits is significant digits.
		for len(intDigits) > 0 && intDigits[0] == 0 {
			intDigits = intDigits[1:]
			digits = digits[1:]
			numInt--
		}
	}
	if f.MaxSignificantDigits == 0 && int(f.MaxFractionDigits) < numFrac {
		if extra := numFrac - int(f.MaxFractionDigits); extra > len(fracDigits) {
			numFrac = 0
			fracDigits = nil
		} else {
			numFrac = int(f.MaxFractionDigits)
			fracDigits = fracDigits[:len(fracDigits)-extra]
		}
	}

	neg := d.Neg && numInt+numFrac > 0
	affix, suffix := f.getAffixes(neg)
	dst = appendAffix(dst, f, affix, neg)
	savedLen := len(dst)

	minInt := int(f.MinIntegerDigits)
	if minInt == 0 && f.MinSignificantDigits > 0 {
		minInt = 1
	}
	// add leading zeros
	for i := minInt; i > numInt; i-- {
		dst = f.AppendDigit(dst, 0)
		if f.needsSep(i) {
			dst = append(dst, f.Symbol(SymGroup)...)
		}
	}
	i := 0
	for ; i < len(intDigits); i++ {
		dst = f.AppendDigit(dst, intDigits[i])
		if f.needsSep(numInt - i) {
			dst = append(dst, f.Symbol(SymGroup)...)
		}
	}
	for ; i < numInt; i++ {
		dst = f.AppendDigit(dst, 0)
		if f.needsSep(numInt - i) {
			dst = append(dst, f.Symbol(SymGroup)...)
		}
	}

	trailZero := int(f.MinFractionDigits) - numFrac
	if d := int(f.MinSignificantDigits) - len(digits); d > 0 && d > trailZero {
		trailZero = d
	}
	if numFrac > 0 || trailZero > 0 || f.Flags&AlwaysDecimalSeparator != 0 {
		dst = append(dst, f.Symbol(SymDecimal)...)
	}
	// Add leading zeros
	for i := numFrac - len(fracDigits); i > 0; i-- {
		dst = f.AppendDigit(dst, 0)
	}
	i = 0
	for ; i < len(fracDigits); i++ {
		dst = f.AppendDigit(dst, fracDigits[i])
	}
	for ; trailZero > 0; trailZero-- {
		dst = f.AppendDigit(dst, 0)
	}
	// Ensure that at least one digit is written no matter what. This makes
	// things more robust, even though a pattern should always require at least
	// one fraction or integer digit.
	if len(dst) == savedLen {
		dst = f.AppendDigit(dst, 0)
	}
	return appendAffix(dst, f, suffix, neg), savedLen, len(dst)
}

// appendScientific appends a formatted number to dst. It returns two possible
// insertion points for padding.
func appendScientific(dst []byte, f *Formatter, d *Decimal) (b []byte, postPre, preSuf int) {
	if dst, ok := f.renderSpecial(dst, d); ok {
		return dst, 0, 0
	}
	// Significant digits are transformed by parser for scientific notation and
	// do not need to be handled here.
	maxInt, numInt := int(f.MaxIntegerDigits), int(f.MinIntegerDigits)
	if numInt == 0 {
		numInt = 1
	}
	maxSig := int(f.MaxFractionDigits) + numInt
	minSig := int(f.MinFractionDigits) + numInt
	n := d.normalize()
	if maxSig > 0 {
		n.round(ToZero, maxSig)
	}
	digits := n.Digits
	exp := n.Exp

	// If a maximum number of integers is specified, the minimum must be 1
	// and the exponent is grouped by this number (e.g. for engineering)
	if len(digits) == 0 {
		exp = 0
	} else if maxInt > numInt {
		// Correct the exponent to reflect a single integer digit.
		exp--
		numInt = 1
		// engineering
		// 0.01234 ([12345]e-1) -> 1.2345e-2  12.345e-3
		// 12345   ([12345]e+5) -> 1.2345e4  12.345e3
		d := int(exp) % maxInt
		if d < 0 {
			d += maxInt
		}
		exp -= int32(d)
		numInt += d
	} else {
		exp -= int32(numInt)
	}
	var intDigits, fracDigits []byte
	if numInt <= len(digits) {
		intDigits = digits[:numInt]
		fracDigits = digits[numInt:]
	} else {
		intDigits = digits
	}
	neg := d.Neg && len(digits) > 0
	affix, suffix := f.getAffixes(neg)
	dst = appendAffix(dst, f, affix, neg)
	savedLen := len(dst)

	i := 0
	for ; i < len(intDigits); i++ {
		dst = f.AppendDigit(dst, intDigits[i])
		if f.needsSep(numInt - i) {
			dst = append(dst, f.Symbol(SymGroup)...)
		}
	}
	for ; i < numInt; i++ {
		dst = f.AppendDigit(dst, 0)
		if f.needsSep(numInt - i) {
			dst = append(dst, f.Symbol(SymGroup)...)
		}
	}

	trailZero := minSig - numInt - len(fracDigits)
	if len(fracDigits) > 0 || trailZero > 0 || f.Flags&AlwaysDecimalSeparator != 0 {
		dst = append(dst, f.Symbol(SymDecimal)...)
	}
	i = 0
	for ; i < len(fracDigits); i++ {
		dst = f.AppendDigit(dst, fracDigits[i])
	}
	for ; trailZero > 0; trailZero-- {
		dst = f.AppendDigit(dst, 0)
	}
	// Ensure that at least one digit is written no matter what. This makes
	// things more robust, even though a pattern should always require at least
	// one fraction or integer digit.
	if len(dst) == savedLen {
		dst = f.AppendDigit(dst, 0)
	}

	// exp
	buf := [12]byte{}
	// TODO: use exponential if superscripting is not available (no Latin
	// numbers or no tags) and use exponential in all other cases.
	exponential := f.Symbol(SymExponential)
	if exponential == "E" {
		dst = append(dst, "\u202f"...) // NARROW NO-BREAK SPACE
		dst = append(dst, f.Symbol(SymSuperscriptingExponent)...)
		dst = append(dst, "\u202f"...) // NARROW NO-BREAK SPACE
		dst = f.AppendDigit(dst, 1)
		dst = f.AppendDigit(dst, 0)
		switch {
		case exp < 0:
			dst = append(dst, superMinus...)
			exp = -exp
		case f.Flags&AlwaysExpSign != 0:
			dst = append(dst, superPlus...)
		}
		b = strconv.AppendUint(buf[:0], uint64(exp), 10)
		for i := len(b); i < int(f.MinExponentDigits); i++ {
			dst = append(dst, superDigits[0]...)
		}
		for _, c := range b {
			dst = append(dst, superDigits[c-'0']...)
		}
	} else {
		dst = append(dst, exponential...)
		switch {
		case exp < 0:
			dst = append(dst, f.Symbol(SymMinusSign)...)
			exp = -exp
		case f.Flags&AlwaysExpSign != 0:
			dst = append(dst, f.Symbol(SymPlusSign)...)
		}
		b = strconv.AppendUint(buf[:0], uint64(exp), 10)
		for i := len(b); i < int(f.MinExponentDigits); i++ {
			dst = f.AppendDigit(dst, 0)
		}
		for _, c := range b {
			dst = f.AppendDigit(dst, c-'0')
		}
	}
	return appendAffix(dst, f, suffix, neg), savedLen, len(dst)
}

const (
	superMinus = "\u207B" // SUPERSCRIPT HYPHEN-MINUS
	superPlus  = "\u207A" // SUPERSCRIPT PLUS SIGN
)

var (
	// Note: the digits are not sequential!!!
	superDigits = []string{
		"\u2070", // SUPERSCRIPT DIGIT ZERO
		"\u00B9", // SUPERSCRIPT DIGIT ONE
		"\u00B2", // SUPERSCRIPT DIGIT TWO
		"\u00B3", // SUPERSCRIPT DIGIT THREE
		"\u2074", // SUPERSCRIPT DIGIT FOUR
		"\u2075", // SUPERSCRIPT DIGIT FIVE
		"\u2076", // SUPERSCRIPT DIGIT SIX
		"\u2077", // SUPERSCRIPT DIGIT SEVEN
		"\u2078", // SUPERSCRIPT DIGIT EIGHT
		"\u2079", // SUPERSCRIPT DIGIT NINE
	}
)

func (f *Formatter) getAffixes(neg bool) (affix, suffix string) {
	str := f.Affix
	if str != "" {
		if f.NegOffset > 0 {
			if neg {
				str = str[f.NegOffset:]
			} else {
				str = str[:f.NegOffset]
			}
		}
		sufStart := 1 + str[0]
		affix = str[1:sufStart]
		suffix = str[sufStart+1:]
	} else if neg {
		affix = "-"
	}
	return affix, suffix
}

func (f *Formatter) renderSpecial(dst []byte, d *Decimal) (b []byte, ok bool) {
	if d.NaN {
		return fmtNaN(dst, f), true
	}
	if d.Inf {
		return fmtInfinite(dst, f, d), true
	}
	return dst, false
}

func fmtNaN(dst []byte, f *Formatter) []byte {
	return append(dst, f.Symbol(SymNan)...)
}

func fmtInfinite(dst []byte, f *Formatter, d *Decimal) []byte {
	if d.Neg {
		dst = append(dst, f.Symbol(SymMinusSign)...)
	}
	return append(dst, f.Symbol(SymInfinity)...)
}

func appendAffix(dst []byte, f *Formatter, affix string, neg bool) []byte {
	quoting := false
	escaping := false
	for _, r := range affix {
		switch {
		case escaping:
			// escaping occurs both inside and outside of quotes
			dst = append(dst, string(r)...)
			escaping = false
		case r == '\\':
			escaping = true
		case r == '\'':
			quoting = !quoting
		case quoting:
			dst = append(dst, string(r)...)
		case r == '%':
			if f.DigitShift == 3 {
				dst = append(dst, f.Symbol(SymPerMille)...)
			} else {
				dst = append(dst, f.Symbol(SymPercentSign)...)
			}
		case r == '-' || r == '+':
			if neg {
				dst = append(dst, f.Symbol(SymMinusSign)...)
			} else {
				dst = append(dst, f.Symbol(SymPlusSign)...)
			}
		default:
			dst = append(dst, string(r)...)
		}
	}
	return dst
}
