/*******************************************************************************
 * 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.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.net.*;
import org.eclipse.osgi.framework.log.FrameworkLogEntry;

public class MultiplexingURLStreamHandler extends URLStreamHandler {
	private static Method openConnectionMethod;
	private static Method equalsMethod;
	private static Method getDefaultPortMethod;
	private static Method getHostAddressMethod;
	private static Method hashCodeMethod;
	private static Method hostsEqualMethod;
	private static Method parseURLMethod;
	private static Method sameFileMethod;
	private static Method setURLMethod;
	private static Method toExternalFormMethod;
	private static Field handlerField;
	private static boolean methodsInitialized = false;

	private String protocol;
	private StreamHandlerFactory factory;

	private static synchronized void initializeMethods(StreamHandlerFactory factory) {
		if (methodsInitialized)
			return;
		try {
			openConnectionMethod = URLStreamHandler.class.getDeclaredMethod("openConnection", new Class[] {URL.class}); //$NON-NLS-1$
			openConnectionMethod.setAccessible(true);

			equalsMethod = URLStreamHandler.class.getDeclaredMethod("equals", new Class[] {URL.class, URL.class}); //$NON-NLS-1$
			equalsMethod.setAccessible(true);

			getDefaultPortMethod = URLStreamHandler.class.getDeclaredMethod("getDefaultPort", null); //$NON-NLS-1$
			getDefaultPortMethod.setAccessible(true);

			getHostAddressMethod = URLStreamHandler.class.getDeclaredMethod("getHostAddress", new Class[] {URL.class}); //$NON-NLS-1$
			getHostAddressMethod.setAccessible(true);

			hashCodeMethod = URLStreamHandler.class.getDeclaredMethod("hashCode", new Class[] {URL.class}); //$NON-NLS-1$
			hashCodeMethod.setAccessible(true);

			hostsEqualMethod = URLStreamHandler.class.getDeclaredMethod("hostsEqual", new Class[] {URL.class, URL.class}); //$NON-NLS-1$
			hostsEqualMethod.setAccessible(true);

			parseURLMethod = URLStreamHandler.class.getDeclaredMethod("parseURL", new Class[] {URL.class, String.class, Integer.TYPE, Integer.TYPE}); //$NON-NLS-1$
			parseURLMethod.setAccessible(true);

			sameFileMethod = URLStreamHandler.class.getDeclaredMethod("sameFile", new Class[] {URL.class, URL.class}); //$NON-NLS-1$
			sameFileMethod.setAccessible(true);

			setURLMethod = URLStreamHandler.class.getDeclaredMethod("setURL", new Class[] {URL.class, String.class, String.class, Integer.TYPE, String.class, String.class, String.class, String.class, String.class}); //$NON-NLS-1$
			setURLMethod.setAccessible(true);

			toExternalFormMethod = URLStreamHandler.class.getDeclaredMethod("toExternalForm", new Class[] {URL.class}); //$NON-NLS-1$
			toExternalFormMethod.setAccessible(true);

			handlerField = URL.class.getDeclaredField("handler"); //$NON-NLS-1$
			handlerField.setAccessible(true);
		} catch (Exception e) {
			factory.adaptor.getFrameworkLog().log(new FrameworkLogEntry(MultiplexingURLStreamHandler.class.getName(), "initializeMethods", FrameworkLogEntry.ERROR, e, null)); //$NON-NLS-1$
			throw new RuntimeException(e.getMessage());
		}
		methodsInitialized = true;
	}

	public MultiplexingURLStreamHandler(String protocol, StreamHandlerFactory factory) {
		this.protocol = protocol;
		this.factory = factory;
		initializeMethods(factory);
	}

	protected URLConnection openConnection(URL url) throws IOException {
		URLStreamHandler handler = factory.findAuthorizedURLStreamHandler(protocol);
		if (handler != null) {
			try {
				return (URLConnection) openConnectionMethod.invoke(handler, new Object[] {url});
			} catch (Exception e) {
				factory.adaptor.getFrameworkLog().log(new FrameworkLogEntry(MultiplexingURLStreamHandler.class.getName(), "openConnection", FrameworkLogEntry.ERROR, e, null)); //$NON-NLS-1$
				throw new RuntimeException(e.getMessage());
			}
		}
		throw new MalformedURLException();
	}

	protected boolean equals(URL url1, URL url2) {
		URLStreamHandler handler = factory.findAuthorizedURLStreamHandler(protocol);
		if (handler != null) {
			try {
				return ((Boolean) equalsMethod.invoke(handler, new Object[] {url1, url2})).booleanValue();
			} catch (Exception e) {
				factory.adaptor.getFrameworkLog().log(new FrameworkLogEntry(MultiplexingURLStreamHandler.class.getName(), "equals", FrameworkLogEntry.ERROR, e, null)); //$NON-NLS-1$
				throw new RuntimeException(e.getMessage());
			}
		}
		throw new IllegalStateException();
	}

	protected int getDefaultPort() {
		URLStreamHandler handler = factory.findAuthorizedURLStreamHandler(protocol);
		if (handler != null) {
			try {
				return ((Integer) getDefaultPortMethod.invoke(handler, null)).intValue();
			} catch (Exception e) {
				factory.adaptor.getFrameworkLog().log(new FrameworkLogEntry(MultiplexingURLStreamHandler.class.getName(), "getDefaultPort", FrameworkLogEntry.ERROR, e, null)); //$NON-NLS-1$
				throw new RuntimeException(e.getMessage());
			}
		}
		throw new IllegalStateException();
	}

	protected InetAddress getHostAddress(URL url) {
		URLStreamHandler handler = factory.findAuthorizedURLStreamHandler(protocol);
		if (handler != null) {
			try {
				return (InetAddress) getHostAddressMethod.invoke(handler, new Object[] {url});
			} catch (Exception e) {
				factory.adaptor.getFrameworkLog().log(new FrameworkLogEntry(MultiplexingURLStreamHandler.class.getName(), "hashCode", FrameworkLogEntry.ERROR, e, null)); //$NON-NLS-1$
				throw new RuntimeException(e.getMessage());
			}
		}
		throw new IllegalStateException();
	}

	protected int hashCode(URL url) {
		URLStreamHandler handler = factory.findAuthorizedURLStreamHandler(protocol);
		if (handler != null) {
			try {
				return ((Integer) hashCodeMethod.invoke(handler, new Object[] {url})).intValue();
			} catch (Exception e) {
				factory.adaptor.getFrameworkLog().log(new FrameworkLogEntry(MultiplexingURLStreamHandler.class.getName(), "hashCode", FrameworkLogEntry.ERROR, e, null)); //$NON-NLS-1$
				throw new RuntimeException(e.getMessage());
			}
		}
		throw new IllegalStateException();
	}

	protected boolean hostsEqual(URL url1, URL url2) {
		URLStreamHandler handler = factory.findAuthorizedURLStreamHandler(protocol);
		if (handler != null) {
			try {
				return ((Boolean) hostsEqualMethod.invoke(handler, new Object[] {url1, url2})).booleanValue();
			} catch (Exception e) {
				factory.adaptor.getFrameworkLog().log(new FrameworkLogEntry(MultiplexingURLStreamHandler.class.getName(), "hostsEqual", FrameworkLogEntry.ERROR, e, null)); //$NON-NLS-1$
				throw new RuntimeException(e.getMessage());
			}
		}
		throw new IllegalStateException();
	}

	protected void parseURL(URL arg0, String arg1, int arg2, int arg3) {
		URLStreamHandler handler = factory.findAuthorizedURLStreamHandler(protocol);
		if (handler != null) {
			try {
				// the handler is set because of a check in setURL (called internally in parseURL)
				// to ensure that this handler and the URL's handler are the same.				
				handlerField.set(arg0, handler);
				parseURLMethod.invoke(handler, new Object[] {arg0, arg1, new Integer(arg2), new Integer(arg3)});
				handlerField.set(arg0, this);
				return;
			} catch (Exception e) {
				factory.adaptor.getFrameworkLog().log(new FrameworkLogEntry(MultiplexingURLStreamHandler.class.getName(), "parseURL", FrameworkLogEntry.ERROR, e, null)); //$NON-NLS-1$
				throw new RuntimeException(e.getMessage());
			}
		}
		throw new IllegalStateException();
	}

	protected boolean sameFile(URL url1, URL url2) {
		URLStreamHandler handler = factory.findAuthorizedURLStreamHandler(protocol);
		if (handler != null) {
			try {
				return ((Boolean) sameFileMethod.invoke(handler, new Object[] {url1, url2})).booleanValue();
			} catch (Exception e) {
				factory.adaptor.getFrameworkLog().log(new FrameworkLogEntry(MultiplexingURLStreamHandler.class.getName(), "sameFile", FrameworkLogEntry.ERROR, e, null)); //$NON-NLS-1$
				throw new RuntimeException(e.getMessage());
			}
		}
		throw new IllegalStateException();
	}

	protected void setURL(URL arg0, String arg1, String arg2, int arg3, String arg4, String arg5, String arg6, String arg7, String arg8) {
		URLStreamHandler handler = factory.findAuthorizedURLStreamHandler(protocol);
		if (handler != null) {
			try {
				// the handler is set because of a check in setURL to ensure that this handler
				// and the URL's handler are the same.
				handlerField.set(arg0, handler);
				setURLMethod.invoke(handler, new Object[] {arg0, arg1, arg2, new Integer(arg3), arg4, arg5, arg6, arg7, arg8});
				handlerField.set(arg0, this);
				return;
			} catch (Exception e) {
				factory.adaptor.getFrameworkLog().log(new FrameworkLogEntry(MultiplexingURLStreamHandler.class.getName(), "setURL", FrameworkLogEntry.ERROR, e, null)); //$NON-NLS-1$
				throw new RuntimeException(e.getMessage());
			}
		}
		throw new IllegalStateException();
	}

	protected String toExternalForm(URL url) {
		URLStreamHandler handler = factory.findAuthorizedURLStreamHandler(protocol);
		if (handler != null) {
			try {
				return (String) toExternalFormMethod.invoke(handler, new Object[] {url});
			} catch (Exception e) {
				factory.adaptor.getFrameworkLog().log(new FrameworkLogEntry(MultiplexingURLStreamHandler.class.getName(), "toExternalForm", FrameworkLogEntry.ERROR, e, null)); //$NON-NLS-1$
				throw new RuntimeException(e.getMessage());
			}
		}
		throw new IllegalStateException();
	}

}
