/*
 * 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.lang.ref.ReferenceQueue;
import java.lang.ref.WeakReference;
import java.util.Locale;
import java.util.Map;
import java.util.WeakHashMap;

import org.apache.commons.beanutils2.BeanUtilsBean;
import org.apache.commons.beanutils2.BeanUtilsTestCase;
import org.apache.commons.beanutils2.ContextClassLoaderLocal;
import org.apache.commons.beanutils2.ConversionException;
import org.apache.commons.beanutils2.ConvertUtils;
import org.apache.commons.beanutils2.PrimitiveBean;
import org.apache.commons.beanutils2.locale.converters.LongLocaleConverter;
import org.apache.commons.logging.LogFactory;

import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;

/**
 * <p>
 * Test Case for changes made during LocaleBeanutils Beanification.
 * This is basically a cut-and-correct version of the beanutils beanifications tests.
 * </p>
 *
 */

public class LocaleBeanificationTestCase extends TestCase {



    /** Maximum number of iterations before our test fails */
    public static final int MAX_GC_ITERATIONS = 50;







    /**
     * Construct a new instance of this test case.
     *
     * @param name Name of the test case
     */
    public LocaleBeanificationTestCase(final String name) {
        super(name);
    }





    /**
     * Set up instance variables required by this test case.
     */
    @Override
    public void setUp() {

        LocaleConvertUtils.deregister();

    }


    /**
     * Return the tests included in this test suite.
     */
    public static Test suite() {
        return new TestSuite(LocaleBeanificationTestCase.class);
    }


    /**
     * Tear down instance variables required by this test case.
     */
    @Override
    public void tearDown() {
        // No action required
    }




    /** Test of the methodology we'll use for some of the later tests */
    public void testMemoryTestMethodology() throws Exception {
        // test methodology
        // many thanks to Juozas Baliuka for suggesting this method
        ClassLoader loader = new ClassLoader(this.getClass().getClassLoader()) {};
        final WeakReference<ClassLoader> reference = new  WeakReference<>(loader);
        Class<?> myClass = loader.loadClass("org.apache.commons.beanutils2.BetaBean");

        assertNotNull("Weak reference released early", reference.get());

        // dereference class loader and class:
        loader = null;
        myClass = null;

        int iterations = 0;
        int bytz = 2;
        while(true) {
            System.gc();
            if(iterations++ > MAX_GC_ITERATIONS){
                fail("Max iterations reached before resource released.");
            }
            if( reference.get() == null ) {
                break;

            }
            // create garbage:
            final byte[] b =  new byte[bytz];
            bytz = bytz * 2;
        }
    }

    /** Tests whether classloaders and beans are released from memory by the map used by beanutils */
    public void testMemoryLeak2() throws Exception {
        // tests when the map used by beanutils has the right behavior

        if (BeanUtilsTestCase.isPre14JVM()) {
            System.out.println("WARNING: CANNOT TEST MEMORY LEAK ON PRE1.4 JVM");
            return;
        }

        // many thanks to Juozas Baliuka for suggesting this methodology
        TestClassLoader loader = new TestClassLoader();
        final ReferenceQueue<Object> queue = new ReferenceQueue<>();
        final WeakReference<ClassLoader> loaderReference = new WeakReference<>(loader, queue);
        Integer test = new Integer(1);

        final WeakReference<Integer> testReference = new WeakReference<>(test, queue);
        //Map map = new ReferenceMap(ReferenceMap.WEAK, ReferenceMap.HARD, true);
        final Map<TestClassLoader, Integer> map = new WeakHashMap<>();
        map.put(loader, test);

        assertEquals("In map", test, map.get(loader));
        assertNotNull("Weak reference released early (1)", loaderReference.get());
        assertNotNull("Weak reference released early (2)", testReference.get());

        // dereference strong references
        loader = null;
        test = null;

        int iterations = 0;
        int bytz = 2;
        while(true) {
            System.gc();
            if(iterations++ > MAX_GC_ITERATIONS){
                fail("Max iterations reached before resource released.");
            }
            map.isEmpty();

            if(
                loaderReference.get() == null &&
                testReference.get() == null) {
                break;

            }
            // create garbage:
            final byte[] b =  new byte[bytz];
            bytz = bytz * 2;
        }
    }

