/*
 * 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.converters;

import java.text.DateFormatSymbols;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Locale;

import org.apache.commons.beanutils2.ConversionException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
 * Test Case for the DateLocaleConverter class.
 *
 */

public class DateLocaleConverterTestCase extends BaseLocaleConverterTestCase {

    /** All logging goes through this logger */
    private final Log log = LogFactory.getLog(DateLocaleConverterTestCase.class);

    protected String localizedDatePattern;
    protected String localizedDateValue;
    protected String localizedShortDateValue;
    protected String defaultDatePattern;
    protected String defaultDateValue;
    protected String defaultShortDateValue;

    protected boolean validLocalDateSymbols;

    

    public DateLocaleConverterTestCase(final String name) {
        super(name);
    }

    

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

        super.setUp();

        final String version = System.getProperty("java.specification.version");
        log.debug("JDK Version "+version);


        try {
            final SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd");
            expectedValue      = format.parse("20041001");
            defaultValue       = format.parse("19670316");
        } catch (final Exception ex) {
            log.error("Error creating expected/default dates", ex);
        }

        // Default Locale (Use US)
        defaultLocale           = Locale.US;
        defaultDatePattern      = "d MMMM yyyy";
        defaultDateValue        = "1 October 2004";
        defaultShortDateValue   = "10/01/04";

        // Use German Locale
//        localizedLocale         = Locale.GERMAN;  // N.B. doesn't work for dates
//        localizedLocale         = Locale.GERMANY; // N.B. doesn't work for dates
        localizedLocale         = new Locale("de", "AT"); // Austria/German works
        localizedDatePattern    = "t MMMM uuuu";
        localizedDateValue      = "1 Oktober 2004";
        localizedShortDateValue = "01.10.04";

        // Test whether the "local pattern characters" are what we
        // are expecting - Locale.GERMAN and Locale.GERMANY, Locale.FRENCH all
        // returned the standard "English" pattern characters on my machine
        // for JDK 1.4 (JDK 1.3 was OK). The Austria/German locale was OK though
        final String expectedChars = "GuMtkHmsSEDFwWahKzZ";
        final DateFormatSymbols localizedSymbols = new DateFormatSymbols(localizedLocale);
        final String localChars    = localizedSymbols.getLocalPatternChars();

