using Xunit;

namespace Humanizer.Tests.Localisation.ruRU
{
    [UseCulture("ru-RU")]
    public class NumberToWordsTests
    {
        [Theory]
        [InlineData(0, "ноль")]
        [InlineData(1, "один")]
        [InlineData(10, "десять")]
        [InlineData(11, "одиннадцать")]
        [InlineData(12, "двенадцать")]
        [InlineData(13, "тринадцать")]
        [InlineData(14, "четырнадцать")]
        [InlineData(15, "пятнадцать")]
        [InlineData(16, "шестнадцать")]
        [InlineData(17, "семнадцать")]
        [InlineData(18, "восемнадцать")]
        [InlineData(19, "девятнадцать")]
        [InlineData(20, "двадцать")]
        [InlineData(30, "тридцать")]
        [InlineData(40, "сорок")]
        [InlineData(50, "пятьдесят")]
        [InlineData(60, "шестьдесят")]
        [InlineData(70, "семьдесят")]
        [InlineData(80, "восемьдесят")]
        [InlineData(90, "девяносто")]
        [InlineData(100, "сто")]
        [InlineData(200, "двести")]
        [InlineData(300, "триста")]
        [InlineData(400, "четыреста")]
        [InlineData(500, "пятьсот")]
        [InlineData(600, "шестьсот")]
        [InlineData(700, "семьсот")]
        [InlineData(800, "восемьсот")]
        [InlineData(900, "девятьсот")]
        [InlineData(1000, "одна тысяча")]
        [InlineData(2000, "две тысячи")]
        [InlineData(3000, "три тысячи")]
        [InlineData(4000, "четыре тысячи")]
        [InlineData(5000, "пять тысяч")]
        [InlineData(10000, "десять тысяч")]
        [InlineData(100000, "сто тысяч")]
        [InlineData(1000000, "один миллион")]
        [InlineData(2000000, "два миллиона")]
        [InlineData(10000000, "десять миллионов")]
        [InlineData(100000000, "сто миллионов")]
        [InlineData(1000000000, "один миллиард")]
        [InlineData(2000000000, "два миллиарда")]
        [InlineData(3000000000, "три миллиарда")]
        [InlineData(4000000000, "четыре миллиарда")]
        [InlineData(122, "сто двадцать два")]
        [InlineData(3501, "три тысячи пятьсот один")]
        [InlineData(111, "сто одиннадцать")]
        [InlineData(1112, "одна тысяча сто двенадцать")]
        [InlineData(11213, "одиннадцать тысяч двести тринадцать")]
        [InlineData(121314, "сто двадцать одна тысяча триста четырнадцать")]
        [InlineData(2132415, "два миллиона сто тридцать две тысячи четыреста пятнадцать")]
        [InlineData(12345516, "двенадцать миллионов триста сорок пять тысяч пятьсот шестнадцать")]
        [InlineData(751633617, "семьсот пятьдесят один миллион шестьсот тридцать три тысячи шестьсот семнадцать")]
        [InlineData(1111111118, "один миллиард сто одиннадцать миллионов сто одиннадцать тысяч сто восемнадцать")]
        [InlineData(4111111118, "четыре миллиарда сто одиннадцать миллионов сто одиннадцать тысяч сто восемнадцать")]
        [InlineData(-751633617, "минус семьсот пятьдесят один миллион шестьсот тридцать три тысячи шестьсот семнадцать")]
        [InlineData(999999999999, "девятьсот девяносто девять миллиардов девятьсот девяносто девять миллионов девятьсот девяносто девять тысяч девятьсот девяносто девять")]
        [InlineData(1_000_000_000_000, "один триллион")]
        [InlineData(3_000_000_000_000, "три триллиона")]
        [InlineData(5_000_000_000_000, "пять триллионов")]
        [InlineData(999_000_000_000_000, "девятьсот девяносто девять триллионов")]
        [InlineData(
            long.MaxValue,
            "девять квинтиллионов " +
            "двести двадцать три квадриллиона " +
            "триста семьдесят два триллиона " +
            "тридцать шесть миллиардов " +
            "восемьсот пятьдесят четыре миллиона " +
            "семьсот семьдесят пять тысяч " +
            "восемьсот семь")]
        [InlineData(
            long.MinValue,
            "минус девять квинтиллионов " +
            "двести двадцать три квадриллиона " +
            "триста семьдесят два триллиона " +
            "тридцать шесть миллиардов " +
            "восемьсот пятьдесят четыре миллиона " +
            "семьсот семьдесят пять тысяч " +
            "восемьсот восемь")]
        public void ToWords(long number, string expected)
        {
            Assert.Equal(expected, number.ToWords());
        }

