// © 2016 and later: Unicode, Inc. and others.
// License & terms of use: http://www.unicode.org/copyright.html#License
/*
 *******************************************************************************
 * Copyright (C) 2008-2015, International Business Machines Corporation and    *
 * others. All Rights Reserved.                                                *
 *******************************************************************************
 */
package com.ibm.icu.dev.test.localespi;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.text.NumberFormat;
import java.text.ParseException;
import java.util.Locale;

import org.junit.Test;

import com.ibm.icu.dev.test.TestFmwk;
import com.ibm.icu.util.ULocale;

public class NumberFormatTest extends TestFmwk {
    private static final int DEFAULT_TYPE = 0;
    private static final int NUMBER_TYPE = 1;
    private static final int INTEGER_TYPE  = 2;
    private static final int PERCENT_TYPE = 3;
    private static final int CURRENCY_TYPE = 4;

    /*
     * Check if getInstance returns the ICU implementation.
     */
    @Test
    public void TestGetInstance() {
        for (Locale loc : NumberFormat.getAvailableLocales()) {
            if (TestUtil.isExcluded(loc)) {
                logln("Skipped " + loc);
                continue;
            }
            checkGetInstance(DEFAULT_TYPE, loc);
            checkGetInstance(NUMBER_TYPE, loc);
            checkGetInstance(INTEGER_TYPE, loc);
            checkGetInstance(PERCENT_TYPE, loc);
            checkGetInstance(CURRENCY_TYPE, loc);
        }
    }

    private void checkGetInstance(int type, Locale loc) {
        NumberFormat nf;
        String[] method = new String[1];
        nf = getJDKInstance(type, loc, method);

        boolean isIcuImpl = (nf instanceof com.ibm.icu.impl.jdkadapter.DecimalFormatICU)
                            || (nf instanceof com.ibm.icu.impl.jdkadapter.NumberFormatICU);
        if (TestUtil.isICUExtendedLocale(loc)) {
            if (!isIcuImpl) {
                errln("FAIL: " + method[0] + " returned JDK NumberFormat for locale " + loc);
            }
        } else {
            if (isIcuImpl) {
                logln("INFO: " + method[0] + " returned ICU NumberFormat for locale " + loc);
            }
            Locale iculoc = TestUtil.toICUExtendedLocale(loc);
            NumberFormat nfIcu = null;
            nfIcu = getJDKInstance(type, iculoc, null);
            if (isIcuImpl) {
                if (!nf.equals(nfIcu)) {
                    errln("FAIL: " + method[0] + " returned ICU NumberFormat for locale " + loc
                            + ", but different from the one for locale " + iculoc);
                }
            } else {
                if (!(nfIcu instanceof com.ibm.icu.impl.jdkadapter.DecimalFormatICU)
                        && !(nfIcu instanceof com.ibm.icu.impl.jdkadapter.NumberFormatICU)) {
                    errln("FAIL: " + method[0] + " returned JDK NumberFormat for locale " + iculoc);
                }
            }
        }
    }

    private NumberFormat getJDKInstance(int type, Locale loc, String[] methodName) {
        NumberFormat nf = null;
        String method = null;

        switch (type) {
        case DEFAULT_TYPE:
            nf = NumberFormat.getInstance(loc);
            method = "getInstance";
            break;
        case NUMBER_TYPE:
            nf = NumberFormat.getNumberInstance(loc);
            method = "getNumberInstance";
            break;
        case INTEGER_TYPE:
            nf = NumberFormat.getIntegerInstance(loc);
            method = "getIntegerInstance";
            break;
        case PERCENT_TYPE:
            nf = NumberFormat.getPercentInstance(loc);
            method = "getPercentInstance";
            break;
        case CURRENCY_TYPE:
            nf = NumberFormat.getCurrencyInstance(loc);
            method = "getCurrencyInstance";
            break;
        }
        if (methodName != null) {
            methodName[0] = method;
        }
        return nf;
    }

