/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.apache.commons.beanutils2.locale;

import java.sql.Date;
import java.sql.Time;
import java.sql.Timestamp;
import java.text.NumberFormat;
import java.util.Locale;

import org.apache.commons.beanutils2.ConversionException;

import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;

/**
 * <p>
 *  Test Case for the LocaleConvertUtils class.
 *  See unimplemented functionality of the convert utils in the method begining with fixme
 * </p>
 *
 */

public class LocaleConvertUtilsTestCase extends TestCase {

    

    private char m_decimalSeparator;

    

    /**
     * Construct a new instance of this test case.
     *
     * @param name Name of the test case
     */
    public LocaleConvertUtilsTestCase(final String name) {
        super(name);
    }

    

    /**
     * Set up instance variables required by this test case.
     */
    @Override
    public void setUp() {

        LocaleConvertUtils.deregister();

        final NumberFormat nf = NumberFormat.getNumberInstance();
        final String result = nf.format(1.1);

        // could be commas instead of stops in Europe.
        m_decimalSeparator = result.charAt(1);

    }

    /**
     * Return the tests included in this test suite.
     */
    public static Test suite() {
        return new TestSuite(LocaleConvertUtilsTestCase.class);
    }

    /**
     * Tear down instance variables required by this test case.
     */
    @Override
    public void tearDown() {
        // No action required
    }

    

    /**
     * Negative String to primitive integer array tests.
     */
    public void fixmetestNegativeIntegerArray() {

        fail("Array conversions not implemented yet.");

        Object value = null;
        final int intArray[] = new int[0];

        value = LocaleConvertUtils.convert((String) null, intArray.getClass());
        checkIntegerArray(value, intArray);
        value = LocaleConvertUtils.convert("a", intArray.getClass());
        checkIntegerArray(value, intArray);
        value = LocaleConvertUtils.convert("{ a }", intArray.getClass());
        checkIntegerArray(value, intArray);
        value = LocaleConvertUtils.convert("1a3", intArray.getClass());
        checkIntegerArray(value, intArray);
        value = LocaleConvertUtils.convert("{ 1a3 }", intArray.getClass());
        checkIntegerArray(value, intArray);
        value = LocaleConvertUtils.convert("0,1a3", intArray.getClass());
        checkIntegerArray(value, intArray);
        value = LocaleConvertUtils.convert("{ 0, 1a3 }", intArray.getClass());
        checkIntegerArray(value, intArray);

    }

    /**
     * Negative scalar conversion tests.  These rely on the standard
     * default value conversions in LocaleConvertUtils.
     */
    public void testNegativeScalar() {

        /*  fixme Boolean converters not implemented at this point
        value = LocaleConvertUtils.convert("foo", Boolean.TYPE);
        ...

        value = LocaleConvertUtils.convert("foo", Boolean.class);
        ...
        */

        try {
            LocaleConvertUtils.convert("foo", Byte.TYPE);
            fail("Should have thrown conversion exception (1)");
        } catch (final ConversionException e) {
            // Expected result
        }

        try {
            LocaleConvertUtils.convert("foo", Byte.class);
            fail("Should have thrown conversion exception (2)");
        } catch (final ConversionException e) {
            // Expected result
        }

        /* fixme - not implemented
         try {
             value = LocaleConvertUtils.convert("org.apache.commons.beanutils2.Undefined", Class.class);
             fail("Should have thrown conversion exception");
         } catch (ConversionException e) {
             ; // Expected result
         }
         */

        try {
            LocaleConvertUtils.convert("foo", Double.TYPE);
            fail("Should have thrown conversion exception (3)");
        } catch (final ConversionException e) {
            // Expected result
        }

        try {
            LocaleConvertUtils.convert("foo", Double.class);
            fail("Should have thrown conversion exception (4)");
        } catch (final ConversionException e) {
            // Expected result
        }

        try {
            LocaleConvertUtils.convert("foo", Float.TYPE);
            fail("Should have thrown conversion exception (5)");
        } catch (final ConversionException e) {
            // Expected result
        }

        try {
            LocaleConvertUtils.convert("foo", Float.class);
            fail("Should have thrown conversion exception (6)");
        } catch (final ConversionException e) {
            // Expected result
        }

        try {
            LocaleConvertUtils.convert("foo", Integer.TYPE);
            fail("Should have thrown conversion exception (7)");
        } catch (final ConversionException e) {
            // Expected result
        }

        try {
            LocaleConvertUtils.convert("foo", Integer.class);
            fail("Should have thrown conversion exception (8)");
        } catch (final ConversionException e) {
            // Expected result
        }

        try {
            LocaleConvertUtils.convert("foo", Byte.TYPE);
            fail("Should have thrown conversion exception (9)");
        } catch (final ConversionException e) {
            // Expected result
        }

        try {
            LocaleConvertUtils.convert("foo", Long.class);
            fail("Should have thrown conversion exception (10)");
        } catch (final ConversionException e) {
            // Expected result
        }

        try {
            LocaleConvertUtils.convert("foo", Short.TYPE);
            fail("Should have thrown conversion exception (11)");
        } catch (final ConversionException e) {
            // Expected result
        }

        try {
            LocaleConvertUtils.convert("foo", Short.class);
            fail("Should have thrown conversion exception (12)");
        } catch (final ConversionException e) {
            // Expected result
        }

    }

