// © 2018 and later: Unicode, Inc. and others.
// License & terms of use: http://www.unicode.org/copyright.html
package com.ibm.icu.dev.test.number;

import static com.ibm.icu.impl.StaticUnicodeSets.get;

import java.math.BigDecimal;
import java.util.Random;

import org.junit.Before;
import org.junit.Test;

import com.ibm.icu.dev.test.TestFmwk;
import com.ibm.icu.impl.StaticUnicodeSets.Key;
import com.ibm.icu.impl.number.DecimalQuantity_DualStorageBCD;
import com.ibm.icu.lang.UCharacter;
import com.ibm.icu.number.NumberFormatter;
import com.ibm.icu.number.Precision;
import com.ibm.icu.number.UnlocalizedNumberFormatter;
import com.ibm.icu.text.DecimalFormatSymbols;
import com.ibm.icu.text.UnicodeSet;
import com.ibm.icu.util.MeasureUnit;
import com.ibm.icu.util.NoUnit;
import com.ibm.icu.util.ULocale;

/**
 * Tests that are disabled except in exhaustive mode due to runtime.
 *
 * @author sffc
 */
public class ExhaustiveNumberTest extends TestFmwk {
    @Before
    public void beforeMethod() {
        // Disable this test class except for exhaustive mode.
        // To enable exhaustive mode, pass the JVM argument "-DICU.exhaustive=10"
        org.junit.Assume.assumeTrue(getExhaustiveness() > 5);
    }

    @Test
    public void testSetCoverage() {
        // Lenient comma/period should be supersets of strict comma/period;
        // it also makes the coverage logic cheaper.
        assertTrue("COMMA should be superset of STRICT_COMMA",
                get(Key.COMMA).containsAll(get(Key.STRICT_COMMA)));
        assertTrue("PERIOD should be superset of STRICT_PERIOD",
                get(Key.PERIOD).containsAll(get(Key.STRICT_PERIOD)));

        UnicodeSet decimals = get(Key.STRICT_COMMA).cloneAsThawed().addAll(get(Key.STRICT_PERIOD))
                .freeze();
        UnicodeSet grouping = decimals.cloneAsThawed().addAll(get(Key.OTHER_GROUPING_SEPARATORS))
                .freeze();
        UnicodeSet plusSign = get(Key.PLUS_SIGN);
        UnicodeSet minusSign = get(Key.MINUS_SIGN);
        UnicodeSet percent = get(Key.PERCENT_SIGN);
        UnicodeSet permille = get(Key.PERMILLE_SIGN);
        UnicodeSet infinity = get(Key.INFINITY_SIGN);

        for (ULocale locale : ULocale.getAvailableLocales()) {
            DecimalFormatSymbols dfs = DecimalFormatSymbols.getInstance(locale);

            assertInSet(locale, decimals, dfs.getDecimalSeparatorString());
            assertInSet(locale, grouping, dfs.getGroupingSeparatorString());
            assertInSet(locale, plusSign, dfs.getPlusSignString());
            assertInSet(locale, minusSign, dfs.getMinusSignString());
            assertInSet(locale, percent, dfs.getPercentString());
            assertInSet(locale, permille, dfs.getPerMillString());
            assertInSet(locale, infinity, dfs.getInfinity());
        }
    }

    static void assertInSet(ULocale locale, UnicodeSet set, String str) {
        if (str.codePointCount(0, str.length()) != 1) {
            // Ignore locale strings with more than one code point (usually a bidi mark)
            return;
        }
        assertInSet(locale, set, str.codePointAt(0));
    }

    static void assertInSet(ULocale locale, UnicodeSet set, int cp) {
        // If this test case fails, add the specified code point to the corresponding set in
        // UnicodeSetStaticCache.java and numparse_unisets.cpp
        assertTrue(
                locale
                        + " U+"
                        + Integer.toHexString(cp)
                        + " ("
                        + UCharacter.toString(cp)
                        + ") should be in "
                        + set,
                set.contains(cp));
    }

