/*******************************************************************************
 * Copyright (c) 2012, 2013 Oracle.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * and Apache License v2.0 which accompanies this distribution. 
 * The Eclipse Public License is available at
 *     http://www.eclipse.org/legal/epl-v10.html
 * and the Apache License v2.0 is available at 
 *     http://www.opensource.org/licenses/apache2.0.php.
 * You may elect to redistribute this code under either of these licenses.
 *
 * Contributors:
 *     Bob Nettleton - Initial Developer tests for Reference Implementation
 ******************************************************************************/
 
package org.eclipse.gemini.naming.test;

import java.io.IOException;
import java.io.InputStream;
import java.lang.management.ManagementFactory;
import java.net.ConnectException;
import java.net.MalformedURLException;
import java.net.URL;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.util.Dictionary;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.HashMap;
import java.util.Map;

import javax.management.MBeanServer;
import javax.management.remote.JMXConnectorServer;
import javax.management.remote.JMXConnectorServerFactory;
import javax.management.remote.JMXServiceURL;
import javax.naming.CommunicationException;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.Name;
import javax.naming.NameNotFoundException;
import javax.naming.NameParser;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.Reference;
import javax.naming.Referenceable;
import javax.naming.StringRefAddr;
import javax.naming.directory.DirContext;
import javax.naming.directory.InitialDirContext;
import javax.naming.spi.InitialContextFactory;
import javax.naming.spi.InitialContextFactoryBuilder;
import javax.naming.spi.NamingManager;
import javax.naming.spi.ObjectFactory;
import javax.naming.spi.ObjectFactoryBuilder;

import org.osgi.framework.*;


/**
 * Test case used to verify the Factory resolution process
 * in Gemini Naming.  
 * 
 */
public class FactoryResolutionTestCase extends NamingTestCase {

	private ClassLoader m_oldClassLoader = null;
	
	protected void onSetUp() throws Exception {
		super.onSetUp();
		m_oldClassLoader = Thread.currentThread().getContextClassLoader();
		Thread.currentThread().setContextClassLoader(new TestClassLoaderTwo());
	}

	
	protected void onTearDown() throws Exception {
		super.onTearDown();
		Thread.currentThread().setContextClassLoader(m_oldClassLoader);
	}
	
	
	/**
	 * Verifies that the Factory Manager allows access to the JNDI implementations
	 * provided by the JDK.  This test will verify access to the RMI JNDI implementation as 
	 * an example of how to test this.  
	 * 
	 * @TODO, add tests for the other factories provided by the JDK
	 * @throws Exception
	 */
	public void testAccessToJDK_RMIContext() throws Exception {
		Hashtable environment = new Hashtable();
		environment.put(Context.INITIAL_CONTEXT_FACTORY, 
				        "com.sun.jndi.rmi.registry.RegistryContextFactory");
		environment.put("osgi.service.jndi.bundleContext", bundleContext);
		
		// verify that context can be created without any errors
		Context context = null;
		try {
			context = new InitialContext(environment);
		} finally {
			context.close();
		}
	}
	
	/**
	 * Verifies access to the LDAP context factory provided by the 
	 * JDK.  This test does not verify any LDAP connectivity, it merely 
	 * ensures that the JDK-provided implementation is available in an OSGi
	 * environment.  
	 * 
	 * @throws Exception
	 */
	public void testAccessToJDK_LDAPContext() throws Exception {
		Hashtable environment = new Hashtable();
		environment.put(Context.INITIAL_CONTEXT_FACTORY, 
				        "com.sun.jndi.ldap.LdapCtxFactory");
		environment.put("osgi.service.jndi.bundleContext", bundleContext);
		
		DirContext dirContext = null;
		try {
			dirContext = new InitialDirContext(environment);
			// verify that a communication exception is thrown, 
			// since this test does not include an LDAP server
			// the intention of this test is to verify that the factory 
			// can be made available by the factory manager.  
			fail("CommunicationException should have been thrown");
		}
		catch (CommunicationException communicationException) {
			// expected exception for this test
			assertTrue("Did not receive expected root exception for this test",
					    communicationException.getCause() instanceof ConnectException); 
		} finally {
			if (dirContext != null) {
				dirContext.close();
			}
		}
	}