    /**
     * Negative String to String array tests.
     */
    public void fixmetestNegativeStringArray() {

        fail("Array conversions not implemented yet.");

        Object value = null;
        final String stringArray[] = new String[0];

        value = LocaleConvertUtils.convert((String) null, stringArray.getClass());
        checkStringArray(value, stringArray);
    }

    /**
     * Test conversion of object to string for arrays - .
     */
    public void fixmetestObjectToStringArray() {

        fail("Array conversions not implemented yet.");
        final int intArray0[] = new int[0];
        final int intArray1[] = {123};
        final int intArray2[] = {123, 456};
        final String stringArray0[] = new String[0];
        final String stringArray1[] = {"abc"};
        final String stringArray2[] = {"abc", "def"};

        assertEquals("intArray0", null,
                LocaleConvertUtils.convert(intArray0));
        assertEquals("intArray1", "123",
                LocaleConvertUtils.convert(intArray1));
        assertEquals("intArray2", "123",
                LocaleConvertUtils.convert(intArray2));

        assertEquals("stringArray0", null,
                LocaleConvertUtils.convert(stringArray0));
        assertEquals("stringArray1", "abc",
                LocaleConvertUtils.convert(stringArray1));
        assertEquals("stringArray2", "abc",
                LocaleConvertUtils.convert(stringArray2));

    }

    /**
     * Test conversion of object to string for scalars.
     */
    public void testObjectToStringScalar() {

        assertEquals("Boolean->String", "false",
                LocaleConvertUtils.convert(Boolean.FALSE));
        assertEquals("Boolean->String", "true",
                LocaleConvertUtils.convert(Boolean.TRUE));
        assertEquals("Byte->String", "123",
                LocaleConvertUtils.convert(new Byte((byte) 123)));
        assertEquals("Character->String", "a",
                LocaleConvertUtils.convert(new Character('a')));
        assertEquals("Double->String", "123" + m_decimalSeparator + "4",
                LocaleConvertUtils.convert(new Double(123.4)));
        assertEquals("Float->String", "123" + m_decimalSeparator + "4",
                LocaleConvertUtils.convert(new Float((float) 123.4)));
        assertEquals("Integer->String", "123",
                LocaleConvertUtils.convert(new Integer(123)));
        assertEquals("Long->String", "123",
                LocaleConvertUtils.convert(new Long(123)));
        assertEquals("Short->String", "123",
                LocaleConvertUtils.convert(new Short((short) 123)));
        assertEquals("String->String", "abc",
                LocaleConvertUtils.convert("abc"));
        assertEquals("String->String null", null,
                LocaleConvertUtils.convert(null));

    }

    /**
     * Positive array conversion tests.
     */
    public void fixmetestPositiveArray() {

        fail("Array conversions not implemented yet.");

        final String values1[] = {"10", "20", "30"};
        Object value = LocaleConvertUtils.convert(values1, Integer.TYPE);
        final int shape[] = new int[0];
        assertEquals(shape.getClass(), value.getClass());
        final int results1[] = (int[]) value;
        assertEquals(results1[0], 10);
        assertEquals(results1[1], 20);
        assertEquals(results1[2], 30);

        final String values2[] = {"100", "200", "300"};
        value = LocaleConvertUtils.convert(values2, shape.getClass());
        assertEquals(shape.getClass(), value.getClass());
        final int results2[] = (int[]) value;
        assertEquals(results2[0], 100);
        assertEquals(results2[1], 200);
        assertEquals(results2[2], 300);
    }

