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

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NameNotFoundException;
import javax.naming.NamingException;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Properties;

import org.apache.commons.configuration2.event.ConfigurationErrorEvent;
import org.apache.commons.configuration2.event.ErrorListenerTestImpl;
import org.apache.commons.configuration2.event.EventListener;
import org.apache.commons.configuration2.event.EventType;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

/**
 * Test to see if the JNDIConfiguration works properly.
 *
 */
public class TestJNDIConfiguration {

    public static final String CONTEXT_FACTORY = MockInitialContextFactory.class.getName();

    private PotentialErrorJNDIConfiguration conf;
    private NonStringTestHolder nonStringTestHolder;

    /** A test error listener for counting internal errors. */
    private ErrorListenerTestImpl listener;

    @Before
    public void setUp() throws Exception {

        System.setProperty("java.naming.factory.initial", CONTEXT_FACTORY);

        final Properties props = new Properties();
        props.put("java.naming.factory.initial", CONTEXT_FACTORY);
        final Context ctx = new InitialContext(props);
        conf = new PotentialErrorJNDIConfiguration(ctx);

        nonStringTestHolder = new NonStringTestHolder();
        nonStringTestHolder.setConfiguration(conf);

        listener = new ErrorListenerTestImpl(conf);
        conf.addEventListener(ConfigurationErrorEvent.ANY, listener);
    }

    /**
     * Clears the test environment. If an error listener is defined, checks whether no error event was received.
     */
    @After
    public void tearDown() throws Exception {
        if (listener != null) {
            listener.done();
        }
    }

    @Test
    public void testBoolean() throws Exception {
        nonStringTestHolder.testBoolean();
    }

    @Test
    public void testBooleanDefaultValue() throws Exception {
        nonStringTestHolder.testBooleanDefaultValue();
    }

    @Test
    public void testByte() throws Exception {
        nonStringTestHolder.testByte();
    }

    @Test
    public void testDouble() throws Exception {
        nonStringTestHolder.testDouble();
    }

    @Test
    public void testDoubleDefaultValue() throws Exception {
        nonStringTestHolder.testDoubleDefaultValue();
    }

    @Test
    public void testFloat() throws Exception {
        nonStringTestHolder.testFloat();
    }

    @Test
    public void testFloatDefaultValue() throws Exception {
        nonStringTestHolder.testFloatDefaultValue();
    }

    @Test
    public void testInteger() throws Exception {
        nonStringTestHolder.testInteger();
    }

    @Test
    public void testIntegerDefaultValue() throws Exception {
        nonStringTestHolder.testIntegerDefaultValue();
    }

    @Test
    public void testLong() throws Exception {
        nonStringTestHolder.testLong();
    }

    @Test
    public void testLongDefaultValue() throws Exception {
        nonStringTestHolder.testLongDefaultValue();
    }

    @Test
    public void testShort() throws Exception {
        nonStringTestHolder.testShort();
    }

    @Test
    public void testShortDefaultValue() throws Exception {
        nonStringTestHolder.testShortDefaultValue();
    }

    @Test
    public void testListMissing() throws Exception {
        nonStringTestHolder.testListMissing();
    }

    @Test
    public void testSubset() throws Exception {
        nonStringTestHolder.testSubset();
    }

    @Test
    public void testProperties() throws Exception {
        final Object o = conf.getProperty("test.boolean");
        assertNotNull(o);
        assertEquals("true", o.toString());
    }

    @Test
    public void testContainsKey() {
        final String key = "test.boolean";
        assertTrue("'" + key + "' not found", conf.containsKey(key));

        conf.clearProperty(key);
        assertFalse("'" + key + "' still found", conf.containsKey(key));
    }

    @Test
    public void testChangePrefix() {
        assertEquals("'test.boolean' property", "true", conf.getString("test.boolean"));
        assertEquals("'boolean' property", null, conf.getString("boolean"));

        // change the prefix
        conf.setPrefix("test");
        assertEquals("'test.boolean' property", null, conf.getString("test.boolean"));
        assertEquals("'boolean' property", "true", conf.getString("boolean"));
    }

    @Test
    public void testResetRemovedProperties() throws Exception {
        assertEquals("'test.boolean' property", "true", conf.getString("test.boolean"));

        // remove the property
        conf.clearProperty("test.boolean");
        assertEquals("'test.boolean' property", null, conf.getString("test.boolean"));

        // change the context
        conf.setContext(new InitialContext());

        // get the property
        assertEquals("'test.boolean' property", "true", conf.getString("test.boolean"));
    }