	/**
	 * Verify that if an ObjectFactory classname is specified in a Reference, and that
	 * ObjectFactory is not available to the Factory Manager, that the manager will 
	 * query the existing ObjectFactoryBuilder services in order to attempt to 
	 * find a matching ObjectFactory.  
	 * 
	 * Please see section 5.2.2.1 of RFC 142 for more details.
	 * 
	 * @throws Exception
	 */
	public void testSpecificObjectFactoryResolvedByBuilder() throws Exception {
		final int expectedValue = 100;
		// stub builder to be used in test
		ObjectFactoryBuilder factoryBuilder = new ObjectFactoryBuilder() {
			public ObjectFactory createObjectFactory(Object var0, Hashtable var1) throws NamingException {
				return new ObjectFactory() {
				    public Object getObjectInstance(Object obj, Name name, Context nameCtx, Hashtable environment) throws Exception {
				        return new Integer(expectedValue);
				    }
				};
			}
        };
        
        // only register the builder implementation
        registerService(ObjectFactoryBuilder.class.getName(), factoryBuilder, null);

        // reference data does not matter, since we're testing that
        // the factory manager can locate the only ObjectFactory registered.
        Reference reference = new Reference("test", "com.test.factory.DoesNotExist", null);
        Object result = NamingManager.getObjectInstance(reference, null, null, null);
        assertEquals("JNDI Factory Manager did not locate the correct ObjectFactory", 
                      new Integer(expectedValue), result);
	}
	
	
	/**
	 * Verify that the Factory Manager can resolve a reference that includes an 
	 * address (StringRefAddr) of type "URL".  This address can be used by the Factory
	 * Manager in order to locate a URL context factory that supports the given scheme.  
	 * 
	 * Please see section 5.2.2.1 of RFC 142 for more details.
	 * 
	 * @throws Exception
	 */
	public void testObjectFactoryResolvedUsingURLContextFactory() throws Exception {
		final int expectedValue = 100;
		ObjectFactory urlContextFactory = new ObjectFactory() {
			public Object getObjectInstance(Object var0, Name var1,
					Context var2, Hashtable var3) throws Exception {
				return new Integer(expectedValue);
			}
			
		};
		
		Hashtable serviceProperties = new Hashtable();
		serviceProperties.put("osgi.jndi.url.scheme", "testURL");
		
		registerService(ObjectFactory.class.getName(), 
				 	    urlContextFactory, 
				 	    serviceProperties);

        // reference data does not matter, since we're testing that
        // the factory manager can locate the URL context factory 
		// to support this URL scheme
        Reference reference = new Reference("test", null, null);
        // create a string reference address of type URL
        // and add it to the reference
        reference.add(new StringRefAddr("URL", "testURL://testOne"));
        
        Object result = NamingManager.getObjectInstance(reference, null, null, null);
		assertEquals("Incorrect type returned by URL context factory",
					  new Integer(expectedValue), result);
	}
	
	
	/**
	 * Verify that if no ObjectFactories are found to resolve the reference, 
	 * then the Reference object itself is returned.  This behavior complies with the 
	 * behavior of the NamingManager.getObjectInstance() method.  In this test case
	 * the Reference specifies a factory class that is not available.    
	 * 
	 */
	public void testReturnValueWhenSpecifiedAndNoObjectFactoriesFound() throws Exception {
        // no ObjectFactory services or builder services are registered for this test
		Reference reference = new Reference("test", "com.test.factory.FactoryDoesNotExist", null);
        
        Object result = NamingManager.getObjectInstance(reference, null, null, null);
        assertSame("Factory Manager did not return the refInfo as expected",
        		    reference, result);
	}
	
	
	/**
	 * Verify that if no ObjectFactories are found to resolve the reference, 
	 * then the Reference object itself is returned.  This behavior complies with the 
	 * behavior of the NamingManager.getObjectInstance() method.  In this test case
	 * the Reference does not specify a factory class.      
	 * 
	 */
	public void testReturnValueWhenNotSpecifiedAndNoObjectFactoriesFound() throws Exception {
		// no ObjectFactory services or builder services are registered for this test
		Reference reference = new Reference("test", null, null);
		
		Object result = NamingManager.getObjectInstance(reference, null, null, null);
        assertSame("Factory Manager did not return the refInfo as expected",
        		    reference, result); 
	}
	
	
	/**
	 * Verify that an ObjectFactoryBuilder can be queried in the attempt 
	 * to resolve a reference.  Verify that this process works as expected 
	 * when the NamingManager.getObjectInstance() method is called.  
	 * @throws Exception
	 */
	public void testReferenceableSupportWithBuilder() throws Exception {
		final int expectedValue = 100;
		// stub builder to be used in test
		ObjectFactoryBuilder factoryBuilder = new ObjectFactoryBuilder() {
			public ObjectFactory createObjectFactory(Object var0, Hashtable var1) throws NamingException {
				return new ObjectFactory() {
				    public Object getObjectInstance(Object obj, Name name, Context nameCtx, Hashtable environment) throws Exception {
				        return new Integer(expectedValue);
				    }
				};
			}
        };
        
        // only register the builder implementation
        registerService(ObjectFactoryBuilder.class.getName(), factoryBuilder, null);

        // create implementation of Referenceable that can
        // create a reference to resolve
        Referenceable referenceable = new Referenceable() {
			public Reference getReference() throws NamingException {
				return new Reference("test", "com.test.factory.DoesNotExist", null);
			}
        };
        
        Object result = NamingManager.getObjectInstance(referenceable, null, null, null);
        assertEquals("JNDI Factory Manager did not locate the correct ObjectFactory", 
                      new Integer(expectedValue), result);
	}
	
	
	/**
	 * Verify that the Gemini Naming bundle can support calls to resolve 
	 * a reference from the NamingManager.getObjectInstance() method.  This test
	 * verifies that an ObjectFactory registered as an OSGi service can be queried in
	 * the attempt to resolve the reference.  
	 */
	public void testReferenceableSupportWithObjectFactory() throws Exception {
		final int expectedValue = 100;
		// stub builder to be used in test
		final ObjectFactory objectFactory = new ObjectFactory() {
			public Object getObjectInstance(Object obj, Name name, Context nameCtx, Hashtable environment) throws Exception {
				return new Integer(expectedValue);
			}
		};
		
		
		String[] serviceInterfaces = { ObjectFactory.class.getName(), 
				                       objectFactory.getClass().getName() };

		ServiceRegistration serviceRegistration = 
			bundleContext.registerService(serviceInterfaces, objectFactory, null);
        
        try {
			// create implementation of Referenceable that can
			// create a reference to resolve
			Referenceable referenceable = new Referenceable() {
				public Reference getReference() throws NamingException {
					return new Reference("test", objectFactory.getClass().getName(), null);
				}
			};
			
			Object result = NamingManager.getObjectInstance(referenceable, null, null, null);
			assertEquals("JNDI Factory Manager did not locate the correct ObjectFactory", 
			              new Integer(expectedValue), result);
		}
		finally {
			serviceRegistration.unregister();
		}
	}
	
	
	/**
	 * Verify that a "jndi.properties" file can be used in a Bundle to 
	 * specify the desired InitialContextFactory implementation.  
	 */
	public void testJndiPropertiesFileFromArchive() throws Exception {
		final String expectedLookupName = "test-binding-one";
		final String expectedLookupValue = "this is only a test!";
		// setup a stub context factory
		Context testContext = new TestContext() {
			public Object lookup(String name) throws NamingException {
				if(name.equals(expectedLookupName)) {
					return expectedLookupValue;
				}
				
				throw new NameNotFoundException("Error in test");
			}
			
		};
		
		InitialContextFactory initialContextFactory = new TestContextFactory(testContext);
		String[] interfaceNames = { InitialContextFactory.class.getName(), TestContextFactory.class.getName() }; 
		
		// register context factory
		ServiceRegistration serviceRegistration = 
			bundleContext.registerService(interfaceNames, initialContextFactory, null);
		
		InitialContext context = null;
		try {
			Hashtable environment = new Hashtable();
			environment.put("osgi.service.jndi.bundleContext", bundleContext);
			context = new InitialContext(environment);
			assertEquals("Incorrect value returned by context factory", 
					     expectedLookupValue, context.lookup(expectedLookupName));
		} finally {
			context.close();
			
			serviceRegistration.unregister();
		}
	}
    
