// Copyright 2016 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.

//go:generate go run gen.go gen_common.go

// Package plural provides utilities for handling linguistic plurals in text.
//
// The definitions in this package are based on the plural rule handling defined
// in CLDR. See
// http://unicode.org/reports/tr35/tr35-numbers.html#Language_Plural_Rules for
// details.
package plural

import (
	"golang.org/x/text/internal/number"
	"golang.org/x/text/language"
)

// Rules defines the plural rules for all languages for a certain plural type.
//
//
// This package is UNDER CONSTRUCTION and its API may change.
type Rules struct {
	rules          []pluralCheck
	index          []byte
	langToIndex    []byte
	inclusionMasks []uint64
}

var (
	// Cardinal defines the plural rules for numbers indicating quantities.
	Cardinal *Rules = cardinal

	// Ordinal defines the plural rules for numbers indicating position
	// (first, second, etc.).
	Ordinal *Rules = ordinal

	ordinal = &Rules{
		ordinalRules,
		ordinalIndex,
		ordinalLangToIndex,
		ordinalInclusionMasks[:],
	}

	cardinal = &Rules{
		cardinalRules,
		cardinalIndex,
		cardinalLangToIndex,
		cardinalInclusionMasks[:],
	}
)

// getIntApprox converts the digits in slice digits[start:end] to an integer
// according to the following rules:
//	- Let i be asInt(digits[start:end]), where out-of-range digits are assumed
//	  to be zero.
//	- Result n is big if i / 10^nMod > 1.
//	- Otherwise the result is i % 10^nMod.
//
// For example, if digits is {1, 2, 3} and start:end is 0:5, then the result
// for various values of nMod is:
//	- when nMod == 2, n == big
//	- when nMod == 3, n == big
//	- when nMod == 4, n == big
//	- when nMod == 5, n == 12300
//	- when nMod == 6, n == 12300
//	- when nMod == 7, n == 12300
func getIntApprox(digits []byte, start, end, nMod, big int) (n int) {
	// Leading 0 digits just result in 0.
	p := start
	if p < 0 {
		p = 0
	}
	// Range only over the part for which we have digits.
	mid := end
	if mid >= len(digits) {
		mid = len(digits)
	}
	// Check digits more significant that nMod.
	if q := end - nMod; q > 0 {
		if q > mid {
			q = mid
		}
		for ; p < q; p++ {
			if digits[p] != 0 {
				return big
			}
		}
	}
	for ; p < mid; p++ {
		n = 10*n + int(digits[p])
	}
	// Multiply for trailing zeros.
	for ; p < end; p++ {
		n *= 10
	}
	return n
}

// MatchDigits computes the plural form for the given language and the given
// decimal floating point digits. The digits are stored in big-endian order and
// are of value byte(0) - byte(9). The floating point position is indicated by
// exp and the number of visible decimals is scale. All leading and trailing
// zeros may be omitted from digits.
//
// The following table contains examples of possible arguments to represent
// the given numbers.
//      decimal    digits              exp    scale
//      123        []byte{1, 2, 3}     3      0
//      123.4      []byte{1, 2, 3, 4}  3      1
//      123.40     []byte{1, 2, 3, 4}  3      2
//      100000     []byte{1}           6      0
//      100000.00  []byte{1}           6      3
func (p *Rules) MatchDigits(t language.Tag, digits []byte, exp, scale int) Form {
	index, _ := language.CompactIndex(t)

	// Differentiate up to including mod 1000000 for the integer part.
	n := getIntApprox(digits, 0, exp, 6, 1000000)

	// Differentiate up to including mod 100 for the fractional part.
	f := getIntApprox(digits, exp, exp+scale, 2, 100)

	return matchPlural(p, index, n, f, scale)
}

func (p *Rules) matchDisplayDigits(t language.Tag, d *number.Digits) (Form, int) {
	n := getIntApprox(d.Digits, 0, int(d.Exp), 6, 1000000)
	return p.MatchDigits(t, d.Digits, int(d.Exp), d.NumFracDigits()), n
}

