/*******************************************************************************
 * Copyright (c) 2010 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 (Oracle) - Initial Reference Implementation Unit Tests
 ******************************************************************************/

package org.eclipse.gemini.naming;

import java.lang.reflect.Field;
import java.util.Dictionary;
import java.util.Hashtable;

import javax.naming.NamingException;
import javax.naming.spi.DirObjectFactory;
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.easymock.EasyMockSupport;
import org.osgi.framework.BundleContext;
import org.osgi.framework.Filter;
import org.osgi.framework.InvalidSyntaxException;
import org.osgi.framework.ServiceListener;
import org.osgi.framework.ServiceReference;
import org.osgi.framework.ServiceRegistration;
import org.osgi.service.jndi.JNDIConstants;
import org.osgi.service.jndi.JNDIContextManager;
import org.osgi.service.jndi.JNDIProviderAdmin;

import static org.easymock.EasyMock.*;

import junit.framework.TestCase;

public class ActivatorTestCase extends TestCase {

	public void setUp() {
		setNamingManagerStaticFieldToNull("initctx_factory_builder");
		setNamingManagerStaticFieldToNull("object_factory_builder");
	}

	public void tearDown() {
		setNamingManagerStaticFieldToNull("initctx_factory_builder");
		setNamingManagerStaticFieldToNull("object_factory_builder");
	}
	
	
	/**
	 * Verify the basic startup of the Gemini Naming Activator.  
	 *  
	 * This test method verifies that all the expected services are 
	 * registered using the correct interface, actual type, and service
	 * properties.  
	 */
	public void testStart() throws Exception {
		EasyMockSupport mockSupport = new EasyMockSupport();
		BundleContext bundleContextMock = 
			mockSupport.createMock(BundleContext.class);
		
		setupBundleContextMock(mockSupport, bundleContextMock);
		// expect OSGi URLContextFactory 
		Hashtable<String, Object> serviceProperties = new Hashtable<String, Object>();
		serviceProperties.put(JNDIConstants.JNDI_URLSCHEME, "osgi");
		setServiceRegistrationExpectation(mockSupport, bundleContextMock,
				                          ObjectFactory.class.getName(), 
				                          OSGiURLContextFactoryServiceFactory.class, 
				                          serviceProperties);

		// expect the "default" InitialContextFactoryBuilder
		setServiceRegistrationExpectation(mockSupport, bundleContextMock,
				                          InitialContextFactoryBuilder.class.getName(),
				                          DefaultRuntimeInitialContextFactoryBuilder.class,
				                          null);
		
		// expect the JNDIContextManager service registration
		setServiceRegistrationExpectation(mockSupport, bundleContextMock, 
				                          JNDIContextManager.class.getName(),
				                          ContextManagerServiceFactoryImpl.class, 
                						  null);
		// expect the JNDIProviderAdmin service registration
		setServiceRegistrationExpectation(mockSupport, bundleContextMock, 
                						  JNDIProviderAdmin.class.getName(),
                						  SecurityAwareProviderAdminImpl.class, 
                						  null);
				
		
		mockSupport.replayAll();
		
		// begin test
		Activator activator = new Activator();
		activator.start(bundleContextMock);
		
		// verify that the static singletons are set as expected
		assertTrue("Activator did not set the InitialContextFactoryBuilder singleton correctly",
				    getPrivateStaticField(NamingManager.class, "initctx_factory_builder") instanceof TraditionalInitialContextFactoryBuilder);
		assertTrue("Activator did not set the ObjectFactoryBuilder singleton correctly",
			       getPrivateStaticField(NamingManager.class, "object_factory_builder") instanceof TraditionalObjectFactoryBuilder);
		
		// stop() should complete without any exceptions
		activator.stop(bundleContextMock);
		
		mockSupport.verifyAll();
	}
	
	public void testRegistrationOfContextBuilderError() throws Exception {
		// setup test mocks
		EasyMockSupport mockSupport = new EasyMockSupport();
		InitialContextFactoryBuilder builderMock = 
			mockSupport.createMock(InitialContextFactoryBuilder.class);
		if(!NamingManager.hasInitialContextFactoryBuilder()) {
			NamingManager.setInitialContextFactoryBuilder(builderMock);
		}
		
		BundleContext bundleContextMock = 
			mockSupport.createMock(BundleContext.class);
		mockSupport.replayAll();
		
		// begin test
		Activator activator = new Activator();
		try {
			activator.start(bundleContextMock);
			fail("NamingException should have been thrown");
		} catch (NamingException namingException) {
			// expected exception
		}
		
		mockSupport.verifyAll();
		
	}
	
	
	public void testRegistrationOfObjectFactoryBuilderError() throws Exception {
		// setup test mocks
		EasyMockSupport mockSupport = new EasyMockSupport();
		ObjectFactoryBuilder builderMock = 
			mockSupport.createMock(ObjectFactoryBuilder.class);
		
		try {
			// try to set builder, to guarantee
			// that Activator's attempt to set this will fail
			NamingManager.setObjectFactoryBuilder(builderMock);
		} catch (Throwable throwable) {
			// if already set, test can continue
		}
		
		BundleContext bundleContextMock = 
			mockSupport.createMock(BundleContext.class);
		mockSupport.replayAll();
		
		// begin test
		Activator activator = new Activator();
		try {
			activator.start(bundleContextMock);
			fail("NamingException should have been thrown");
		} catch (NamingException namingException) {
			// expected exception
		}
		
		mockSupport.verifyAll();
		
	}

