// © 2016 and later: Unicode, Inc. and others.
// License & terms of use: http://www.unicode.org/copyright.html
/*
 *******************************************************************************
 * Copyright (C) 2001-2012, International Business Machines Corporation and    *
 * others. All Rights Reserved.                                                *
 *******************************************************************************
 */

/**
 * Port From:   ICU4C v1.8.1 : format : NumberFormatRegressionTest
 * Source File: $ICU4CRoot/source/test/intltest/numrgts.cpp
 **/

package com.ibm.icu.dev.test.format;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.text.ParseException;
import java.text.ParsePosition;
import java.util.Date;
import java.util.Locale;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

import com.ibm.icu.dev.test.TestFmwk;
import com.ibm.icu.text.DateFormat;
import com.ibm.icu.text.DecimalFormat;
import com.ibm.icu.text.DecimalFormatSymbols;
import com.ibm.icu.text.NumberFormat;
import com.ibm.icu.util.Calendar;
import com.ibm.icu.util.ULocale;

/**
 * Performs regression test for MessageFormat
 **/
@RunWith(JUnit4.class)
public class NumberFormatRegressionTest extends TestFmwk {
    /**
     * alphaWorks upgrade
     */
    @Test
    public void Test4161100() {
        NumberFormat nf = NumberFormat.getInstance(Locale.US);
        nf.setMinimumFractionDigits(1);
        nf.setMaximumFractionDigits(1);
        double a = -0.09;
        String s = nf.format(a);
        logln(a + " x " +
              ((DecimalFormat) nf).toPattern() + " = " + s);
        if (!s.equals("-0.1")) {
            errln("FAIL");
        }
    }

    /**
     * DateFormat should call setIntegerParseOnly(true) on adopted
     * NumberFormat objects.
     */
    @Test
    public void TestJ691() {

        Locale loc = new Locale("fr", "CH");

        // set up the input date string & expected output
        String udt = "11.10.2000";
        String exp = "11.10.00";

        // create a Calendar for this locale
        Calendar cal = Calendar.getInstance(loc);

        // create a NumberFormat for this locale
        NumberFormat nf = NumberFormat.getInstance(loc);

        // *** Here's the key: We don't want to have to do THIS:
        //nf.setParseIntegerOnly(true);
        // or this (with changes to fr_CH per cldrbug:9370):
        //nf.setGroupingUsed(false);
        // so they are done in DateFormat.setNumberFormat

        // create the DateFormat
        DateFormat df = DateFormat.getDateInstance(DateFormat.SHORT, loc);

        df.setCalendar(cal);
        df.setNumberFormat(nf);

        // set parsing to lenient & parse
        Date ulocdat = new Date();
        df.setLenient(true);
        try {
            ulocdat = df.parse(udt);
        } catch (java.text.ParseException pe) {
            errln(pe.getMessage());
        }
        // format back to a string
        String outString = df.format(ulocdat);

        if (!outString.equals(exp)) {
            errln("FAIL: " + udt + " => " + outString);
        }
    }

    /**
     * Test getIntegerInstance();
     */
    @Test
    public void Test4408066() {

        NumberFormat nf1 = NumberFormat.getIntegerInstance();
        NumberFormat nf2 = NumberFormat.getIntegerInstance(Locale.CHINA);

        //test isParseIntegerOnly
        if (!nf1.isParseIntegerOnly() || !nf2.isParseIntegerOnly()) {
            errln("Failed : Integer Number Format Instance should set setParseIntegerOnly(true)");
        }

        //Test format
        {
            double[] data = {
                -3.75, -2.5, -1.5,
                -1.25, 0,    1.0,
                1.25,  1.5,  2.5,
                3.75,  10.0, 255.5
                };
            String[] expected = {
                "-4", "-2", "-2",
                "-1", "0",  "1",
                "1",  "2",  "2",
                "4",  "10", "256"
                };

            for (int i = 0; i < data.length; ++i) {
                String result = nf1.format(data[i]);
                if (!result.equals(expected[i])) {
                    errln("Failed => Source: " + Double.toString(data[i])
                        + ";Formatted : " + result
                        + ";but expectted: " + expected[i]);
                }
            }
        }
        //Test parse, Parsing should stop at "."
        {
            String data[] = {
                "-3.75", "-2.5", "-1.5",
                "-1.25", "0",    "1.0",
                "1.25",  "1.5",  "2.5",
                "3.75",  "10.0", "255.5"
                };
            long[] expected = {
                -3, -2, -1,
                -1, 0,  1,
                1,  1,  2,
                3,  10, 255
                };

            for (int i = 0; i < data.length; ++i) {
                Number n = null;
                try {
                    n = nf1.parse(data[i]);
                } catch (ParseException e) {
                    errln("Failed: " + e.getMessage());
                }
                if (!(n instanceof Long) || (n instanceof Integer)) {
                    errln("Failed: Integer Number Format should parse string to Long/Integer");
                }
                if (n.longValue() != expected[i]) {
                    errln("Failed=> Source: " + data[i]
                        + ";result : " + n.toString()
                        + ";expected :" + Long.toString(expected[i]));
                }
            }
        }
    }