func validForms(p *Rules, t language.Tag) (forms []Form) {
	index, _ := language.CompactIndex(t)
	offset := p.langToIndex[index]
	rules := p.rules[p.index[offset]:p.index[offset+1]]

	forms = append(forms, Other)
	last := Other
	for _, r := range rules {
		if cat := Form(r.cat & formMask); cat != andNext && last != cat {
			forms = append(forms, cat)
			last = cat
		}
	}
	return forms
}

func (p *Rules) matchComponents(t language.Tag, n, f, scale int) Form {
	index, _ := language.CompactIndex(t)
	return matchPlural(p, index, n, f, scale)
}

// MatchPlural returns the plural form for the given language and plural
// operands (as defined in
// http://unicode.org/reports/tr35/tr35-numbers.html#Language_Plural_Rules):
//  where
//  	n  absolute value of the source number (integer and decimals)
//  input
//  	i  integer digits of n.
//  	v  number of visible fraction digits in n, with trailing zeros.
//  	w  number of visible fraction digits in n, without trailing zeros.
//  	f  visible fractional digits in n, with trailing zeros (f = t * 10^(v-w))
//  	t  visible fractional digits in n, without trailing zeros.
//
// If any of the operand values is too large to fit in an int, it is okay to
// pass the value modulo 10,000,000.
func (p *Rules) MatchPlural(lang language.Tag, i, v, w, f, t int) Form {
	index, _ := language.CompactIndex(lang)
	return matchPlural(p, index, i, f, v)
}

func matchPlural(p *Rules, index int, n, f, v int) Form {
	nMask := p.inclusionMasks[n%maxMod]
	// Compute the fMask inline in the rules below, as it is relatively rare.
	// fMask := p.inclusionMasks[f%maxMod]
	vMask := p.inclusionMasks[v%maxMod]

	// Do the matching
	offset := p.langToIndex[index]
	rules := p.rules[p.index[offset]:p.index[offset+1]]
	for i := 0; i < len(rules); i++ {
		rule := rules[i]
		setBit := uint64(1 << rule.setID)
		var skip bool
		switch op := opID(rule.cat >> opShift); op {
		case opI: // i = x
			skip = n >= numN || nMask&setBit == 0

		case opI | opNotEqual: // i != x
			skip = n < numN && nMask&setBit != 0

		case opI | opMod: // i % m = x
			skip = nMask&setBit == 0

		case opI | opMod | opNotEqual: // i % m != x
			skip = nMask&setBit != 0

		case opN: // n = x
			skip = f != 0 || n >= numN || nMask&setBit == 0

		case opN | opNotEqual: // n != x
			skip = f == 0 && n < numN && nMask&setBit != 0

		case opN | opMod: // n % m = x
			skip = f != 0 || nMask&setBit == 0

		case opN | opMod | opNotEqual: // n % m != x
			skip = f == 0 && nMask&setBit != 0

		case opF: // f = x
			skip = f >= numN || p.inclusionMasks[f%maxMod]&setBit == 0

		case opF | opNotEqual: // f != x
			skip = f < numN && p.inclusionMasks[f%maxMod]&setBit != 0

		case opF | opMod: // f % m = x
			skip = p.inclusionMasks[f%maxMod]&setBit == 0

		case opF | opMod | opNotEqual: // f % m != x
			skip = p.inclusionMasks[f%maxMod]&setBit != 0

		case opV: // v = x
			skip = v < numN && vMask&setBit == 0

		case opV | opNotEqual: // v != x
			skip = v < numN && vMask&setBit != 0

		case opW: // w == 0
			skip = f != 0

		case opW | opNotEqual: // w != 0
			skip = f == 0

		// Hard-wired rules that cannot be handled by our algorithm.

		case opBretonM:
			skip = f != 0 || n == 0 || n%1000000 != 0

		case opAzerbaijan00s:
			// 100,200,300,400,500,600,700,800,900
			skip = n == 0 || n >= 1000 || n%100 != 0

		case opItalian800:
			skip = (f != 0 || n >= numN || nMask&setBit == 0) && n != 800
		}
		if skip {
			// advance over AND entries.
			for ; i < len(rules) && rules[i].cat&formMask == andNext; i++ {
			}
			continue
		}
		// return if we have a final entry.
		if cat := rule.cat & formMask; cat != andNext {
			return Form(cat)
		}
	}
	return Other
}
