/**
 * 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.openejb.core.ivm.naming;

import junit.framework.TestCase;
import org.apache.openejb.util.Debug;
import org.apache.openejb.util.Join;

import javax.naming.Context;
import javax.naming.NameAlreadyBoundException;
import javax.naming.NamingException;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.TreeMap;
import javax.naming.OperationNotSupportedException;
import org.apache.openejb.loader.SystemInstance;
import org.apache.openejb.SystemException;
import javax.naming.NameClassPair;
import javax.naming.NamingEnumeration;

/**
 * @version $Rev$ $Date$
 */
public class IvmContextTest extends TestCase {
    private Map<String, Integer> map;
    private IvmContext context;

    public void testLookups() throws Exception {
        // lookup
        for (final Map.Entry<String, Integer> entry : map.entrySet()) {
            final String name = entry.getKey();
            final Integer expected = entry.getValue();
            visit(context, name, new Visitor() {
                public void visit(final Context context, final String name, final String parentName) throws NamingException {
                    assertLookup("relative lookup " + parentName + " : " + name, context, name, expected);
                }
            });
        }
    }

    public void testList() throws Exception {
        // list
        for (final Map.Entry<String, Integer> entry : map.entrySet()) {
            final String name = entry.getKey();
            visit(context, name, new Visitor() {
                public void visit(final Context context, final String name, final String parentName) throws NamingException {

                    final Map<String, Object> expected = new TreeMap<>();

                    for (final Map.Entry<String, Integer> entry : map.entrySet()) {
                        String key = entry.getKey();
                        if (key.startsWith(parentName)) {
                            key = key.substring(parentName.length(), key.length());
                            expected.put(key, entry.getValue());
                        }
                    }

                    final Map<String, Object> actual = list(context);

                    assertEquals("relative list " + parentName + " : " + name, expected, actual);
                }
            });
        }
    }

    public void setUp() throws Exception {
        map = new LinkedHashMap<>();
        map.put("color/orange", 1);
        map.put("color/blue", 2);
        map.put("color/red/scarlet", 3);
        map.put("color/red/crimson", 4);
        map.put("shape", 5);

        context = new IvmContext("/");

        for (final Map.Entry<String, Integer> entry : map.entrySet()) {
            context.bind(entry.getKey(), entry.getValue());
        }
    }

    private Map<String, Object> list(final Context context) throws NamingException {
        final Map<String, Object> map = Debug.contextToMap(context);

        // Prune the context entries out
        map.entrySet().removeIf(entry -> entry.getValue() instanceof Context);

        return map;
    }

    private void assertLookup(final String message, final Context context, final String name, final Object expected) {
        try {
            final Object actual = context.lookup(name);
            assertNotNull(message, actual);
            assertEquals(message, expected, actual);
        } catch (final NamingException e) {
            fail(message + " - Exception:" + e.getClass().getName() + " : " + e.getMessage());
        }
    }

    public void test1() throws Exception {

        final IvmContext context = new IvmContext("");
        context.bind("one", 1);
        context.bind("two", 2);
        context.bind("three", 3);

        assertContextEntry(context, "one", 1);
        assertContextEntry(context, "two", 2);
        assertContextEntry(context, "three", 3);

        context.unbind("one");

        try {
            context.lookup("one");
            fail("name should be unbound");
        } catch (final javax.naming.NameNotFoundException e) {
            // pass
        }

        // The other entries should still be there
//        assertContextEntry(context, "one", 1);
        assertContextEntry(context, "two", 2);
        assertContextEntry(context, "three", 3);

        final Map<String, Object> map = list(context);
        assertFalse("name should not appear in bindings list", map.containsKey("one"));
    }

    public void test2() throws Exception {

        final IvmContext context = new IvmContext();
        context.bind("one", 1);
        context.bind("two", 2);
        context.bind("three", 3);

        assertContextEntry(context, "one", 1);
        assertContextEntry(context, "two", 2);
        assertContextEntry(context, "three", 3);

        context.unbind("two");

        try {
            context.lookup("two");
            fail("name should be unbound");
        } catch (final javax.naming.NameNotFoundException e) {
            // pass
        }

        // The other entries should still be there
        assertContextEntry(context, "one", 1);
        assertContextEntry(context, "three", 3);

        final Map<String, Object> map = list(context);
        assertFalse("name should not appear in bindings list", map.containsKey("two"));
    }