    /** Tests whether classloaders and beans are released from memory */
    public void testMemoryLeak() throws Exception {
        if (BeanUtilsTestCase.isPre14JVM()) {
            System.out.println("WARNING: CANNOT TEST MEMORY LEAK ON PRE1.4 JVM");
            return;
        }

        // many thanks to Juozas Baliuka for suggesting this methodology
        TestClassLoader loader = new TestClassLoader();
        final WeakReference<TestClassLoader> loaderReference = new  WeakReference<>(loader);
        LocaleBeanUtilsBean.getLocaleBeanUtilsInstance();

        class GetBeanUtilsBeanThread extends Thread {

            LocaleBeanUtilsBean beanUtils;
            LocaleConvertUtilsBean convertUtils;

            GetBeanUtilsBeanThread() {}

            @Override
            public void run() {
                beanUtils = LocaleBeanUtilsBean.getLocaleBeanUtilsInstance();
                convertUtils = LocaleConvertUtilsBean.getInstance();
                // XXX Log keeps a reference around!
                LogFactory.releaseAll();
            }

            @Override
            public String toString() {
                return "GetBeanUtilsBeanThread";
            }
        }


        GetBeanUtilsBeanThread thread = new GetBeanUtilsBeanThread();
        final WeakReference<GetBeanUtilsBeanThread> threadWeakReference = new WeakReference<>(thread);
        thread.setContextClassLoader(loader);

        thread.start();
        thread.join();

        final WeakReference<LocaleBeanUtilsBean> beanUtilsReference = new WeakReference<>(thread.beanUtils);
        final WeakReference<LocaleConvertUtilsBean> convertUtilsReference = new WeakReference<>(thread.convertUtils);

        assertNotNull("Weak reference released early (1)", loaderReference.get());
        assertNotNull("Weak reference released early (2)", beanUtilsReference.get());
        assertNotNull("Weak reference released early (4)", convertUtilsReference.get());

        // dereference strong references
        loader = null;
        thread.setContextClassLoader(null);
        thread = null;

        int iterations = 0;
        int bytz = 2;
        while(true) {
            LocaleBeanUtilsBean.getLocaleBeanUtilsInstance();
            System.gc();
            if(iterations++ > MAX_GC_ITERATIONS){
                fail("Max iterations reached before resource released.");
            }

            if(
                loaderReference.get() == null &&
                beanUtilsReference.get() == null &&
                convertUtilsReference.get() == null) {
                break;

            }
            // create garbage:
            final byte[] b =  new byte[bytz];
            bytz = bytz * 2;
        }
    }

    /**
     * Tests whether difference instances are loaded by different
     * context classloaders.
     */
    public void testGetByContextClassLoader() throws Exception {

        class GetBeanUtilsBeanThread extends Thread {

            private final Signal signal;

            GetBeanUtilsBeanThread(final Signal signal) {
                this.signal = signal;
            }

            @Override
            public void run() {
                signal.setSignal(2);
                signal.setBean(LocaleBeanUtilsBean.getLocaleBeanUtilsInstance());
                signal.setConvertUtils(LocaleConvertUtilsBean.getInstance());
            }

            @Override
            public String toString() {
                return "GetBeanUtilsBeanThread";
            }
        }

        final Signal signal = new Signal();
        signal.setSignal(1);

        final GetBeanUtilsBeanThread thread = new GetBeanUtilsBeanThread(signal);
        thread.setContextClassLoader(new TestClassLoader());

        thread.start();
        thread.join();

        assertEquals("Signal not set by test thread", 2, signal.getSignal());
        assertTrue(
                    "Different LocaleBeanUtilsBean instances per context classloader",
                    BeanUtilsBean.getInstance() != signal.getBean());
        assertTrue(
                    "Different LocaleConvertUtilsBean instances per context classloader",
                    LocaleConvertUtilsBean.getInstance() != signal.getConvertUtils());
    }