    /**
     * Positive String to primitive integer array tests.
     */
    public void fixmetestPositiveIntegerArray() {

        fail("Array conversions not implemented yet.");

        Object value = null;
        final int intArray[] = new int[0];
        final int intArray1[] = new int[]{0};
        final int intArray2[] = new int[]{0, 10};

        value = LocaleConvertUtils.convert("{  }", intArray.getClass());
        checkIntegerArray(value, intArray);

        value = LocaleConvertUtils.convert("0", intArray.getClass());
        checkIntegerArray(value, intArray1);
        value = LocaleConvertUtils.convert(" 0 ", intArray.getClass());
        checkIntegerArray(value, intArray1);
        value = LocaleConvertUtils.convert("{ 0 }", intArray.getClass());
        checkIntegerArray(value, intArray1);

        value = LocaleConvertUtils.convert("0,10", intArray.getClass());
        checkIntegerArray(value, intArray2);
        value = LocaleConvertUtils.convert("0 10", intArray.getClass());
        checkIntegerArray(value, intArray2);
        value = LocaleConvertUtils.convert("{0,10}", intArray.getClass());
        checkIntegerArray(value, intArray2);
        value = LocaleConvertUtils.convert("{0 10}", intArray.getClass());
        checkIntegerArray(value, intArray2);
        value = LocaleConvertUtils.convert("{ 0, 10 }", intArray.getClass());
        checkIntegerArray(value, intArray2);
        value = LocaleConvertUtils.convert("{ 0 10 }", intArray.getClass());
        checkIntegerArray(value, intArray2);
    }