    public void test3() throws Exception {

        final IvmContext context = new IvmContext();
        context.bind("veggies/tomato/roma", 33);
        context.bind("fruit/apple/grannysmith", 22);
        context.bind("fruit/orange/mandarin", 44);

        assertContextEntry(context, "veggies/tomato/roma", 33);
        assertContextEntry(context, "fruit/apple/grannysmith", 22);
        assertContextEntry(context, "fruit/orange/mandarin", 44);

        context.unbind("fruit/apple/grannysmith");
        context.prune("fruit");

        context.unbind("veggies/tomato/roma");
        context.prune("veggies");

        try {
            context.lookup("fruit/apple/grannysmith");
            fail("name should be unbound");
        } catch (final javax.naming.NameNotFoundException pass) {
        }
        try {
            context.lookup("veggies/tomato/roma");
            fail("name should be unbound");
        } catch (final javax.naming.NameNotFoundException pass) {
        }
        try {
            context.lookup("veggies/tomato");
            fail("name should be unbound");
        } catch (final javax.naming.NameNotFoundException pass) {
        }

        try {
            context.lookup("veggies/fruit");
            fail("name should be unbound");
        } catch (final javax.naming.NameNotFoundException pass) {
        }

        final Map<String, Object> map = list(context);
        assertFalse("name should not appear in bindings list", map.containsKey("veggies/tomato/roma"));
    }

    public void testAlreadyBound() throws Exception {

        final IvmContext context = new IvmContext();
        context.bind("number", 2);
        try {
            context.bind("number", 3);
            fail("A NameAlreadyBoundException should have been thrown");
        } catch (final NameAlreadyBoundException e) {
            // pass
        }

    }

    public void test() throws Exception {

        final IvmContext context = new IvmContext();
        context.bind("comp/env/rate/work/doc/lot/pop", 1);
        context.bind("comp/env/rate/work/doc/lot/price", 2);
        context.bind("comp/env/rate/work/doc/lot/break/story", 3);

        final Object o = context.lookup("comp/env/rate/work/doc/lot/pop");
        assertNotNull(o);
        assertTrue(o instanceof Integer);
        assertEquals(o, 1);

        context.unbind("comp/env/rate/work/doc/lot/pop");

        try {
            context.lookup("comp/env/rate/work/doc/lot/pop");
            fail("name should be unbound");
        } catch (final javax.naming.NameNotFoundException e) {
            // pass
        }

        final Map<String, Object> map = list(context);
        assertFalse("name should not appear in bindings list", map.containsKey("comp/env/rate/work/doc/lot/pop"));
    }

    public void testReadOnlyThrowsExceptionByDefault() throws NamingException, NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {
        final IvmContext context = new IvmContext();
        context.setReadOnly(true);

        try {
            context.bind("global/foo/Bar", "Bar");
            fail();
        } catch (OperationNotSupportedException e) {
            // ok
        }
     }
     
     public void testReadOnlyNoException() throws NamingException, NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {
        final IvmContext context = new IvmContext();
        context.setReadOnly(true);

        String originalValue = System.getProperty(IvmContext.JNDI_EXCEPTION_ON_FAILED_WRITE);
        System.setProperty(IvmContext.JNDI_EXCEPTION_ON_FAILED_WRITE, Boolean.FALSE.toString());
        try {
            Context subContext = context.createSubcontext("global/foo/Bar");
            assertNull(subContext);
        } finally {
            if(originalValue == null) {
                System.clearProperty(IvmContext.JNDI_EXCEPTION_ON_FAILED_WRITE);
            } else {
                System.setProperty(IvmContext.JNDI_EXCEPTION_ON_FAILED_WRITE, originalValue);
            }
            SystemInstance.reset();
        }
     }
     
     public void testReadOnlyAppliedRecursively() throws NamingException, NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {
        final IvmContext context = new IvmContext();
        Context subContext = context.createSubcontext("global/foo/Bar");

        context.setReadOnly(true);
        if(IvmContext.class.isInstance(subContext)) {
            assertTrue(IvmContext.class.cast(subContext).readOnly);
        } else { 
            throw new IllegalStateException("Naming context " + subContext + " not instance of " + IvmContext.class) ;
        }

    }
     
     /*
      * NameNode#getBinding returns new IvmContext wrapping current read-only context in some cases
      * This test checks whether the "wrapper" is also read only if the current is 
      */
     public void testGetBindingPropagatesReadOnlyFlag() throws NamingException, NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {
        final IvmContext context = new IvmContext("comp");
        context.bind("env/test", "test");

        context.setReadOnly(true);
        Object result = context.lookup("env");

        if(IvmContext.class.isInstance(result)) {
            assertTrue(IvmContext.class.cast(result).readOnly);
        } else { 
            throw new IllegalStateException("Naming context " + result + " not instance of " + IvmContext.class) ;
        }

    }
     
