/*
 * 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.text.ParseException;
import java.util.Locale;

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


/**
 * <p>The base class for all standard type locale-sensitive converters.
 * It has {@link LocaleConverter} and {@link org.apache.commons.beanutils2.Converter} implementations,
 * that convert an incoming locale-sensitive Object into an object of correspond type,
 * optionally using a default value or throwing a {@link ConversionException}
 * if a conversion error occurs.</p>
 *
 */

public abstract class BaseLocaleConverter implements LocaleConverter {

    

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

    /** The default value specified to our Constructor, if any. */
    private Object defaultValue = null;

    /** Should we return the default value on conversion errors? */
    protected boolean useDefault = false;

    /** The locale specified to our Constructor, by default - system locale. */
    protected Locale locale = Locale.getDefault();

    /** The default pattern specified to our Constructor, if any. */
    protected String pattern = null;

    /** The flag indicating whether the given pattern string is localized or not. */
    protected boolean locPattern = false;

    

    /**
     * Create a {@link LocaleConverter} that will throw a {@link ConversionException}
     * if a conversion error occurs.
     * An unlocalized pattern is used for the conversion.
     *
     * @param locale        The locale
     * @param pattern       The conversion pattern
     */
    protected BaseLocaleConverter(final Locale locale, final String pattern) {

        this(null, locale, pattern, false, false);
    }

    /**
     * Create a {@link LocaleConverter} that will throw a {@link ConversionException}
     * if a conversion error occurs.
     *
     * @param locale        The locale
     * @param pattern       The conversion pattern
     * @param locPattern    Indicate whether the pattern is localized or not
     */
    protected BaseLocaleConverter(final Locale locale, final String pattern, final boolean locPattern) {

        this(null, locale, pattern, false, locPattern);
    }

    /**
     * Create a {@link LocaleConverter} that will return the specified default value
     * if a conversion error occurs.
     * An unlocalized pattern is used for the conversion.
     *
     * @param defaultValue  The default value to be returned
     * @param locale        The locale
     * @param pattern       The conversion pattern
     */
    protected BaseLocaleConverter(final Object defaultValue, final Locale locale, final String pattern) {

        this(defaultValue, locale, pattern, false);
    }

    /**
     * Create a {@link LocaleConverter} that will return the specified default value
     * if a conversion error occurs.
     *
     * @param defaultValue  The default value to be returned
     * @param locale        The locale
     * @param pattern       The conversion pattern
     * @param locPattern    Indicate whether the pattern is localized or not
     */
    protected BaseLocaleConverter(final Object defaultValue, final Locale locale, final String pattern, final boolean locPattern) {

        this(defaultValue, locale, pattern, true, locPattern);
    }

    /**
     * Create a {@link LocaleConverter} that will return the specified default value
     * or throw a {@link ConversionException} if a conversion error occurs.
     *
     * @param defaultValue  The default value to be returned
     * @param locale        The locale
     * @param pattern       The conversion pattern
     * @param useDefault    Indicate whether the default value is used or not
     * @param locPattern    Indicate whether the pattern is localized or not
     */
    private BaseLocaleConverter(final Object defaultValue, final Locale locale,
                                final String pattern, final boolean useDefault, final boolean locPattern) {

        if (useDefault) {
            this.defaultValue = defaultValue;
            this.useDefault = true;
        }

        if (locale != null) {
            this.locale = locale;
        }

        this.pattern = pattern;
        this.locPattern = locPattern;
    }

    

    /**
     * Convert the specified locale-sensitive input object into an output object of the
     * specified type.
     *
     * @param value The input object to be converted
     * @param pattern The pattern is used for the conversion
     * @return The converted value
     *
     * @throws ParseException if conversion cannot be performed
     *  successfully
     */

    abstract protected Object parse(Object value, String pattern) throws ParseException;


    /**
     * Convert the specified locale-sensitive input object into an output object.
     * The default pattern is used for the conversion.
     *
     * @param value The input object to be converted
     * @return The converted value
     *
     * @throws ConversionException if conversion cannot be performed
     *  successfully
     */
    public Object convert(final Object value) {
        return convert(value, null);
    }

    /**
     * Convert the specified locale-sensitive input object into an output object.
     *
     * @param value The input object to be converted
     * @param pattern The pattern is used for the conversion
     * @return The converted value
     *
     * @throws ConversionException if conversion cannot be performed
     *  successfully
     */
    public Object convert(final Object value, final String pattern) {
        return convert(null, value, pattern);
    }

    /**
     * Convert the specified locale-sensitive input object into an output object of the
     * specified type. The default pattern is used for the conversion.
     *
     * @param <T> The desired target type of the conversion
     * @param type Data type to which this value should be converted
     * @param value The input object to be converted
     * @return The converted value
     *
     * @throws ConversionException if conversion cannot be performed
     *  successfully
     */
    @Override
    public <T> T convert(final Class<T> type, final Object value) {
        return convert(type, value, null);
    }

    /**
     * Convert the specified locale-sensitive input object into an output object of the
     * specified type.
     *
     * @param <T> The desired target type of the conversion
     * @param type Data is type to which this value should be converted
     * @param value is the input object to be converted
     * @param pattern is the pattern is used for the conversion; if null is
     * passed then the default pattern associated with the converter object
     * will be used.
     * @return The converted value
     *
     * @throws ConversionException if conversion cannot be performed
     *  successfully
     */
    @Override
    public <T> T convert(final Class<T> type, final Object value, final String pattern) {
        final Class<T> targetType = ConvertUtils.primitiveToWrapper(type);
        if (value == null) {
            if (useDefault) {
                return getDefaultAs(targetType);
            }
            // symmetric beanutils function allows null
            // so do not: throw new ConversionException("No value specified");
            log.debug("Null value specified for conversion, returing null");
            return null;
        }

        try {
            if (pattern != null) {
                return checkConversionResult(targetType, parse(value, pattern));
            }
            return checkConversionResult(targetType, parse(value, this.pattern));
        } catch (final Exception e) {
            if (useDefault) {
                return getDefaultAs(targetType);
            }
            if (e instanceof ConversionException) {
                throw (ConversionException)e;
            }
            throw new ConversionException(e);
        }
    }

    /**
     * Returns the default object specified for this converter cast for the
     * given target type. If the default value is not conform to the given type,
     * an exception is thrown.
     *
     * @param <T> the desired target type
     * @param type the target class of the conversion
     * @return the default value in the given target type
     * @throws ConversionException if the default object is not compatible with
     *         the target type
     */
    private <T> T getDefaultAs(final Class<T> type) {
        return checkConversionResult(type, defaultValue);
    }

    /**
     * Checks whether the result of a conversion is conform to the specified
     * target type. If this is the case, the passed in result object is cast to
     * the correct target type. Otherwise, an exception is thrown.
     *
     * @param <T> the desired result type
     * @param type the target class of the conversion
     * @param result the conversion result object
     * @return the result cast to the target class
     * @throws ConversionException if the result object is not compatible with
     *         the target type
     */
    private static <T> T checkConversionResult(final Class<T> type, final Object result) {
        if (type == null) {
            // in this case we cannot do much; the result object is returned
            @SuppressWarnings("unchecked")
            final
            T temp = (T) result;
            return temp;
        }

        if (result == null) {
            return null;
        }
        if (type.isInstance(result)) {
            return type.cast(result);
        }
        throw new ConversionException("Unsupported target type: " + type);
    }
}