    /**
     * Positive scalar conversion tests.
     */
    public void testPositiveScalar() {
        Object value = null;

        /* fixme Boolean converters not implemented
         value = LocaleConvertUtils.convert("true", Boolean.TYPE);
         assertTrue(value instanceof Boolean);
         assertEquals(((Boolean) value).booleanValue(), true);

         value = LocaleConvertUtils.convert("true", Boolean.class);
         assertTrue(value instanceof Boolean);
         assertEquals(((Boolean) value).booleanValue(), true);

         value = LocaleConvertUtils.convert("yes", Boolean.TYPE);
         assertTrue(value instanceof Boolean);
         assertEquals(((Boolean) value).booleanValue(), true);

         value = LocaleConvertUtils.convert("yes", Boolean.class);
         assertTrue(value instanceof Boolean);
         assertEquals(((Boolean) value).booleanValue(), true);

         value = LocaleConvertUtils.convert("y", Boolean.TYPE);
         assertTrue(value instanceof Boolean);
         assertEquals(((Boolean) value).booleanValue(), true);

         value = LocaleConvertUtils.convert("y", Boolean.class);
         assertTrue(value instanceof Boolean);
         assertEquals(((Boolean) value).booleanValue(), true);

         value = LocaleConvertUtils.convert("on", Boolean.TYPE);
         assertTrue(value instanceof Boolean);
         assertEquals(((Boolean) value).booleanValue(), true);

         value = LocaleConvertUtils.convert("on", Boolean.class);
         assertTrue(value instanceof Boolean);
         assertEquals(((Boolean) value).booleanValue(), true);

         value = LocaleConvertUtils.convert("false", Boolean.TYPE);
         assertTrue(value instanceof Boolean);
         assertEquals(((Boolean) value).booleanValue(), false);

         value = LocaleConvertUtils.convert("false", Boolean.class);
         assertTrue(value instanceof Boolean);
         assertEquals(((Boolean) value).booleanValue(), false);

         value = LocaleConvertUtils.convert("no", Boolean.TYPE);
         assertTrue(value instanceof Boolean);
         assertEquals(((Boolean) value).booleanValue(), false);

         value = LocaleConvertUtils.convert("no", Boolean.class);
         assertTrue(value instanceof Boolean);
         assertEquals(((Boolean) value).booleanValue(), false);

         value = LocaleConvertUtils.convert("n", Boolean.TYPE);
         assertTrue(value instanceof Boolean);
         assertEquals(((Boolean) value).booleanValue(), false);

         value = LocaleConvertUtils.convert("n", Boolean.class);
         assertTrue(value instanceof Boolean);
         assertEquals(((Boolean) value).booleanValue(), false);

         value = LocaleConvertUtils.convert("off", Boolean.TYPE);
         assertTrue(value instanceof Boolean);
         assertEquals(((Boolean) value).booleanValue(), false);

         value = LocaleConvertUtils.convert("off", Boolean.class);
         assertTrue(value instanceof Boolean);
         assertEquals(((Boolean) value).booleanValue(), false);
         */

        value = LocaleConvertUtils.convert("123", Byte.TYPE);
        assertTrue(value instanceof Byte);
        assertEquals(((Byte) value).byteValue(), (byte) 123);

        value = LocaleConvertUtils.convert("123", Byte.class);
        assertTrue(value instanceof Byte);
        assertEquals(((Byte) value).byteValue(), (byte) 123);

        /*fixme Character conversion not implemented yet
        value = LocaleConvertUtils.convert("a", Character.TYPE);
        assertTrue(value instanceof Character);
        assertEquals(((Character) value).charValue(), 'a');

        value = LocaleConvertUtils.convert("a", Character.class);
        assertTrue(value instanceof Character);
        assertEquals(((Character) value).charValue(), 'a');
        */
        /* fixme - this is a discrepancy with standard converters ( probably not major issue )
        value = LocaleConvertUtils.convert("java.lang.String", Class.class);
        assertTrue(value instanceof Class);
        assertEquals(String.class, (Class) value);
        */

        value = LocaleConvertUtils.convert("123" + m_decimalSeparator + "456", Double.TYPE);
        assertTrue(value instanceof Double);
        assertEquals(((Double) value).doubleValue(), 123.456, 0.005);

        value = LocaleConvertUtils.convert("123" + m_decimalSeparator + "456", Double.class);
        assertTrue(value instanceof Double);
        assertEquals(((Double) value).doubleValue(), 123.456, 0.005);

        value = LocaleConvertUtils.convert("123" + m_decimalSeparator + "456", Float.TYPE);
        assertTrue(value instanceof Float);
        assertEquals(((Float) value).floatValue(), (float) 123.456,
                (float) 0.005);

        value = LocaleConvertUtils.convert("123" + m_decimalSeparator + "456", Float.class);
        assertTrue(value instanceof Float);
        assertEquals(((Float) value).floatValue(), (float) 123.456,
                (float) 0.005);

        value = LocaleConvertUtils.convert("123", Integer.TYPE);
        assertTrue(value instanceof Integer);
        assertEquals(((Integer) value).intValue(), 123);

        value = LocaleConvertUtils.convert("123", Integer.class);
        assertTrue(value instanceof Integer);
        assertEquals(((Integer) value).intValue(), 123);

        value = LocaleConvertUtils.convert("123", Long.TYPE);
        assertTrue(value instanceof Long);
        assertEquals(((Long) value).longValue(), 123);

        value = LocaleConvertUtils.convert("123456", Long.class);
        assertTrue(value instanceof Long);
        assertEquals(((Long) value).longValue(), 123456);

        /* fixme - Short conversion not implemented at this point
        value = LocaleConvertUtils.convert("123", Short.TYPE);
        assertTrue(value instanceof Short);
        assertEquals(((Short) value).shortValue(), (short) 123);

        value = LocaleConvertUtils.convert("123", Short.class);
        assertTrue(value instanceof Short);
        assertEquals(((Short) value).shortValue(), (short) 123);
        */

        String input = null;

        input = "2002-03-17";
        value = LocaleConvertUtils.convert(input, Date.class);
        assertTrue(value instanceof Date);
        assertEquals(input, value.toString());

        input = "20:30:40";
        value = LocaleConvertUtils.convert(input, Time.class);
        assertTrue(value instanceof Time);
        assertEquals(input, value.toString());

        input = "2002-03-17 20:30:40.0";
        value = LocaleConvertUtils.convert(input, Timestamp.class);
        assertTrue(value instanceof Timestamp);
        assertEquals(input, value.toString());

    }