    /**
     * Tests whether difference instances are loaded by different
     * context classloaders.
     */
    public void testContextClassLoaderLocal() throws Exception {

        class CCLLTesterThread extends Thread {

            private final Signal signal;
            private final ContextClassLoaderLocal<Integer> ccll;

            CCLLTesterThread(final Signal signal, final ContextClassLoaderLocal<Integer> ccll) {
                this.signal = signal;
                this.ccll = ccll;
            }

            @Override
            public void run() {
                ccll.set(new Integer(1789));
                signal.setSignal(2);
                signal.setMarkerObject(ccll.get());
            }

            @Override
            public String toString() {
                return "CCLLTesterThread";
            }
        }

        final ContextClassLoaderLocal<Integer> ccll = new ContextClassLoaderLocal<>();
        ccll.set(1776);
        assertEquals("Start thread sets value", new Integer(1776), ccll.get());

        final Signal signal = new Signal();
        signal.setSignal(1);

        final CCLLTesterThread thread = new CCLLTesterThread(signal, ccll);
        thread.setContextClassLoader(new TestClassLoader());

        thread.start();
        thread.join();

        assertEquals("Signal not set by test thread", 2, signal.getSignal());
        assertEquals("Second thread preserves value", new Integer(1776), ccll.get());
        assertEquals("Second thread gets value it set", new Integer(1789), signal.getMarkerObject());
    }

    /** Tests whether calls are independent for different classloaders */
    public void testContextClassloaderIndependence() throws Exception {

        class TestIndependenceThread extends Thread {
            private final Signal signal;
            private final PrimitiveBean bean;

            TestIndependenceThread(final Signal signal, final PrimitiveBean bean) {
                this.signal = signal;
                this.bean = bean;
            }

            @Override
            public void run() {
                try {
                    signal.setSignal(3);
                    LocaleConvertUtils.register(new LocaleConverter() {
                                            @Override
                                            public <T> T convert(final Class<T> type, final Object value) {
                                                return ConvertUtils.primitiveToWrapper(type).cast(9);
                                            }
                                            @Override
                                            public <T> T convert(final Class<T> type, final Object value, final String pattern) {
                                                return ConvertUtils.primitiveToWrapper(type).cast(9);
                                            }
                                                }, Integer.TYPE, Locale.getDefault());
                    LocaleBeanUtils.setProperty(bean, "int", "1");
                } catch (final Exception e) {
                    e.printStackTrace();
                    signal.setException(e);
                }
            }

            @Override
            public String toString() {
                return "TestIndependenceThread";
            }
        }

        final PrimitiveBean bean = new PrimitiveBean();
        LocaleBeanUtils.setProperty(bean, "int", new Integer(1));
        assertEquals("Wrong property value (1)", 1, bean.getInt());

        LocaleConvertUtils.register(new LocaleConverter() {
                                @Override
                                public <T> T convert(final Class<T> type, final Object value) {
                                    return ConvertUtils.primitiveToWrapper(type).cast(5);
                                }
                                @Override
                                public <T> T convert(final Class<T> type, final Object value, final String pattern) {
                                    return ConvertUtils.primitiveToWrapper(type).cast(5);
                                }
                                    }, Integer.TYPE, Locale.getDefault());
        LocaleBeanUtils.setProperty(bean, "int", "1");
        assertEquals("Wrong property value(2)", 5, bean.getInt());

        final Signal signal = new Signal();
        signal.setSignal(1);
        final TestIndependenceThread thread = new TestIndependenceThread(signal, bean);
        thread.setContextClassLoader(new TestClassLoader());

        thread.start();
        thread.join();

        assertNull("Exception thrown by test thread:" + signal.getException(), signal.getException());
        assertEquals("Signal not set by test thread", 3, signal.getSignal());
        assertEquals("Wrong property value(3)", 9, bean.getInt());

    }