    @Test
    public void testConstructor() throws Exception {
        // test the constructor accepting a context
        JNDIConfiguration c = new JNDIConfiguration(new InitialContext());

        assertEquals("'test.boolean' property", "true", c.getString("test.boolean"));

        // test the constructor accepting a context and a prefix
        c = new JNDIConfiguration(new InitialContext(), "test");

        assertEquals("'boolean' property", "true", c.getString("boolean"));
    }

    /**
     * Configures the test config to throw an exception.
     */
    private PotentialErrorJNDIConfiguration setUpErrorConfig() {
        conf.installException();
        // remove log error listener to avoid output in tests
        final Iterator<EventListener<? super ConfigurationErrorEvent>> iterator = conf.getEventListeners(ConfigurationErrorEvent.ANY).iterator();
        conf.removeEventListener(ConfigurationErrorEvent.ANY, iterator.next());
        return conf;
    }

    /**
     * Tests whether the expected error events have been received.
     *
     * @param type the expected event type
     * @param opEventType the event type of the failed operation
     * @param propName the name of the property
     * @param propValue the property value
     */
    private void checkErrorListener(final EventType<? extends ConfigurationErrorEvent> type, final EventType<?> opEventType, final String propName,
        final Object propValue) {
        final Throwable exception = listener.checkEvent(type, opEventType, propName, propValue);
        assertTrue("Wrong exception class", exception instanceof NamingException);
        listener = null;
    }

    /**
     * Tests whether a JNDI configuration registers an error log listener.
     */
    @Test
    public void testLogListener() throws NamingException {
        final JNDIConfiguration c = new JNDIConfiguration();
        assertEquals("No error log listener registered", 1, c.getEventListeners(ConfigurationErrorEvent.ANY).size());
    }

    /**
     * Tests handling of errors in getKeys().
     */
    @Test
    public void testGetKeysError() {
        assertFalse("Iteration not empty", setUpErrorConfig().getKeys().hasNext());
        checkErrorListener(ConfigurationErrorEvent.READ, ConfigurationErrorEvent.READ, null, null);
    }

    /**
     * Tests handling of errors in isEmpty().
     */
    @Test
    public void testIsEmptyError() throws Exception {
        assertTrue("Error config not empty", setUpErrorConfig().isEmpty());
        checkErrorListener(ConfigurationErrorEvent.READ, ConfigurationErrorEvent.READ, null, null);
    }

    /**
     * Tests handling of errors in the containsKey() method.
     */
    @Test
    public void testContainsKeyError() {
        assertFalse("Key contained after error", setUpErrorConfig().containsKey("key"));
        checkErrorListener(ConfigurationErrorEvent.READ, ConfigurationErrorEvent.READ, "key", null);
    }

    /**
     * Tests handling of errors in getProperty().
     */
    @Test
    public void testGetPropertyError() {
        assertNull("Wrong property value after error", setUpErrorConfig().getProperty("key"));
        checkErrorListener(ConfigurationErrorEvent.READ, ConfigurationErrorEvent.READ, "key", null);
    }

    /**
     * Tests the getKeys() method when there are cycles in the tree.
     */
    @Test
    public void testGetKeysWithCycles() throws NamingException {
        final Hashtable<Object, Object> env = new Hashtable<>();
        env.put(MockInitialContextFactory.PROP_CYCLES, Boolean.TRUE);
        final InitialContext initCtx = new InitialContext(env);
        final JNDIConfiguration c = new JNDIConfiguration(initCtx);
        c.getKeys("cycle");
    }

    /**
     * Tests getKeys() if no data is found. This should not cause a problem and not notify the error listeners.
     */
    @Test
    public void testGetKeysNoData() {
        conf.installException(new NameNotFoundException("Test exception"));
        assertFalse("Got keys", conf.getKeys().hasNext());
        listener.done();
    }

    /**
     * A special JNDI configuration implementation that can be configured to throw an exception when accessing the base
     * context. Used for testing the exception handling.
     */
    public static class PotentialErrorJNDIConfiguration extends JNDIConfiguration {
        /** An exception to be thrown by getBaseContext(). */
        private NamingException exception;

        public PotentialErrorJNDIConfiguration(final Context ctx) {
            super(ctx);
        }

        /**
         * Prepares this object to throw an exception when the JNDI context is queried.
         *
         * @param nex the exception to be thrown
         */
        public void installException(final NamingException nex) {
            exception = nex;
        }

        /**
         * Prepares this object to throw a standard exception when the JNDI context is queried.
         */
        public void installException() {
            installException(new NamingException("Simulated JNDI exception!"));
        }

        /**
         * Returns the JNDI context. Optionally throws an exception.
         */
        @Override
        public Context getBaseContext() throws NamingException {
            if (exception != null) {
                throw exception;
            }
            return super.getBaseContext();
        }
    }
}