    /**
     * Verify that RMI URL Context Factory can be used by default.
     */
    public void testRMIURLContextFactory() throws Exception {
        MBeanServer theMBeanServer = ManagementFactory.getPlatformMBeanServer();
		// Create the RMI registry
		try {
			LocateRegistry.createRegistry(1515);
		} catch (RemoteException e) {
			fail("Can't create registry: " + e.toString());
		}
        
		// Build the connection string with fixed ports
		StringBuilder url = new StringBuilder();
		url.append("service:jmx:rmi://localhost:");
		url.append(1516);
		url.append("/jndi/rmi://localhost:");
		url.append(1515);
		url.append("/jmxrmi");
		
        JMXServiceURL serviceUrl = null;
		try {
			serviceUrl = new JMXServiceURL(url.toString());
		} catch (MalformedURLException e) {
			fail("Can't create registry: " + e.toString());
		}
        
		Map<String, Object> env = new HashMap<String, Object>();
		ClassLoader currentTCCL = Thread.currentThread().getContextClassLoader();
        JMXConnectorServer cs = null;
		try {
			Thread.currentThread().setContextClassLoader(getClass().getClassLoader());
			cs = JMXConnectorServerFactory.newJMXConnectorServer(serviceUrl, env, theMBeanServer);
			cs.start();
			System.out.println("Start MBean JMX registry with ports: registry=" + 1515 + ", server=" + 1516);
            assertTrue(cs.isActive());
		} catch (IOException e) {
			fail("Can't create registry: " + e.toString());
		} finally {
			Thread.currentThread().setContextClassLoader(currentTCCL);
            if (cs != null) {
                cs.stop();
            }
		}
    }
	