        [Theory]
        [InlineData(122, "сто двадцать две", GrammaticalGender.Feminine)]
        [InlineData(3501, "три тысячи пятьсот одна", GrammaticalGender.Feminine)]
        [InlineData(3501, "три тысячи пятьсот одно", GrammaticalGender.Neuter)]
        public void ToWordsWithGender(int number, string expected, GrammaticalGender gender)
        {
            Assert.Equal(expected, number.ToWords(gender));
        }

        [Theory]
        [InlineData(0, "нулевой")]
        [InlineData(1, "первый")]
        [InlineData(2, "второй")]
        [InlineData(3, "третий")]
        [InlineData(10, "десятый")]
        [InlineData(11, "одиннадцатый")]
        [InlineData(12, "двенадцатый")]
        [InlineData(13, "тринадцатый")]
        [InlineData(14, "четырнадцатый")]
        [InlineData(15, "пятнадцатый")]
        [InlineData(16, "шестнадцатый")]
        [InlineData(17, "семнадцатый")]
        [InlineData(18, "восемнадцатый")]
        [InlineData(19, "девятнадцатый")]
        [InlineData(20, "двадцатый")]
        [InlineData(30, "тридцатый")]
        [InlineData(40, "сороковой")]
        [InlineData(50, "пятидесятый")]
        [InlineData(60, "шестидесятый")]
        [InlineData(70, "семидесятый")]
        [InlineData(80, "восьмидесятый")]
        [InlineData(90, "девяностый")]
        [InlineData(100, "сотый")]
        [InlineData(101, "сто первый")]
        [InlineData(140, "сто сороковой")]
        [InlineData(200, "двухсотый")]
        [InlineData(300, "трёхсотый")]
        [InlineData(400, "четырёхсотый")]
        [InlineData(500, "пятисотый")]
        [InlineData(600, "шестисотый")]
        [InlineData(700, "семисотый")]
        [InlineData(800, "восьмисотый")]
        [InlineData(900, "девятисотый")]
        [InlineData(1000, "тысячный")]
        [InlineData(1001, "одна тысяча первый")]
        [InlineData(1040, "одна тысяча сороковой")]
        [InlineData(2000, "двухтысячный")]
        [InlineData(3000, "трёхтысячный")]
        [InlineData(4000, "четырёхтысячный")]
        [InlineData(5000, "пятитысячный")]
        [InlineData(10000, "десятитысячный")]
        [InlineData(21000, "двадцатиоднотысячный")]
        [InlineData(100000, "стотысячный")]
        [InlineData(101000, "стооднотысячный")]
        [InlineData(121000, "стодвадцатиоднотысячный")]
        [InlineData(200000, "двухсоттысячный")]
        [InlineData(1000000, "миллионный")]
        [InlineData(2000000, "двухмиллионный")]
        [InlineData(10000000, "десятимиллионный")]
        [InlineData(21000000, "двадцатиодномиллионный")]
        [InlineData(100000000, "стомиллионный")]
        [InlineData(230000000, "двухсоттридцатимиллионный")]
        [InlineData(1000000000, "миллиардный")]
        [InlineData(2000000000, "двухмиллиардный")]
        [InlineData(122, "сто двадцать второй")]
        [InlineData(3501, "три тысячи пятьсот первый")]
        [InlineData(111, "сто одиннадцатый")]
        [InlineData(1112, "одна тысяча сто двенадцатый")]
        [InlineData(11213, "одиннадцать тысяч двести тринадцатый")]
        [InlineData(121314, "сто двадцать одна тысяча триста четырнадцатый")]
        [InlineData(2132415, "два миллиона сто тридцать две тысячи четыреста пятнадцатый")]
        [InlineData(12345516, "двенадцать миллионов триста сорок пять тысяч пятьсот шестнадцатый")]
        [InlineData(751633617, "семьсот пятьдесят один миллион шестьсот тридцать три тысячи шестьсот семнадцатый")]
        [InlineData(1111111118, "один миллиард сто одиннадцать миллионов сто одиннадцать тысяч сто восемнадцатый")]
        [InlineData(1111111000, "один миллиард сто одиннадцать миллионов стоодиннадцатитысячный")]
        [InlineData(1234567000, "один миллиард двести тридцать четыре миллиона пятисотшестидесятисемитысячный")]
        [InlineData(-751633617, "минус семьсот пятьдесят один миллион шестьсот тридцать три тысячи шестьсот семнадцатый")]
        public void ToOrdinalWords(int number, string expected)
        {
            Assert.Equal(expected, number.ToOrdinalWords());
        }