    //Test New serialized DecimalFormat(2.0) read old serialized forms of DecimalFormat(1.3.1.1)
    @Test
    public void TestSerialization() throws IOException{
        byte[][] contents = NumberFormatSerialTestData.getContent();
        double data = 1234.56;
        String[] expected = {
            "1,234.56", "$1,234.56", "1.23456E3", "1,234.56"};
        for (int i = 0; i < 4; ++i) {
            ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(contents[i]));
            try {
                NumberFormat format = (NumberFormat) ois.readObject();
                String result = format.format(data);
                assertEquals("Deserialization new version should read old version", expected[i], result);
            } catch (Exception e) {
                e.printStackTrace();
                warnln("FAIL: " + e);
            }
        }
    }

    /*
     * Test case for JB#5509, strict parsing issue
     */
    @Test
    public void TestJB5509() {
        String[] data = {
                "1,2",
                "1.2",
                "1,2.5",
                "1,23.5",
                "1,234.5",
                "1,234",
                "1,234,567",
                "1,234,567.8",
                "1,234,5",
                "1,234,5.6",
                "1,234,56.7"
        };
        boolean[] expected = { // false for expected parse failure
                false,
                true,
                false,
                false,
                true,
                true,
                true,
                true,
                false,
                false,
                false,
                false
        };

        DecimalFormat df = new DecimalFormat("#,##0.###", new DecimalFormatSymbols(new ULocale("en_US")));
        df.setParseStrict(true);
        for (int i = 0; i < data.length; i++) {
            try {
                df.parse(data[i]);
                if (!expected[i]) {
                    errln("Failed: ParseException must be thrown for string " + data[i]);
                }
            } catch (ParseException pe) {
                if (expected[i]) {
                    errln("Failed: ParseException must not be thrown for string " + data[i]);
                }
            }
        }
    }

    /*
     * Test case for ticket#5698 - parsing extremely large/small values
     */
    @Test
    public void TestT5698() {
        final String[] data = {
                "12345679E66666666666666666",
                "-12345679E66666666666666666",
                ".1E2147483648", // exponent > max int
                ".1E2147483647", // exponent == max int
                ".1E-2147483648", // exponent == min int
                ".1E-2147483649", // exponent < min int
                "1.23E350", // value > max double
                "1.23E300", // value < max double
                "-1.23E350", // value < min double
                "-1.23E300", // value > min double
                "4.9E-324", // value = smallest non-zero double
                "1.0E-325", // 0 < value < smallest non-zero positive double0
                "-1.0E-325", // 0 > value > largest non-zero negative double
        };
        final double[] expected = {
                Double.POSITIVE_INFINITY,
                Double.NEGATIVE_INFINITY,
                Double.POSITIVE_INFINITY,
                Double.POSITIVE_INFINITY,
                0.0,
                0.0,
                Double.POSITIVE_INFINITY,
                1.23e300d,
                Double.NEGATIVE_INFINITY,
                -1.23e300d,
                4.9e-324d,
                0.0,
                -0.0,
        };

        NumberFormat nfmt = NumberFormat.getInstance();

        for (int i = 0; i < data.length; i++) {
            try {
                Number n = nfmt.parse(data[i]);
                if (expected[i] != n.doubleValue()) {
                    errln("Failed: Parsed result for " + data[i] + ": "
                            + n.doubleValue() + " / expected: " + expected[i]);
                }
            } catch (ParseException pe) {
                errln("Failed: ParseException is thrown for " + data[i]);
            }
        }
    }
    @Test
    public void TestSurrogatesParsing() { // Test parsing of numbers that use digits from the supplemental planes.
        final String[] data = {
                "1\ud801\udca2,3\ud801\udca45.67", //
                "\ud801\udca1\ud801\udca2,\ud801\udca3\ud801\udca4\ud801\udca5.\ud801\udca6\ud801\udca7\ud801\udca8", //
                "\ud835\udfd2.\ud835\udfd7E-\ud835\udfd1",
                "\ud835\udfd3.8E-0\ud835\udfd0"
                };
        final double[] expected = {
                12345.67,
                12345.678,
                0.0049,
                0.058
        };

        NumberFormat nfmt = NumberFormat.getInstance();

        for (int i = 0; i < data.length; i++) {
            try {
                Number n = nfmt.parse(data[i]);
                if (expected[i] != n.doubleValue()) {
                    errln("Failed: Parsed result for " + data[i] + ": "
                            + n.doubleValue() + " / expected: " + expected[i]);
                }
            } catch (ParseException pe) {
                errln("Failed: ParseException is thrown for " + data[i]);
            }
        }
    }

    void checkNBSPPatternRtNum(String testcase, NumberFormat nf, double myNumber) {
        String myString = nf.format(myNumber);

            double aNumber;
            try {
                aNumber = nf.parse(myString).doubleValue();
            } catch (ParseException e) {
                // TODO Auto-generated catch block
                errln("FAIL: " + testcase +" - failed to parse. " + e.toString());
                return;
            }
            if(Math.abs(aNumber-myNumber)>.001) {
            errln("FAIL: "+testcase+": formatted "+myNumber+", parsed into "+aNumber+"\n");
        } else {
            logln("PASS: "+testcase+": formatted "+myNumber+", parsed into "+aNumber+"\n");
        }
    }

    void checkNBSPPatternRT(String testcase, NumberFormat nf) {
        checkNBSPPatternRtNum(testcase, nf, 12345.);
        checkNBSPPatternRtNum(testcase, nf, -12345.);
    }

    @Test
    public void TestNBSPInPattern() {
    NumberFormat nf = null;
    String testcase;


    testcase="ar_AE UNUM_CURRENCY";
    nf = NumberFormat.getCurrencyInstance(new ULocale("ar_AE"));
    checkNBSPPatternRT(testcase, nf);
    // if we don't have CLDR 1.6 data, bring out the problem anyways

    String SPECIAL_PATTERN = "\u00A4\u00A4'\u062f.\u0625.\u200f\u00a0'###0.00";
    testcase = "ar_AE special pattern: " + SPECIAL_PATTERN;
    nf = new DecimalFormat();
    ((DecimalFormat)nf).applyPattern(SPECIAL_PATTERN);
    checkNBSPPatternRT(testcase, nf);

    }

    /*
     * Test case for #9293
     * Parsing currency in strict mode
     */
    @Test
    public void TestT9293() {
        NumberFormat fmt = NumberFormat.getCurrencyInstance();
        fmt.setParseStrict(true);

        final int val = 123456;
        String txt = fmt.format(123456);

        ParsePosition pos = new ParsePosition(0);
        Number num = fmt.parse(txt, pos);

        if (pos.getErrorIndex() >= 0) {
            errln("FAIL: Parsing " + txt + " - error index: " + pos.getErrorIndex());
        } else if (val != num.intValue()) {
            errln("FAIL: Parsed result: " + num + " - expected: " + val);
        }
    }

    @Test
    public void TestAffixesNoCurrency() {
        ULocale locale = new ULocale("en");
        DecimalFormat nf = (DecimalFormat) NumberFormat.getInstance(locale, NumberFormat.PLURALCURRENCYSTYLE);
        assertEquals(
            "Positive suffix should contain the localized display name for currency XXX",
            " (unknown currency)",
            nf.getPositiveSuffix());
    }

    @Test
    public void TestGroupingEnabledDisabledGetters() {
        // See ticket #13442 comment 14
        DecimalFormatSymbols EN = DecimalFormatSymbols.getInstance(ULocale.ENGLISH);
        {
            DecimalFormat df = new DecimalFormat("0", EN);
            assertEquals("pat 0: ", 0, df.getGroupingSize());
            assertEquals("pat 0: ", false, df.isGroupingUsed());
            df.setGroupingUsed(false);
            assertEquals("pat 0 then disabled: ", 0, df.getGroupingSize());
            assertEquals("pat 0 then disabled: ", "1111", df.format(1111));
            df.setGroupingUsed(true);
            assertEquals("pat 0 then enabled: ", 0, df.getGroupingSize());
            assertEquals("pat 0 then enabled: ", "1111", df.format(1111));
        }
        {
            DecimalFormat df = new DecimalFormat("#,##0", EN);
            assertEquals("pat #,##0: ", 3, df.getGroupingSize());
            assertEquals("pat #,##0: ", true, df.isGroupingUsed());
            df.setGroupingUsed(false);
            assertEquals("pat #,##0 then disabled: ", 3, df.getGroupingSize());
            assertEquals("pat #,##0 then disabled: ", "1111", df.format(1111));
            df.setGroupingUsed(true);
            assertEquals("pat #,##0 then enabled: ", 3, df.getGroupingSize());
            assertEquals("pat #,##0 then enabled: ", "1,111", df.format(1111));
        }
    }
}