	// Stub implementations of JNDI factories used for simpler unit testing
	static class TestContextFactoryBuilder implements InitialContextFactoryBuilder {
		private final Context m_context;
		
		TestContextFactoryBuilder(Context context) {
			m_context = context;
		}
		
		
		public InitialContextFactory createInitialContextFactory(Hashtable var0)
				throws NamingException {
			return new TestContextFactory(m_context);
		}
	}
	
	private static class TestContextFactory implements InitialContextFactory {
		private final Context m_context;
		
		TestContextFactory(Context context) {
			m_context = context;
		}
		
		
		public Context getInitialContext(Hashtable var0) throws NamingException {
			return m_context;
		}
		
	}
	
	static class TestContext implements Context {
		
		private int m_numOfCloseCalls = 0;
		
		int getNumCloseCalls() {
			return m_numOfCloseCalls;
		}
		
		public Object addToEnvironment(String var0, Object var1)
				throws NamingException {
			return null;
		}

		public void bind(String var0, Object var1) throws NamingException {
		}

		public void bind(Name var0, Object var1) throws NamingException {
		}

		public void close() throws NamingException {
			m_numOfCloseCalls++;
		}

		public String composeName(String var0, String var1)
				throws NamingException {
			return null;
		}

		public Name composeName(Name var0, Name var1) throws NamingException {
			return null;
		}

		public Context createSubcontext(String var0) throws NamingException {
			return null;
		}

		public Context createSubcontext(Name var0) throws NamingException {
			return null;
		}

		public void destroySubcontext(String var0) throws NamingException {
		}

		public void destroySubcontext(Name var0) throws NamingException {
		}

		public Hashtable getEnvironment() throws NamingException {
			return null;
		}

		public String getNameInNamespace() throws NamingException {
			return null;
		}

		public NameParser getNameParser(String var0) throws NamingException {
			return null;
		}

		public NameParser getNameParser(Name var0) throws NamingException {
			return null;
		}

		public NamingEnumeration list(String var0) throws NamingException {
			return null;
		}

		public NamingEnumeration list(Name var0) throws NamingException {
			return null;
		}

		public NamingEnumeration listBindings(String var0)
				throws NamingException {
			return null;
		}

		public NamingEnumeration listBindings(Name var0) throws NamingException {
			return null;
		}

		public Object lookup(String var0) throws NamingException {
			return null;
		}

		public Object lookup(Name var0) throws NamingException {
			return null;
		}

		public Object lookupLink(String var0) throws NamingException {
			return null;
		}

		public Object lookupLink(Name var0) throws NamingException {
			return null;
		}

		public void rebind(String var0, Object var1) throws NamingException {
		}

		public void rebind(Name var0, Object var1) throws NamingException {
		}

		public Object removeFromEnvironment(String var0) throws NamingException {
			return null;
		}

		public void rename(String var0, String var1) throws NamingException {
		}

		public void rename(Name var0, Name var1) throws NamingException {
		}

		public void unbind(String var0) throws NamingException {
		}

		public void unbind(Name var0) throws NamingException {
		}
		
	}
	

	private class TestClassLoaderTwo extends ClassLoader implements BundleReference {

		public Bundle getBundle() {
			return new Bundle() {
				public Enumeration findEntries(String path, String filePattern, boolean recurse) {
					return null;
				}

				public BundleContext getBundleContext() {
					return getContext();
				}

				public long getBundleId() {
					return 0;
				}

				public URL getEntry(String path) {
					return null;
				}

				public Enumeration getEntryPaths(String path) {
					return null;
				}

				public Dictionary getHeaders() {
					return null;
				}

				public Dictionary getHeaders(String locale) {
					return null;
				}

				public long getLastModified() {
					return 0;
				}

				public String getLocation() {
					return null;
				}

				public ServiceReference[] getRegisteredServices() {
					return null;
				}

				public URL getResource(String name) {
					return null;
				}

				public Enumeration getResources(String name) throws IOException {
					return null;
				}

				public ServiceReference[] getServicesInUse() {
					return null;
				}

				public Map getSignerCertificates(int signersType) {
					return null;
				}

				public int getState() {
					return 0;
				}

				public String getSymbolicName() {
					return null;
				}

				public Version getVersion() {
					return null;
				}

				public boolean hasPermission(Object permission) {
					return false;
				}

				public Class loadClass(String name) throws ClassNotFoundException {
					return null;
				}

				public void start() throws BundleException {
				}

				public void start(int options) throws BundleException {
				}

				public void stop() throws BundleException {
				}

				public void stop(int options) throws BundleException {
				}

				public void uninstall() throws BundleException {
				}

				public void update() throws BundleException {
				}

				public void update(InputStream input) throws BundleException {
				}
				
			};
		}
			
	}
	
	
}