        [Theory]
        [InlineData(0, "нулевая")]
        [InlineData(1, "первая")]
        [InlineData(2, "вторая")]
        [InlineData(3, "третья")]
        [InlineData(10, "десятая")]
        [InlineData(11, "одиннадцатая")]
        [InlineData(12, "двенадцатая")]
        [InlineData(13, "тринадцатая")]
        [InlineData(14, "четырнадцатая")]
        [InlineData(15, "пятнадцатая")]
        [InlineData(16, "шестнадцатая")]
        [InlineData(17, "семнадцатая")]
        [InlineData(18, "восемнадцатая")]
        [InlineData(19, "девятнадцатая")]
        [InlineData(20, "двадцатая")]
        [InlineData(30, "тридцатая")]
        [InlineData(40, "сороковая")]
        [InlineData(50, "пятидесятая")]
        [InlineData(60, "шестидесятая")]
        [InlineData(70, "семидесятая")]
        [InlineData(80, "восьмидесятая")]
        [InlineData(90, "девяностая")]
        [InlineData(100, "сотая")]
        [InlineData(200, "двухсотая")]
        [InlineData(300, "трёхсотая")]
        [InlineData(400, "четырёхсотая")]
        [InlineData(500, "пятисотая")]
        [InlineData(600, "шестисотая")]
        [InlineData(700, "семисотая")]
        [InlineData(800, "восьмисотая")]
        [InlineData(900, "девятисотая")]
        [InlineData(1000, "тысячная")]
        [InlineData(2000, "двухтысячная")]
        [InlineData(3000, "трёхтысячная")]
        [InlineData(4000, "четырёхтысячная")]
        [InlineData(5000, "пятитысячная")]
        [InlineData(10000, "десятитысячная")]
        [InlineData(90000, "девяностотысячная")]
        [InlineData(100000, "стотысячная")]
        [InlineData(990000, "девятисотдевяностотысячная")]
        [InlineData(990001, "девятьсот девяносто тысяч первая")]
        [InlineData(1000000, "миллионная")]
        [InlineData(2000000, "двухмиллионная")]
        [InlineData(10000000, "десятимиллионная")]
        [InlineData(100000000, "стомиллионная")]
        [InlineData(1000000000, "миллиардная")]
        [InlineData(2000000000, "двухмиллиардная")]
        [InlineData(122, "сто двадцать вторая")]
        [InlineData(3501, "три тысячи пятьсот первая")]
        [InlineData(111, "сто одиннадцатая")]
        [InlineData(1112, "одна тысяча сто двенадцатая")]
        [InlineData(11000, "одиннадцатитысячная")]
        [InlineData(11001, "одиннадцать тысяч первая")]
        [InlineData(11213, "одиннадцать тысяч двести тринадцатая")]
        [InlineData(15000, "пятнадцатитысячная")]
        [InlineData(20000, "двадцатитысячная")]
        [InlineData(121314, "сто двадцать одна тысяча триста четырнадцатая")]
        [InlineData(2132415, "два миллиона сто тридцать две тысячи четыреста пятнадцатая")]
        [InlineData(12345516, "двенадцать миллионов триста сорок пять тысяч пятьсот шестнадцатая")]
        [InlineData(751633617, "семьсот пятьдесят один миллион шестьсот тридцать три тысячи шестьсот семнадцатая")]
        [InlineData(1111111118, "один миллиард сто одиннадцать миллионов сто одиннадцать тысяч сто восемнадцатая")]
        [InlineData(-751633617, "минус семьсот пятьдесят один миллион шестьсот тридцать три тысячи шестьсот семнадцатая")]
        public void ToOrdinalWordsFeminine(int number, string expected)
        {
            Assert.Equal(expected, number.ToOrdinalWords(GrammaticalGender.Feminine));
        }

        [Theory]
        [InlineData(3, "третье")]
        [InlineData(111, "сто одиннадцатое")]
        [InlineData(1112, "одна тысяча сто двенадцатое")]
        [InlineData(11213, "одиннадцать тысяч двести тринадцатое")]
        [InlineData(121314, "сто двадцать одна тысяча триста четырнадцатое")]
        [InlineData(2132415, "два миллиона сто тридцать две тысячи четыреста пятнадцатое")]
        [InlineData(12345516, "двенадцать миллионов триста сорок пять тысяч пятьсот шестнадцатое")]
        [InlineData(751633617, "семьсот пятьдесят один миллион шестьсот тридцать три тысячи шестьсот семнадцатое")]
        [InlineData(1111111118, "один миллиард сто одиннадцать миллионов сто одиннадцать тысяч сто восемнадцатое")]
        [InlineData(-751633617, "минус семьсот пятьдесят один миллион шестьсот тридцать три тысячи шестьсот семнадцатое")]
        public void ToOrdinalWordsNeuter(int number, string expected)
        {
            Assert.Equal(expected, number.ToOrdinalWords(GrammaticalGender.Neuter));
        }
    }
}