        // different JDK versions seem to have different numbers of pattern characters
        final int lth = localChars.length() > expectedChars.length() ? expectedChars.length() :
                     localChars.length() < expectedChars.length() ? localChars.length() : expectedChars.length();
        validLocalDateSymbols = expectedChars.substring(0, lth).equals(localChars.substring(0, lth));

    }

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


    

    public void testSetLenient() {
        // make sure that date format works as expected
        final SimpleDateFormat dateFormat = new SimpleDateFormat("MMM dd, yyyy", Locale.UK);

        // test with no leniency
        dateFormat.setLenient(false);

        try {

            dateFormat.parse("Feb 10, 2001");

        } catch (final ParseException e) {
            fail("Could not parse date (1) - " + e.getMessage());
        }

        try {

            dateFormat.parse("Feb 31, 2001");
            fail("Parsed illegal date (1)");

        } catch (final ParseException e) {
            // that's what we expected
        }

        // test with leniency
        dateFormat.setLenient(true);

        try {

            dateFormat.parse("Feb 10, 2001");

        } catch (final ParseException e) {
            fail("Could not parse date (2) - " + e.getMessage());
        }

        try {

            dateFormat.parse("Feb 31, 2001");

        } catch (final ParseException e) {
            fail("Could not parse date (3) - " + e.getMessage());
        }

        // now repeat tests for converter
        final DateLocaleConverter converter = new DateLocaleConverter(Locale.UK, "MMM dd, yyyy");

        // test with no leniency
        converter.setLenient(false);
        assertEquals("Set lenient failed", converter.isLenient(), false);

        try {

            converter.convert("Feb 10, 2001");

        } catch (final ConversionException e) {
            fail("Could not parse date (4) - " + e.getMessage());
        }

        try {

            converter.convert("Feb 31, 2001");
            assertEquals("Set lenient failed", converter.isLenient(), false);
            fail("Parsed illegal date (2)");

        } catch (final ConversionException e) {
            // that's what we expected
        }

        // test with leniency
        converter.setLenient(true);
        assertEquals("Set lenient failed", converter.isLenient(), true);

        try {

            converter.convert("Feb 10, 2001");

        } catch (final ConversionException e) {
            fail("Could not parse date (5) - " + e.getMessage());
        }

        try {

            converter.convert("Feb 31, 2001");

        } catch (final ConversionException e) {
            fail("Could not parse date (6) - " + e.getMessage());
        }
    }

    /**
     * Test Converter(defaultValue, locale, pattern, localizedPattern) constructor
     */
    public void testConstructorMain() {

        // Skip this test if no valid symbols for the locale
        if (!validLocalDateSymbols) {
            log.error("Invalid locale symbols *** skipping testConstructorMain() **");
            return;
        }

        // ------------- Construct with localized pattern ------------
        converter = new DateLocaleConverter(defaultValue,
                                            localizedLocale,
                                            localizedDatePattern,
                                            true);


        convertValueNoPattern(converter, "(A)", localizedDateValue, expectedValue);
        convertValueWithPattern(converter, "(A)", localizedDateValue, localizedDatePattern, expectedValue);
        convertInvalid(converter, "(A)", defaultValue);
        convertNull(converter, "(A)", defaultValue);


        // Convert value in the wrong format - should return default value
        convertValueNoPattern(converter, "(B)", defaultDateValue, defaultValue);

        // Convert with non-localized pattern - should return default value
        convertValueWithPattern(converter, "(B)", localizedDateValue, defaultDatePattern, defaultValue);

        // **************************************************************************
        // Convert with specified type
        //
        // BaseLocaleConverter completely ignores the type - so even if we specify
        // Double.class here it still returns a Date.
        //  **** This has been changed due to BEANUTILS-449 ****
        // **************************************************************************
        //convertValueToType(converter, "(B)", String.class, localizedDateValue, localizedDatePattern, expectedValue);


        // ------------- Construct with non-localized pattern ------------
        converter = new DateLocaleConverter(defaultValue,
                                            localizedLocale,
                                            defaultDatePattern,
                                            false);


        convertValueNoPattern(converter, "(C)", localizedDateValue, expectedValue);
        convertValueWithPattern(converter, "(C)", localizedDateValue, defaultDatePattern, expectedValue);
        convertInvalid(converter, "(C)", defaultValue);
        convertNull(converter, "(C)", defaultValue);

    }

    /**
     * Test Converter() constructor
     *
     * Uses the default locale, no default value
     *
     */
    public void testConstructor_2() {

        // ------------- Construct using default pattern & default locale ------------
        converter = new DateLocaleConverter();

        // Perform Tests
        convertValueNoPattern(converter, defaultShortDateValue, expectedValue);
        convertValueWithPattern(converter, defaultDateValue, defaultDatePattern, expectedValue);
        convertInvalid(converter, null);
        convertNull(converter, null);

    }

    /**
     * Test Converter(locPattern) constructor
     *
     * Uses the default locale, no default value
     *
     */
    public void testConstructor_3() {

        // ------------- Construct using default pattern & default locale --------
        converter = new DateLocaleConverter(true);

        // Perform Tests
        convertValueNoPattern(converter, defaultShortDateValue, expectedValue);
        convertValueWithPattern(converter, defaultDateValue, defaultDatePattern, expectedValue);
        convertInvalid(converter, null);
        convertNull(converter, null);


    }

    /**
     * Test Converter(Locale) constructor
     */
    public void testConstructor_4() {

        // ------------- Construct using specified Locale --------
        converter = new DateLocaleConverter(localizedLocale);

        // Perform Tests
        convertValueNoPattern(converter, localizedShortDateValue, expectedValue);
        convertValueWithPattern(converter, localizedDateValue, defaultDatePattern, expectedValue);
        convertInvalid(converter, null);
        convertNull(converter, null);


    }


    /**
     * Test Converter(Locale, locPattern) constructor
     */
    public void testConstructor_5() {

        // Skip this test if no valid symbols for the locale
        if (!validLocalDateSymbols) {
            log.error("Invalid locale symbols *** skipping testConstructor_5() **");
            return;
        }

        // ------------- Construct using specified Locale --------
        converter = new DateLocaleConverter(localizedLocale, true);

        // Perform Tests
        convertValueNoPattern(converter, localizedShortDateValue, expectedValue);
        convertValueWithPattern(converter, localizedDateValue, localizedDatePattern, expectedValue);
        convertInvalid(converter, null);
        convertNull(converter, null);


    }

    /**
     * Test Converter(Locale, pattern) constructor
     */
    public void testConstructor_6() {

        // ------------- Construct using specified Locale --------
        converter = new DateLocaleConverter(localizedLocale, defaultDatePattern);

        // Perform Tests
        convertValueNoPattern(converter, localizedDateValue, expectedValue);
        convertValueWithPattern(converter, localizedDateValue, defaultDatePattern, expectedValue);
        convertInvalid(converter, null);
        convertNull(converter, null);

    }

    /**
     * Test Converter(Locale, pattern, locPattern) constructor
     */
    public void testConstructor_7() {

        // Skip this test if no valid symbols for the locale
        if (!validLocalDateSymbols) {
            log.error("Invalid locale symbols *** skipping testConstructor_7() **");
            return;
        }

        // ------------- Construct using specified Locale --------
        converter = new DateLocaleConverter(localizedLocale, localizedDatePattern, true);

        // Perform Tests
        convertValueNoPattern(converter, localizedDateValue, expectedValue);
        convertValueWithPattern(converter, localizedDateValue, localizedDatePattern, expectedValue);
        convertInvalid(converter, null);
        convertNull(converter, null);

    }

    /**
     * Test Converter(defaultValue) constructor
     */
    public void testConstructor_8() {

        // ------------- Construct using specified Locale --------
        converter = new DateLocaleConverter(defaultValue);

        // Perform Tests
        convertValueNoPattern(converter, defaultShortDateValue, expectedValue);
        convertValueWithPattern(converter, defaultDateValue, defaultDatePattern, expectedValue);
        convertInvalid(converter, defaultValue);
        convertNull(converter, defaultValue);

    }

    /**
     * Test Converter(defaultValue, locPattern) constructor
     */
    public void testConstructor_9() {

        // ------------- Construct using specified Locale --------
        converter = new DateLocaleConverter(defaultValue, true);

        // Perform Tests
        convertValueNoPattern(converter, defaultShortDateValue, expectedValue);
        convertValueWithPattern(converter, defaultDateValue, defaultDatePattern, expectedValue);
        convertInvalid(converter, defaultValue);
        convertNull(converter, defaultValue);

    }

    /**
     * Test invalid date
     */
    public void testInvalidDate() {

        converter = new DateLocaleConverter(defaultLocale);

        try {
            converter.convert("01/10/2004", "dd-MM-yyyy");
        } catch (final ConversionException e) {
            assertEquals("Parse Error", "Error parsing date '01/10/2004' at position=2", e.getMessage());
        }

        try {
            converter.convert("01-10-2004X", "dd-MM-yyyy");
        } catch (final ConversionException e) {
            assertEquals("Parse Length", "Date '01-10-2004X' contains unparsed characters from position=10", e.getMessage());
        }

    }

    /**
     * Test java.util.Date
     */
    public void testDateObject() {
        converter = new DateLocaleConverter(defaultLocale);
        assertEquals("java.util.Date", expectedValue, converter.convert(expectedValue));
    }

    /**
     * Test Calendar
     */
    public void testCalendarObject() {
        converter = new DateLocaleConverter(defaultLocale);
        final java.util.Calendar calendar = java.util.Calendar.getInstance();
        calendar.setTime((java.util.Date)expectedValue);
        assertEquals("java.util.Calendar", expectedValue, converter.convert(calendar));
    }

}