     /*
      * NameNode#resolve returns new IvmContext wrapping current read-only context on lookup of name bound only in federated context
      * This test checks whether the "wrapper" is also read only if the current is 
      */
     public void testGetFromFederatedContextPropagatesReadOnlyFlag() throws NamingException {
        final IvmContext context = new IvmContext();
        final IvmContext federatedContext = new IvmContext("comp");
        federatedContext.bind("env/test", "test");
        context.bind("", federatedContext);

        context.setReadOnly(true);
        Object result = context.lookup("env");

        if(IvmContext.class.isInstance(result)) {
            assertTrue(IvmContext.class.cast(result).readOnly);
        } else { 
            throw new IllegalStateException("Naming context " + result + " not instance of " + IvmContext.class) ;
        }
    }

    public void testCloseNoExceptionByDefault() throws NamingException {
        final IvmContext context = new IvmContext();
        try {
            context.close();
        } catch (OperationNotSupportedException e) {
            fail();
        }
    }

    public void testCloseThrowsExceptionIfReadOnly() throws NamingException {
        final IvmContext context = new IvmContext();
        context.setReadOnly(true);
        try {
            context.close();
            fail();
        } catch (OperationNotSupportedException e) {
            //ok
        }
    }
    
   public void testListContextListsAllFederatedContextBindings() throws SystemException, NamingException {
	   //mimic logic from EnterpriseBeanBuilder.build, create compJndiContext and bind in it module, app, global 
	   Context compContext = new IvmContext();
        compContext.bind("java:comp/env/dummy", "dummy");

        Context moduleContext = new IvmContext();
        moduleContext.bind("module/env/test", String.class);
        moduleContext.bind("module/env/sub/test2", String.class);
        Context originalModuleSubContext = (IvmContext)moduleContext.lookup("module");
        compContext.bind("module", originalModuleSubContext);

        Context referencedModuleEnvSubContext = (IvmContext)compContext.lookup("module/env");
        NamingEnumeration<NameClassPair> referencedEnvLookupResult = referencedModuleEnvSubContext.list("");

        boolean testFound= false;
        boolean subFound = false;
        while(referencedEnvLookupResult.hasMore()) {
            String currentName = referencedEnvLookupResult.next().getName();
            if("test".equals(currentName)) {
                testFound = true;
            } else if("sub".equals(currentName)) {
                subFound = true;
            } else {
                fail();
            }
        }
        assertTrue(testFound);
        assertTrue(subFound);
     }

    private void assertContextEntry(final Context context, final String s, final Object expected) throws javax.naming.NamingException {
        assertLookup(context, s, expected);
    }

    public interface Visitor {
        public void visit(Context context, String name, String parentName) throws NamingException;
    }

    private void visit(final Context context, final String name, final Visitor visitor) throws NamingException {
        visit(context, name, "", visitor);
    }

    private void visit(final Context context, final String name, final String parentName, final Visitor visitor) throws NamingException {
        visitor.visit(context, name, parentName);

        final String[] parts = name.split("/");

        if (parts.length > 1) {
            final String thisPart = parts[0];
            final Object o = context.lookup(thisPart);
            assertNotNull(o);
            assertTrue(o instanceof Context);
            visit((Context) o, subpath(parts), parentName + thisPart + "/", visitor);
        }
    }

    private void _visit(final Context context, final String name, final Object expected) throws NamingException {
        // bind
//        try {
//            context.bind(s, expected);
//            fail("should not be allowed to bind");
//        } catch (NameAlreadyBoundException e) {
//            // pass
//        }

        // rebind
//        String tmp = expected.toString() + System.currentTimeMillis();
//        context.rebind(s, tmp);
//        assertLookup(context, s, tmp);

        // unbind
//        context.unbind(s);
//        try {
//            context.lookup(s);
//            fail("name should be unbound");
//        } catch (NameNotFoundException e) {
//            // pass
//        }

        // Restore the original state
//        context.bind(s, expected);
//        assertLookup(context, s, expected);
    }

    private void assertLookup(final Context context, final String s, final Object expected) throws NamingException {
        final Object actual = context.lookup(s);
        assertNotNull(actual);
        assertEquals(expected, actual);
    }

    private String subpath(final String[] strings) {
        final String[] strings2 = new String[strings.length - 1];
        System.arraycopy(strings, 1, strings2, 0, strings2.length);

        final String path = Join.join("/", strings2);
        return path;
    }
}