    /** Tests whether different threads can set beanutils instances correctly */
    public void testBeanUtilsBeanSetInstance() throws Exception {

        class SetInstanceTesterThread extends Thread {

            private final Signal signal;
            private final LocaleBeanUtilsBean bean;

            SetInstanceTesterThread(final Signal signal, final LocaleBeanUtilsBean bean) {
                this.signal = signal;
                this.bean = bean;
            }

            @Override
            public void run() {
                LocaleBeanUtilsBean.setInstance(bean);
                signal.setSignal(21);
                signal.setBean(LocaleBeanUtilsBean.getLocaleBeanUtilsInstance());
            }

            @Override
            public String toString() {
                return "SetInstanceTesterThread";
            }
        }

        final Signal signal = new Signal();
        signal.setSignal(1);

        final LocaleBeanUtilsBean beanOne = new LocaleBeanUtilsBean();
        final LocaleBeanUtilsBean beanTwo = new LocaleBeanUtilsBean();

        final SetInstanceTesterThread thread = new SetInstanceTesterThread(signal, beanTwo);
        thread.setContextClassLoader(new TestClassLoader());

        LocaleBeanUtilsBean.setInstance(beanOne);
        assertEquals("Start thread gets right instance", beanOne, LocaleBeanUtilsBean.getLocaleBeanUtilsInstance());

        thread.start();
        thread.join();

        assertEquals("Signal not set by test thread", 21, signal.getSignal());
        assertEquals("Second thread preserves value", beanOne, LocaleBeanUtilsBean.getLocaleBeanUtilsInstance());
        assertEquals("Second thread gets value it set", beanTwo, signal.getBean());
    }

    /** Tests whether the unset method works*/
    public void testContextClassLoaderUnset() throws Exception {
        final LocaleBeanUtilsBean beanOne = new LocaleBeanUtilsBean();
        final ContextClassLoaderLocal<LocaleBeanUtilsBean> ccll = new ContextClassLoaderLocal<>();
        ccll.set(beanOne);
        assertEquals("Start thread gets right instance", beanOne, ccll.get());
        ccll.unset();
        assertTrue("Unset works", !beanOne.equals(ccll.get()));
    }

    /**
     * Test registering a locale-aware converter with the standard ConvertUtils.
     */
    public void testLocaleAwareConverterInConvertUtils() throws Exception {
        try {
            // first use the default non-locale-aware converter
            try {
                final Long data = (Long) ConvertUtils.convert("777", Long.class);
                assertEquals("Standard format long converted ok", 777, data.longValue());
            }
            catch(final ConversionException ex) {
                fail("Unable to convert non-locale-aware number 777");
            }

            // now try default converter with special delimiters
            try {
                // This conversion will cause an error. But the default
                // Long converter is set up to return a default value of
                // zero on error.
                final Long data = (Long) ConvertUtils.convert("1.000.000", Long.class);
                assertEquals("Standard format behaved as expected", 0, data.longValue());
            }
            catch(final ConversionException ex) {
                fail("Unexpected exception from standard Long converter.");
            }

            // Now try using a locale-aware converter together with
            // locale-specific input string. Note that in the german locale,
            // large numbers can be split up into groups of three digits
            // using a dot character (and comma is the decimal-point indicator).
            try {

                final Locale germanLocale = Locale.GERMAN;
                final LongLocaleConverter longLocaleConverter = new LongLocaleConverter(germanLocale);
                ConvertUtils.register(longLocaleConverter, Long.class);

                final Long data = (Long) ConvertUtils.convert("1.000.000", Long.class);
                assertEquals("German-format long converted ok", 1000000, data.longValue());
            } catch(final ConversionException ex) {
                fail("Unable to convert german-format number");
            }
        } finally {
            ConvertUtils.deregister();
        }
    }

    // ---- Auxillary classes

    class TestClassLoader extends ClassLoader {
        @Override
        public String toString() {
            return "TestClassLoader";
        }
    }

    class Signal {
        private Exception e;
        private int signal = 0;
        private LocaleBeanUtilsBean bean;
        private LocaleConvertUtilsBean convertUtils;
        private Object marker;

        public Exception getException() {
            return e;
        }

        public void setException(final Exception e) {
            this.e = e;
        }

        public int getSignal() {
            return signal;
        }

        public void setSignal(final int signal) {
            this.signal = signal;
        }

        public Object getMarkerObject() {
            return marker;
        }

        public void setMarkerObject(final Object marker) {
            this.marker = marker;
        }

        public LocaleBeanUtilsBean getBean() {
            return bean;
        }

        public void setBean(final LocaleBeanUtilsBean bean) {
            this.bean = bean;
        }

        public LocaleConvertUtilsBean getConvertUtils() {
            return convertUtils;
        }

        public void setConvertUtils(final LocaleConvertUtilsBean convertUtils) {
            this.convertUtils = convertUtils;
        }
    }
}

