// © 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.text.DecimalFormatSymbols;
import java.util.Currency;
import java.util.Locale;

import org.junit.Test;

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

public class DecimalFormatSymbolsTest extends TestFmwk {
    /*
     * Check if getInstance returns the ICU implementation.
     */
    @Test
    public void TestGetInstance() {
        for (Locale loc : DecimalFormatSymbols.getAvailableLocales()) {
            if (TestUtil.isExcluded(loc)) {
                logln("Skipped " + loc);
                continue;
            }

            DecimalFormatSymbols decfs = DecimalFormatSymbols.getInstance(loc);

            boolean isIcuImpl = (decfs instanceof com.ibm.icu.impl.jdkadapter.DecimalFormatSymbolsICU);

            if (TestUtil.isICUExtendedLocale(loc)) {
                if (!isIcuImpl) {
                    errln("FAIL: getInstance returned JDK DecimalFormatSymbols for locale " + loc);
                }
            } else {
                if (isIcuImpl) {
                    logln("INFO: getInstance returned ICU DecimalFormatSymbols for locale " + loc);
                }
                Locale iculoc = TestUtil.toICUExtendedLocale(loc);
                DecimalFormatSymbols decfsIcu = DecimalFormatSymbols.getInstance(iculoc);
                if (isIcuImpl) {
                    if (!decfs.equals(decfsIcu)) {
                        errln("FAIL: getInstance returned ICU DecimalFormatSymbols for locale " + loc
                                + ", but different from the one for locale " + iculoc);
                    }
                } else {
                    if (!(decfsIcu instanceof com.ibm.icu.impl.jdkadapter.DecimalFormatSymbolsICU)) {
                        errln("FAIL: getInstance returned JDK DecimalFormatSymbols for locale " + iculoc);
                    }
                }
            }
        }
    }