    @Test
    public void test20417_PercentParity() {
        UnlocalizedNumberFormatter uNoUnitPercent = NumberFormatter.with().unit(NoUnit.PERCENT);
        UnlocalizedNumberFormatter uNoUnitPermille = NumberFormatter.with().unit(NoUnit.PERMILLE);
        UnlocalizedNumberFormatter uMeasurePercent = NumberFormatter.with().unit(MeasureUnit.PERCENT);
        UnlocalizedNumberFormatter uMeasurePermille = NumberFormatter.with().unit(MeasureUnit.PERMILLE);

        for (ULocale locale : ULocale.getAvailableLocales()) {
            String sNoUnitPercent = uNoUnitPercent.locale(locale).format(50).toString();
            String sNoUnitPermille = uNoUnitPermille.locale(locale).format(50).toString();
            String sMeasurePercent = uMeasurePercent.locale(locale).format(50).toString();
            String sMeasurePermille = uMeasurePermille.locale(locale).format(50).toString();

            assertEquals("Percent, locale " + locale, sNoUnitPercent, sMeasurePercent);
            assertEquals("Permille, locale " + locale, sNoUnitPermille, sMeasurePermille);
        }
    }

    @Test
    public void unlimitedRoundingBigDecimal() {
        BigDecimal ten10000 = BigDecimal.valueOf(10).pow(10000);
        BigDecimal longFraction = ten10000.subtract(BigDecimal.ONE).divide(ten10000);
        String expected = longFraction.toPlainString();
        String actual = NumberFormatter.withLocale(ULocale.ENGLISH).precision(Precision.unlimited())
                .format(longFraction).toString();
        assertEquals("All digits should be displayed", expected, actual);
    }

    @Test
    public void testConvertToAccurateDouble() {
        // based on https://github.com/google/double-conversion/issues/28
        double[] hardDoubles = {
                1651087494906221570.0,
                2.207817077636718750000000000000,
                1.818351745605468750000000000000,
                3.941719055175781250000000000000,
                3.738609313964843750000000000000,
                3.967735290527343750000000000000,
                1.328025817871093750000000000000,
                3.920967102050781250000000000000,
                1.015235900878906250000000000000,
                1.335227966308593750000000000000,
                1.344520568847656250000000000000,
                2.879127502441406250000000000000,
                3.695838928222656250000000000000,
                1.845344543457031250000000000000,
                3.793952941894531250000000000000,
                3.211402893066406250000000000000,
                2.565971374511718750000000000000,
                0.965156555175781250000000000000,
                2.700004577636718750000000000000,
                0.767097473144531250000000000000,
                1.780448913574218750000000000000,
                2.624839782714843750000000000000,
                1.305290222167968750000000000000,
                3.834922790527343750000000000000, };

        double[] exactDoubles = {
                51423,
                51423e10,
                -5074790912492772E-327,
                83602530019752571E-327,
                4.503599627370496E15,
                6.789512076111555E15,
                9.007199254740991E15,
                9.007199254740992E15 };

        for (double d : hardDoubles) {
            checkDoubleBehavior(d, true, "");
        }

        for (double d : exactDoubles) {
            checkDoubleBehavior(d, false, "");
        }

        assertEquals("NaN check failed",
                Double.NaN,
                new DecimalQuantity_DualStorageBCD(Double.NaN).toDouble());
        assertEquals("Inf check failed",
                Double.POSITIVE_INFINITY,
                new DecimalQuantity_DualStorageBCD(Double.POSITIVE_INFINITY).toDouble());
        assertEquals("-Inf check failed",
                Double.NEGATIVE_INFINITY,
                new DecimalQuantity_DualStorageBCD(Double.NEGATIVE_INFINITY).toDouble());

        // Generate random doubles
        String alert = "UNEXPECTED FAILURE: PLEASE REPORT THIS MESSAGE TO THE ICU TEAM: ";
        Random rnd = new Random();
        for (int i = 0; i < 100000; i++) {
            double d = Double.longBitsToDouble(rnd.nextLong());
            if (Double.isNaN(d) || Double.isInfinite(d))
                continue;
            checkDoubleBehavior(d, false, alert);
        }
    }

    private static void checkDoubleBehavior(double d, boolean explicitRequired, String alert) {
        DecimalQuantity_DualStorageBCD fq = new DecimalQuantity_DualStorageBCD(d);
        if (explicitRequired) {
            assertTrue(alert + "Should be using approximate double", !fq.explicitExactDouble);
        }
        fq.roundToInfinity();
        if (explicitRequired) {
            assertTrue(alert + "Should not be using approximate double", fq.explicitExactDouble);
        }
        DecimalQuantityTest
                .assertDoubleEquals(alert + "After conversion to exact BCD (double)", d, fq.toDouble());
        DecimalQuantityTest.assertBigDecimalEquals(alert + "After conversion to exact BCD (BigDecimal)",
                new BigDecimal(Double.toString(d)),
                fq.toBigDecimal());
    }
}
