/*******************************************************************************
 * Copyright (c) 2006 Cognos Incorporated, IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 * 
 *******************************************************************************/
package org.eclipse.osgi.framework.internal.protocol;

import java.lang.reflect.Method;
import java.util.*;
import org.eclipse.osgi.framework.adaptor.FrameworkAdaptor;
import org.eclipse.osgi.framework.log.FrameworkLogEntry;
import org.osgi.framework.BundleContext;
import org.osgi.service.packageadmin.PackageAdmin;
import org.osgi.util.tracker.ServiceTracker;

/*
 * An abstract class for handler factory impls (Stream and Content) that can 
 * handle environments running multiple osgi frameworks with the same VM.
 */
public abstract class MultiplexingFactory {

	protected static final String PACKAGEADMINCLASS = "org.osgi.service.packageadmin.PackageAdmin"; //$NON-NLS-1$
	protected BundleContext context;
	protected FrameworkAdaptor adaptor;
	private List factories; // list of multiplexed factories
	private ServiceTracker packageAdminTracker;

	// used to get access to the protected SecurityManager#getClassContext method
	private static class InternalSecurityManager extends SecurityManager {
		public Class[] getClassContext() {
			return super.getClassContext();
		}
	}

	private static InternalSecurityManager internalSecurityManager = new InternalSecurityManager();

	MultiplexingFactory(BundleContext context, FrameworkAdaptor adaptor) {
		this.context = context;
		this.adaptor = adaptor;
		packageAdminTracker = new ServiceTracker(context, PACKAGEADMINCLASS, null);
		packageAdminTracker.open();
	}

	abstract public void setParentFactory(Object parentFactory);

	abstract public Object getParentFactory();

	public synchronized boolean isMultiplexing() {
		return factories != null;
	}

	public synchronized void register(Object factory) {
		if (factories == null)
			factories = new LinkedList();

		// set parent for each factory so they can do proper delegation
		try {
			Class clazz = factory.getClass();
			Method setParentFactory = clazz.getMethod("setParentFactory", new Class[] {Object.class}); //$NON-NLS-1$
			setParentFactory.invoke(factory, new Object[] {getParentFactory()});
		} catch (Exception e) {
			adaptor.getFrameworkLog().log(new FrameworkLogEntry(MultiplexingFactory.class.getName(), FrameworkLogEntry.ERROR, 0, "register", FrameworkLogEntry.ERROR, e, null)); //$NON-NLS-1$
			throw new RuntimeException(e.getMessage());
		}
		factories.add(factory);
	}

	public synchronized void unregister(Object factory) {
		factories.remove(factory);
		if (factories.isEmpty())
			factories = null;
		// close the service tracker
		try {
			// this is brittle; if class does not directly extend MultplexingFactory then this method will not exist, but we do not want a public method here
			Method closeTracker = factory.getClass().getSuperclass().getDeclaredMethod("closePackageAdminTracker", null); //$NON-NLS-1$
			closeTracker.setAccessible(true); // its a private method
			closeTracker.invoke(factory, null);
		} catch (Exception e) {
			adaptor.getFrameworkLog().log(new FrameworkLogEntry(MultiplexingFactory.class.getName(), FrameworkLogEntry.ERROR, 0, "unregister", FrameworkLogEntry.ERROR, e, null)); //$NON-NLS-1$
			throw new RuntimeException(e.getMessage());
		}
	}

	public synchronized Object designateSuccessor() {
		Object parentFactory = getParentFactory();
		if (factories == null || factories.isEmpty())
			return parentFactory;

		Object successor = factories.remove(0);
		try {
			Class clazz = successor.getClass();
			Method register = clazz.getMethod("register", new Class[] {Object.class}); //$NON-NLS-1$		
			for (Iterator it = factories.iterator(); it.hasNext();) {
				register.invoke(successor, new Object[] {it.next()});
			}
		} catch (Exception e) {
			adaptor.getFrameworkLog().log(new FrameworkLogEntry(MultiplexingFactory.class.getName(), FrameworkLogEntry.ERROR, 0, "designateSuccessor", FrameworkLogEntry.ERROR, e, null)); //$NON-NLS-1$
			throw new RuntimeException(e.getMessage());
		}
		factories = null;
		closePackageAdminTracker(); // close tracker
		return successor;
	}

	private void closePackageAdminTracker() {
		packageAdminTracker.close();
	}

	public synchronized Object findAuthorizedFactory(List ignoredClasses) {
		Class[] classStack = internalSecurityManager.getClassContext();
		for (int i = 0; i < classStack.length; i++) {
			Class clazz = classStack[i];
			if (clazz == InternalSecurityManager.class || clazz == MultiplexingFactory.class || ignoredClasses.contains(clazz))
				continue;
			if (hasAuthority(clazz))
				return this;
			if (factories == null)
				continue;
			for (Iterator it = factories.iterator(); it.hasNext();) {
				Object factory = it.next();
				try {
					Method hasAuthorityMethod = factory.getClass().getMethod("hasAuthority", new Class[] {Class.class}); //$NON-NLS-1$
					if (((Boolean) hasAuthorityMethod.invoke(factory, new Object[] {clazz})).booleanValue()) {
						return factory;
					}
				} catch (Exception e) {
					adaptor.getFrameworkLog().log(new FrameworkLogEntry(MultiplexingFactory.class.getName(), FrameworkLogEntry.ERROR, 0, "findAuthorizedURLStreamHandler-loop", FrameworkLogEntry.ERROR, e, null)); //$NON-NLS-1$
					throw new RuntimeException(e.getMessage());
				}
			}
		}
		return null;
	}

	public boolean hasAuthority(Class clazz) {
		PackageAdmin packageAdminService = (PackageAdmin) packageAdminTracker.getService();
		if (packageAdminService != null) {
			return packageAdminService.getBundle(clazz) != null;
		}
		return false;
	}
}