	/* test utility methods/classes */
	
	private static void setupBundleContextMock(EasyMockSupport mockSupport, BundleContext bundleContextMock) throws InvalidSyntaxException {
		Filter filterMock = 
			mockSupport.createMock(Filter.class);
		expect(bundleContextMock.createFilter("(objectClass=" + InitialContextFactory.class.getName() + ")")).andReturn(filterMock);
		expect(bundleContextMock.createFilter("(objectClass=" + InitialContextFactoryBuilder.class.getName() + ")")).andReturn(filterMock);
		expect(bundleContextMock.createFilter("(objectClass=" + ObjectFactory.class.getName() + ")")).andReturn(filterMock).anyTimes();
		expect(bundleContextMock.createFilter("(objectClass=" + DirObjectFactory.class.getName() + ")")).andReturn(filterMock);
		expect(bundleContextMock.createFilter("(objectClass=" + ObjectFactoryBuilder.class.getName() + ")")).andReturn(filterMock);
		
		bundleContextMock.addServiceListener(isA(ServiceListener.class), isA(String.class));
		expectLastCall().anyTimes();
		
		bundleContextMock.removeServiceListener(isA(ServiceListener.class));
		expectLastCall().anyTimes();
		
		expect(bundleContextMock.getServiceReferences(isA(String.class), isA(String.class))).andReturn(new ServiceReference[0]).anyTimes();
		expect(bundleContextMock.getServiceReferences(isA(String.class), (String)isNull())).andReturn(new ServiceReference[0]).anyTimes();
	}

	private static <T> void setServiceRegistrationExpectation(EasyMockSupport mockSupport, BundleContext bundleContextMock, String serviceName, Class<T> serviceType, Dictionary<String, Object> serviceProperties) {
		ServiceRegistration serviceRegistrationMock = 
			mockSupport.createMock(ServiceRegistration.class);
		// required for stop() method
		serviceRegistrationMock.unregister();
		if(serviceProperties != null) {
			expect(bundleContextMock.registerService(eq(serviceName),
	                isA(serviceType), eq(serviceProperties))).andReturn(serviceRegistrationMock);
		} else {
			expect(bundleContextMock.registerService(eq(serviceName),
	                isA(serviceType), (Dictionary)isNull())).andReturn(serviceRegistrationMock);
		}
		
	}
	
	/**
	 * This method should be used only for unit testing the Gemini Naming Activator.  
	 * 
	 * This method sets the static singleton fields on the NamingManger class to null.  This facilitates
	 * simpler unit-testing of the Activator, which attempts to set these singletons.  The NamingManager usually
	 * throws and Exception on the set() methods for these singletons after they've been set once.  
	 * 
	 * This utility method is meant to make unit testing simpler, but should not be used in production code. 
	 * 
	 * This utility method will probably not work properly if a security manager is enabled.  
	 * 
	 * @param fieldName the name of the static field to set to null.
	 */
	private static void setNamingManagerStaticFieldToNull(String fieldName) {
		try {
			final Field field = NamingManager.class.getDeclaredField(fieldName);
			if(field != null) {
				field.setAccessible(true);
				// reset this static field to null
				field.set(null, null);
			}
		} catch (Throwable throwable) {
			throwable.printStackTrace();
		}
	}
	
	/*
	 * Utility method used to access the private static singletons on the NamingManager class.  
	 * 
	 * This method should only be used for unit-testing the Gemini Naming code.  
	 *
	 * This utility method will probably not work properly if a security manager is enabled.
	 * 
	 * @param type the Class type that contains the field
	 * @param fieldName a String name that identifies the field
	 */
	private static Object getPrivateStaticField(Class type, String fieldName) throws Exception {
		Field field = type.getDeclaredField(fieldName);
		if(field != null) {
			field.setAccessible(true);
			return field.get(null);
		}
		
		return null;
	}
	
}
