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

package plural

import (
	"fmt"
	"strconv"
	"strings"
	"testing"

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

func TestGetIntApprox(t *testing.T) {
	const big = 1234567890
	testCases := []struct {
		digits string
		start  int
		end    int
		nMod   int
		want   int
	}{
		{"123", 0, 1, 1, 1},
		{"123", 0, 2, 1, big},
		{"123", 0, 2, 2, 12},
		{"123", 3, 4, 2, 0},
		{"12345", 3, 4, 2, 4},

		{"123", 0, 5, 2, big},
		{"123", 0, 5, 3, big},
		{"123", 0, 5, 4, big},
		{"123", 0, 5, 5, 12300},
		{"123", 0, 5, 6, 12300},
		{"123", 0, 5, 7, 12300},

		// Translation of examples in MatchDigits.
		// Integer parts
		{"123", 0, 3, 3, 123},  // 123
		{"1234", 0, 3, 3, 123}, // 123.4
		{"1", 0, 6, 8, 100000}, // 100000

		// Fraction parts
		{"123", 3, 3, 3, 0},   // 123
		{"1234", 3, 4, 3, 4},  // 123.4
		{"1234", 3, 5, 3, 40}, // 123.40
		{"1", 6, 8, 8, 0},     // 100000.00
	}
	for _, tc := range testCases {
		t.Run(fmt.Sprintf("%s:%d:%d/%d", tc.digits, tc.start, tc.end, tc.nMod), func(t *testing.T) {
			got := getIntApprox(mkDigits(tc.digits), tc.start, tc.end, tc.nMod, big)
			if got != tc.want {
				t.Errorf("got %d; want %d", got, tc.want)
			}
		})
	}
}

func mkDigits(s string) []byte {
	b := []byte(s)
	for i := range b {
		b[i] -= '0'
	}
	return b
}

func TestOrdinal(t *testing.T) {
	testPlurals(t, Ordinal, ordinalTests)
}

func TestCardinal(t *testing.T) {
	testPlurals(t, Cardinal, cardinalTests)
}

func testPlurals(t *testing.T, p *Rules, testCases []pluralTest) {
	for _, tc := range testCases {
		for _, loc := range strings.Split(tc.locales, " ") {
			tag := language.MustParse(loc)
			// Test integers
			for _, s := range tc.integer {
				a := strings.Split(s, "~")
				from := parseUint(t, a[0])
				to := from
				if len(a) > 1 {
					to = parseUint(t, a[1])
				}
				for n := from; n <= to; n++ {
					t.Run(fmt.Sprintf("%s/int(%d)", loc, n), func(t *testing.T) {
						if f := p.matchComponents(tag, n, 0, 0); f != Form(tc.form) {
							t.Errorf("matchComponents: got %v; want %v", f, Form(tc.form))
						}
						digits := []byte(fmt.Sprint(n))
						for i := range digits {
							digits[i] -= '0'
						}
						if f := p.MatchDigits(tag, digits, 0, 0); f != Form(tc.form) {
							t.Errorf("MatchDigits: got %v; want %v", f, Form(tc.form))
						}
					})
				}
			}
			// Test decimals
			for _, s := range tc.decimal {
				a := strings.Split(s, "~")
				from, scale := parseFixedPoint(t, a[0])
				to := from
				if len(a) > 1 {
					var toScale int
					if to, toScale = parseFixedPoint(t, a[1]); toScale != scale {
						t.Fatalf("%s:%s: non-matching scales %d versus %d", loc, s, scale, toScale)
					}
				}
				m := 1
				for i := 0; i < scale; i++ {
					m *= 10
				}
				for n := from; n <= to; n++ {
					num := fmt.Sprintf("%[1]d.%0[3]*[2]d", n/m, n%m, scale)
					name := fmt.Sprintf("%s:dec(%s)", loc, num)
					t.Run(name, func(t *testing.T) {
						if f := p.matchComponents(tag, n/m, n%m, scale); f != Form(tc.form) {
							t.Errorf("matchComponents: got %v; want %v", f, Form(tc.form))
						}
						digits := []byte(strings.Replace(num, ".", "", 1))
						for i := range digits {
							digits[i] -= '0'
						}
						if f := p.MatchDigits(tag, digits, -scale, scale); f != Form(tc.form) {
							t.Errorf("MatchDigits: got %v; want %v", f, Form(tc.form))
						}
					})
				}
			}
		}
	}
}

func parseUint(t *testing.T, s string) int {
	val, err := strconv.ParseUint(s, 10, 32)
	if err != nil {
		t.Fatal(err)
	}
	return int(val)
}

func parseFixedPoint(t *testing.T, s string) (val, scale int) {
	p := strings.Index(s, ".")
	s = strings.Replace(s, ".", "", 1)
	v, err := strconv.ParseUint(s, 10, 32)
	if err != nil {
		t.Fatal(err)
	}
	return int(v), len(s) - p
}

func BenchmarkPluralSimpleCases(b *testing.B) {
	p := Cardinal
	en, _ := language.CompactIndex(language.English)
	zh, _ := language.CompactIndex(language.Chinese)
	for i := 0; i < b.N; i++ {
		matchPlural(p, en, 0, 0, 0)  // 0
		matchPlural(p, en, 1, 0, 0)  // 1
		matchPlural(p, en, 2, 12, 3) // 2.120
		matchPlural(p, zh, 0, 0, 0)  // 0
		matchPlural(p, zh, 1, 0, 0)  // 1
		matchPlural(p, zh, 2, 12, 3) // 2.120
	}
}

func BenchmarkPluralComplexCases(b *testing.B) {
	p := Cardinal
	ar, _ := language.CompactIndex(language.Arabic)
	lv, _ := language.CompactIndex(language.Latvian)
	for i := 0; i < b.N; i++ {
		matchPlural(p, lv, 0, 19, 2)    // 0.19
		matchPlural(p, lv, 11, 0, 3)    // 11.000
		matchPlural(p, lv, 100, 123, 4) // 0.1230
		matchPlural(p, ar, 0, 0, 0)     // 0
		matchPlural(p, ar, 110, 0, 0)   // 110
		matchPlural(p, ar, 99, 99, 2)   // 99.99
	}
}