    /*
     * Testing the contents of DecimalFormatSymbols 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("pt", "BR"),
                new Locale("ko", "KR"),
        };

        for (Locale loc : TEST_LOCALES) {
            Locale iculoc = TestUtil.toICUExtendedLocale(loc);
            DecimalFormatSymbols jdkDecfs = DecimalFormatSymbols.getInstance(iculoc);
            com.ibm.icu.text.DecimalFormatSymbols icuDecfs = com.ibm.icu.text.DecimalFormatSymbols.getInstance(loc);

            Currency jdkCur = jdkDecfs.getCurrency();
            com.ibm.icu.util.Currency icuCur = icuDecfs.getCurrency();
            if ((jdkCur != null && icuCur == null)
                    || (jdkCur == null && icuCur != null)
                    || !jdkCur.getCurrencyCode().equals(icuCur.getCurrencyCode())) {
                errln("FAIL: Different results returned by getCurrency for locale " + loc);
            }

            checkEquivalence(jdkDecfs.getCurrencySymbol(), icuDecfs.getCurrencySymbol(), loc, "getCurrencySymbol");
            checkEquivalence(jdkDecfs.getDecimalSeparator(), icuDecfs.getDecimalSeparator(), loc, "getDecimalSeparator");
            checkEquivalence(jdkDecfs.getDigit(), icuDecfs.getDigit(), loc, "getDigit");
            checkEquivalence(jdkDecfs.getExponentSeparator(), icuDecfs.getExponentSeparator(), loc, "getExponentSeparator");
            checkEquivalence(jdkDecfs.getGroupingSeparator(), icuDecfs.getGroupingSeparator(), loc, "getGroupingSeparator");
            checkEquivalence(jdkDecfs.getInfinity(), icuDecfs.getInfinity(), loc, "getInfinity");
            checkEquivalence(jdkDecfs.getInternationalCurrencySymbol(), icuDecfs.getInternationalCurrencySymbol(), loc, "getInternationalCurrencySymbol");
            checkEquivalence(jdkDecfs.getMinusSign(), icuDecfs.getMinusSign(), loc, "getMinusSign");
            checkEquivalence(jdkDecfs.getMonetaryDecimalSeparator(), icuDecfs.getMonetaryDecimalSeparator(), loc, "getMonetaryDecimalSeparator");
            checkEquivalence(jdkDecfs.getNaN(), icuDecfs.getNaN(), loc, "getNaN");
            checkEquivalence(jdkDecfs.getPatternSeparator(), icuDecfs.getPatternSeparator(), loc, "getPatternSeparator");
            checkEquivalence(jdkDecfs.getPercent(), icuDecfs.getPercent(), loc, "getPercent");
            checkEquivalence(jdkDecfs.getPerMill(), icuDecfs.getPerMill(), loc, "getPerMill");
            checkEquivalence(jdkDecfs.getZeroDigit(), icuDecfs.getZeroDigit(), loc, "getZeroDigit");
        }
    }

    private void checkEquivalence(Object jo, Object io, Locale loc, String method) {
        if (!jo.equals(io)) {
            errln("FAIL: Different results returned by " + method + " for locale "
                    + loc + " (jdk=" + jo + ",icu=" + io + ")");
        }
    }

    /*
     * Testing setters
     */
    @Test
    public void TestSetSymbols() {
        // ICU's JDK DecimalFormatSymbols implementation for de_DE locale
        DecimalFormatSymbols decfs = DecimalFormatSymbols.getInstance(TestUtil.toICUExtendedLocale(new Locale("de", "DE")));

        // en_US is supported by JDK, so this is the JDK's own DecimalFormatSymbols
        Locale loc = new Locale("en", "US");
        DecimalFormatSymbols decfsEnUS = DecimalFormatSymbols.getInstance(loc);

        // Copying over all symbols
        decfs.setCurrency(decfsEnUS.getCurrency());

        decfs.setCurrencySymbol(decfsEnUS.getCurrencySymbol());
        decfs.setDecimalSeparator(decfsEnUS.getDecimalSeparator());
        decfs.setDigit(decfsEnUS.getDigit());
        decfs.setExponentSeparator(decfsEnUS.getExponentSeparator());
        decfs.setGroupingSeparator(decfsEnUS.getGroupingSeparator());
        decfs.setInfinity(decfsEnUS.getInfinity());
        decfs.setInternationalCurrencySymbol(decfsEnUS.getInternationalCurrencySymbol());
        decfs.setMinusSign(decfsEnUS.getMinusSign());
        decfs.setMonetaryDecimalSeparator(decfsEnUS.getMonetaryDecimalSeparator());
        decfs.setNaN(decfsEnUS.getNaN());
        decfs.setPatternSeparator(decfsEnUS.getPatternSeparator());
        decfs.setPercent(decfsEnUS.getPercent());
        decfs.setPerMill(decfsEnUS.getPerMill());
        decfs.setZeroDigit(decfsEnUS.getZeroDigit());

        // Check
        Currency cur = decfs.getCurrency();
        Currency curEnUS = decfsEnUS.getCurrency();
        if ((cur != null && curEnUS == null)
                || (cur == null && curEnUS != null)
                || !cur.equals(curEnUS)) {
            errln("FAIL: Different results returned by getCurrency");
        }

        checkEquivalence(decfs.getCurrencySymbol(), decfsEnUS.getCurrencySymbol(), loc, "getCurrencySymbol");
        checkEquivalence(decfs.getDecimalSeparator(), decfsEnUS.getDecimalSeparator(), loc, "getDecimalSeparator");
        checkEquivalence(decfs.getDigit(), decfsEnUS.getDigit(), loc, "getDigit");
        checkEquivalence(decfs.getExponentSeparator(), decfsEnUS.getExponentSeparator(), loc, "getExponentSeparator");
        checkEquivalence(decfs.getGroupingSeparator(), decfsEnUS.getGroupingSeparator(), loc, "getGroupingSeparator");
        checkEquivalence(decfs.getInfinity(), decfsEnUS.getInfinity(), loc, "getInfinity");
        checkEquivalence(decfs.getInternationalCurrencySymbol(), decfsEnUS.getInternationalCurrencySymbol(), loc, "getInternationalCurrencySymbol");
        checkEquivalence(decfs.getMinusSign(), decfsEnUS.getMinusSign(), loc, "getMinusSign");
        checkEquivalence(decfs.getMonetaryDecimalSeparator(), decfsEnUS.getMonetaryDecimalSeparator(), loc, "getMonetaryDecimalSeparator");
        checkEquivalence(decfs.getNaN(), decfsEnUS.getNaN(), loc, "getNaN");
        checkEquivalence(decfs.getPatternSeparator(), decfsEnUS.getPatternSeparator(), loc, "getPatternSeparator");
        checkEquivalence(decfs.getPercent(), decfsEnUS.getPercent(), loc, "getPercent");
        checkEquivalence(decfs.getPerMill(), decfsEnUS.getPerMill(), loc, "getPerMill");
        checkEquivalence(decfs.getZeroDigit(), decfsEnUS.getZeroDigit(), loc, "getZeroDigit");
    }

    @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;
        }

        DecimalFormatSymbols jdkDecfs = DecimalFormatSymbols.getInstance(loc);
        com.ibm.icu.text.DecimalFormatSymbols icuDecfs = com.ibm.icu.text.DecimalFormatSymbols.getInstance(uloc);
        // Check digit 0
        if (jdkDecfs.getDigit() != icuDecfs.getDigit()) {
            errln("FAIL: Different decimal digit - via JDK: " + jdkDecfs.getDigit() + ", with ICU: " + icuDecfs.getDigit());
        }

        String jdkCurrencyCode = jdkDecfs.getCurrency().getCurrencyCode();
        String icuCurrencyCode = icuDecfs.getCurrency().getCurrencyCode();
        if (!jdkCurrencyCode.equals(icuCurrencyCode)) {
            errln("FAIL: Different currency code - via JDK: " + jdkCurrencyCode + ", with ICU: " + icuCurrencyCode);
        }
    }
}
