/*
 *******************************************************************************
 * Copyright (C) 2001-2011, 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.util.Date;
import java.util.Locale;

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
 **/
public class NumberFormatRegressionTest extends com.ibm.icu.dev.test.TestFmwk {
    
    public static void main(String[] args) throws Exception{
        new NumberFormatRegressionTest().run(args);
    }
    
    /**
     * alphaWorks upgrade
     */
    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.
     */
    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);
    
        // 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();
     */
    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)
    public void TestSerialization() throws IOException{
        byte[][] contents = NumberFormatSerialTestData.getContent();
        double data = 1234.56;
        String[] expected = {
            "1,234.56", "$1,234.56", "123,456%", "1.23456E3"};
        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);
                if (result.equals(expected[i])) {
                    logln("OK: Deserialized bogus NumberFormat(new version read old version)");
                } else {
                    errln("FAIL: the test data formats are not euqal");
                }
            } catch (Exception e) {
                warnln("FAIL: " + e.getMessage());
            }
        }
    }

    /*
     * Test case for JB#5509, strict parsing issue
     */
    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
     */
    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]);
            }
        }
    }
    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.);
    }

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