    private com.ibm.icu.text.NumberFormat getICUInstance(int type, Locale loc, String[] methodName) {
        com.ibm.icu.text.NumberFormat icunf = null;
        String method = null;

        switch (type) {
        case DEFAULT_TYPE:
            icunf = com.ibm.icu.text.NumberFormat.getInstance(loc);
            method = "getInstance";
            break;
        case NUMBER_TYPE:
            icunf = com.ibm.icu.text.NumberFormat.getNumberInstance(loc);
            method = "getNumberInstance";
            break;
        case INTEGER_TYPE:
            icunf = com.ibm.icu.text.NumberFormat.getIntegerInstance(loc);
            method = "getIntegerInstance";
            break;
        case PERCENT_TYPE:
            icunf = com.ibm.icu.text.NumberFormat.getPercentInstance(loc);
            method = "getPercentInstance";
            break;
        case CURRENCY_TYPE:
            icunf = com.ibm.icu.text.NumberFormat.getCurrencyInstance(loc);
            method = "getCurrencyInstance";
            break;
        }
        if (methodName != null) {
            methodName[0] = method;
        }
        return icunf;
    }

    /*
     * Testing the behavior of number format between ICU instance and its
     * equivalent created via the Locale SPI framework.
     */
    @Test
    public void TestICUEquivalent() {
        Locale[] TEST_LOCALES = {
                new Locale("en", "US"),
                new Locale("de", "DE"),
                new Locale("zh"),
        };

        long[] TEST_LONGS = {
                40L,
                -1578L,
                112233445566778899L,
        };

        double[] TEST_DOUBLES = {
                0.0451D,
                -1.679D,
                124578.369D,
        };

        Object[] TEST_NUMBERS = {
                Byte.valueOf((byte)13),
                Integer.valueOf(3961),
                Long.valueOf(-3451237890000L),
                Float.valueOf(1.754F),
                Double.valueOf(-129.942362353D),
                new BigInteger("-15253545556575859505"),
                new BigDecimal("3.14159265358979323846264338"),
        };

        String[] methodName = new String[1];
        for (Locale loc : TEST_LOCALES) {
            for (int type = 0; type <= 4; type++) {
                Locale iculoc = TestUtil.toICUExtendedLocale(loc);
                NumberFormat nf = getJDKInstance(type, iculoc, methodName);
                com.ibm.icu.text.NumberFormat icunf = getICUInstance(type, loc, null);

                String s1, s2;
                Number n1, n2;
                boolean pe1, pe2;
                for (long l : TEST_LONGS) {
                    s1 = nf.format(l);
                    s2 = icunf.format(l);

                    if (!s1.equals(s2)) {
                        errln("FAIL: Different results for formatting long " + l + " by NumberFormat("
                                + methodName[0] + ") in locale " + loc + " - JDK:" + s1 + " ICU:" + s2);
                    }

                    pe1 = false;
                    n1 = n2 = null;
                    try {
                        n1 = nf.parse(s1);
                    } catch (ParseException e) {
                        pe1 = true;
                    }
                    pe2 = false;
                    try {
                        n2 = icunf.parse(s2);
                    } catch (ParseException e) {
                        pe2 = true;
                    }
                    if ((pe1 && !pe2) || (!pe1 && pe2)) {
                        errln("FAIL: ParseException thrown by " + (pe1 ? "JDK" : "ICU")
                                + " NumberFormat(" + methodName[0] + ") for parsing long" + l
                                + " in locale " + loc);
                    } else if (!pe1 && !pe2 && !n1.equals(n2)) {
                        errln("FAIL: Different results for parsing long " + l + " by NumberFormat("
                                + methodName[0] + ") in locale " + loc + " - JDK:" + n1 + " ICU:" + n2);
                    } else if (pe1 && pe2) {
                        logln("INFO: ParseException thrown by both JDK and ICU NumberFormat("
                                + methodName[0] + ") for parsing long " + l + " in locale " + loc);
                    }
                }

                for (double d : TEST_DOUBLES) {
                    s1 = nf.format(d);
                    s2 = icunf.format(d);

                    if (!s1.equals(s2)) {
                        errln("FAIL: Different results for formatting double " + d + " by NumberFormat("
                                + methodName[0] + ") in locale " + loc + " - JDK:" + s1 + " ICU:" + s2);
                    }

                    pe1 = false;
                    n1 = n2 = null;
                    try {
                        n1 = nf.parse(s1);
                    } catch (ParseException e) {
                        pe1 = true;
                    }
                    pe2 = false;
                    try {
                        n2 = icunf.parse(s2);
                    } catch (ParseException e) {
                        pe2 = true;
                    }
                    if ((pe1 && !pe2) || (!pe1 && pe2)) {
                        errln("FAIL: ParseException thrown by " + (pe1 ? "JDK" : "ICU")
                                + " NumberFormat(" + methodName[0] + ") for parsing double" + d
                                + " in locale " + loc);
                    } else if (!pe1 && !pe2 && !n1.equals(n2)) {
                        errln("FAIL: Different results for parsing double " + d + " by NumberFormat("
                                + methodName[0] + ") in locale " + loc + " - JDK:" + n1 + " ICU:" + n2);
                    } else if (pe1 && pe2) {
                        logln("INFO: ParseException thrown by both JDK and ICU NumberFormat("
                                + methodName[0] + ") for parsing double " + d + " in locale " + loc);
                    }
                }

                for (Object o : TEST_NUMBERS) {
                    s1 = nf.format(o);
                    s2 = icunf.format(o);

                    if (!s1.equals(s2)) {
                        errln("FAIL: Different results for formatting " + o.getClass().getName() + " by NumberFormat("
                                + methodName[0] + ") in locale " + loc + " - JDK:" + s1 + " ICU:" + s2);
                    }

                    pe1 = false;
                    n1 = n2 = null;
                    try {
                        n1 = nf.parse(s1);
                    } catch (ParseException e) {
                        pe1 = true;
                    }
                    pe2 = false;
                    try {
                        n2 = icunf.parse(s2);
                    } catch (ParseException e) {
                        pe2 = true;
                    }
                    if ((pe1 && !pe2) || (!pe1 && pe2)) {
                        errln("FAIL: ParseException thrown by " + (pe1 ? "JDK" : "ICU")
                                + " NumberFormat(" + methodName[0] + ") for parsing " + o.getClass().getName()
                                + " in locale " + loc);
                    } else if (!pe1 && !pe2 && !n1.equals(n2)) {
                        errln("FAIL: Different results for parsing " + o.getClass().getName() + " by NumberFormat("
                                + methodName[0] + ") in locale " + loc + " - JDK:" + n1 + " ICU:" + n2);
                    } else if (pe1 && pe2) {
                        logln("INFO: ParseException thrown by both JDK and ICU NumberFormat("
                                + methodName[0] + ") for parsing " + o.getClass().getName() + " in locale " + loc);
                    }
                }
            }
        }
    }

    @Test
    public void TestKeywords() {
        // ICU provider variant is appended
        ULocale uloc0 = new ULocale("en_US_" + TestUtil.ICU_VARIANT + "@numbers=Arab;currency=EUR");
        Locale loc = uloc0.toLocale();
        // On Java 7+, locale extension is preserved
        ULocale uloc = ULocale.forLocale(loc);
        String nsType = uloc.getKeywordValue("numbers");
        if (nsType == null) {
            // Java 6 - skip this test
            return;
        }

        NumberFormat jdkNfmt = NumberFormat.getCurrencyInstance(loc);
        com.ibm.icu.text.NumberFormat icuNfmt = com.ibm.icu.text.NumberFormat.getCurrencyInstance(uloc);

        final double num = 12345.67d;
        String jdkOut = jdkNfmt.format(num);
        String icuOut = icuNfmt.format(num);

        if (!jdkOut.equals(icuOut)) {
            errln("FAIL: JDK number format with Locale " + loc + " is " + jdkOut + ", expected: " + icuOut);
        }
    }
}