    /**
     * Positive String to String array tests.
     */
    public void fixmetestPositiveStringArray() {

        fail("Array conversions not implemented yet.");

        Object value = null;
        final String stringArray[] = new String[0];
        final String stringArray1[] = new String[]
        {"abc"};
        final String stringArray2[] = new String[]
        {"abc", "de,f"};

        value = LocaleConvertUtils.convert("", stringArray.getClass());
        checkStringArray(value, stringArray);
        value = LocaleConvertUtils.convert(" ", stringArray.getClass());
        checkStringArray(value, stringArray);
        value = LocaleConvertUtils.convert("{}", stringArray.getClass());
        checkStringArray(value, stringArray);
        value = LocaleConvertUtils.convert("{  }", stringArray.getClass());
        checkStringArray(value, stringArray);

        value = LocaleConvertUtils.convert("abc", stringArray.getClass());
        checkStringArray(value, stringArray1);
        value = LocaleConvertUtils.convert("{abc}", stringArray.getClass());
        checkStringArray(value, stringArray1);
        value = LocaleConvertUtils.convert("\"abc\"", stringArray.getClass());
        checkStringArray(value, stringArray1);
        value = LocaleConvertUtils.convert("{\"abc\"}", stringArray.getClass());
        checkStringArray(value, stringArray1);
        value = LocaleConvertUtils.convert("'abc'", stringArray.getClass());
        checkStringArray(value, stringArray1);
        value = LocaleConvertUtils.convert("{'abc'}", stringArray.getClass());
        checkStringArray(value, stringArray1);

        value = LocaleConvertUtils.convert("abc 'de,f'",
                stringArray.getClass());
        checkStringArray(value, stringArray2);
        value = LocaleConvertUtils.convert("{abc, 'de,f'}",
                stringArray.getClass());
        checkStringArray(value, stringArray2);
        value = LocaleConvertUtils.convert("\"abc\",\"de,f\"",
                stringArray.getClass());
        checkStringArray(value, stringArray2);
        value = LocaleConvertUtils.convert("{\"abc\" 'de,f'}",
                stringArray.getClass());
        checkStringArray(value, stringArray2);
        value = LocaleConvertUtils.convert("'abc' 'de,f'",
                stringArray.getClass());
        checkStringArray(value, stringArray2);
        value = LocaleConvertUtils.convert("{'abc', \"de,f\"}",
                stringArray.getClass());
        checkStringArray(value, stringArray2);

    }

    /**
     * Test conversion of a String using a Locale and pattern.
     */
    public void testConvertStringLocaleNull() {
        Object result = null;
        try {
            result = LocaleConvertUtils.convert("123", Integer.class, (Locale)null, "#,###");
        } catch (final Exception e) {
            e.printStackTrace();
            fail("Threw: " + e);
        }
        assertNotNull("Null Result", result);
        assertEquals("Integer Type", Integer.class, result.getClass());
        assertEquals("Integer Value", new Integer(123), result);
    }

    /**
     * Test conversion of a String array using a Locale and pattern.
     */
    public void testConvertStringArrayLocaleNull() {
        Object result = null;
        try {
            result = LocaleConvertUtils.convert(new String[] {"123"}, Integer[].class, (Locale)null, "#,###");
        } catch (final Exception e) {
            e.printStackTrace();
            fail("Threw: " + e);
        }
        assertNotNull("Null Result", result);
        assertEquals("Integer Array Type", Integer[].class, result.getClass());
        assertEquals("Integer Array Length", 1, ((Integer[])result).length);
        assertEquals("Integer Array Value", new Integer(123), ((Integer[])result)[0]);
    }

    /**
     * Tests a conversion if there is no suitable converter registered. In this
     * case, the string converter is used, and the passed in target type is
     * ignored. (This test is added to prevent a regression after the locale
     * converters have been generified.)
     */
    public void testDefaultToStringConversionUnsupportedType() {
        final Integer value = 20131101;
        assertEquals("Wrong result", value.toString(),
                LocaleConvertUtils.convert(value.toString(), getClass()));
    }

    

    private void checkIntegerArray(final Object value, final int intArray[]) {

        assertNotNull("Returned value is not null", value);
        assertEquals("Returned value is int[]",
                intArray.getClass(), value.getClass());
        final int results[] = (int[]) value;
        assertEquals("Returned array length", intArray.length, results.length);
        for (int i = 0; i < intArray.length; i++) {
            assertEquals("Returned array value " + i,
                    intArray[i], results[i]);
        }

    }

    private void checkStringArray(final Object value, final String stringArray[]) {

        assertNotNull("Returned value is not null", value);
        assertEquals("Returned value is String[]",
                stringArray.getClass(), value.getClass());
        final String results[] = (String[]) value;
        assertEquals("Returned array length",
                stringArray.length, results.length);
        for (int i = 0; i < stringArray.length; i++) {
            assertEquals("Returned array value " + i,
                    stringArray[i], results[i]);
        }

    }

}

