package org.eclipse.jst.jsp.core.internal.taglib;


import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;

import org.eclipse.core.runtime.Platform;
import org.eclipse.jst.jsp.core.internal.Logger;



/**
 * Custom classloader which allows you to add source directories (folders
 * containing .class files) and jars to the classpath.
 * 
 * @author pavery
 */
public class TaglibClassLoader extends ClassLoader {

	// for debugging
	private static final boolean DEBUG;
	static {
		String value = Platform.getDebugOption("org.eclipse.jst.jsp.core/debug/taglibclassloader"); //$NON-NLS-1$
		DEBUG = value != null && value.equalsIgnoreCase("true"); //$NON-NLS-1$
	}

	private List jarsList = new ArrayList();
	private List dirsList = new ArrayList();
	private List usedJars = new ArrayList();
	private List usedDirs = new ArrayList();

	private Map failedClasses = new HashMap(); // CL: added to optimize
													// failed loading

	// private List loadedClassFilenames = new ArrayList();

	public TaglibClassLoader(ClassLoader parentLoader) {
		super(parentLoader);
	}

	/**
	 * Adds a new jar to classpath.
	 * 
	 * @param filename -
	 *            full path to the jar file
	 */
	public void addJar(String filename) {
		if (DEBUG)
			System.out.println("trying to add: [" + filename + "] to classpath"); //$NON-NLS-1$ //$NON-NLS-2$
		// don't add the same entry twice, or search times will get even worse
		if (!jarsList.contains(filename)) {
			jarsList.add(filename);
			failedClasses = new HashMap();
			if (DEBUG)
				System.out.println(" + [" + filename + "] added to classpath"); //$NON-NLS-1$ //$NON-NLS-2$
		}
	}

	/**
	 * Removes a jar from the classpath.
	 * 
	 * @param filename -
	 *            full path to the jar file
	 */
	public void removeJar(String filename) {
		jarsList.remove(filename);
		failedClasses = new HashMap();
		if (DEBUG)
			System.out.println("removed: [" + filename + "] from classpath"); //$NON-NLS-1$ //$NON-NLS-2$
	}

	public void addDirectory(String dirPath) {
		if (!dirsList.contains(dirPath)) {
			dirsList.add(dirPath);
			failedClasses = new HashMap();
			if (DEBUG)
				System.out.println("added: [" + dirPath + "] to classpath"); //$NON-NLS-1$ //$NON-NLS-2$
		}
	}

	/**
	 * Removes a directory from the classpath.
	 * 
	 * @param dirPath -
	 *            full path of the directory
	 */
	public void removeDirectory(String dirPath) {
		dirsList.remove(dirPath);
		failedClasses = new HashMap();
		if (DEBUG)
			System.out.println("removed: [" + dirPath + "] from classpath"); //$NON-NLS-1$ //$NON-NLS-2$
	}

	/**
	 * Returns the list of JARs on this loader's classpath that contain
	 * classes that have been loaded.
	 * 
	 * @return List - the list of JARs
	 */
	public List getJarsInUse() {
		return usedJars;
	}

	/**
	 * Returns a list of directories on this loader's classpath that contain
	 * classes that have been loaded.
	 * 
	 * @return List - the list of directories (fully-qualified filename
	 *         Strings)
	 */
	public List getDirectoriesInUse() {
		return usedDirs;
	}
	
	Map getFailures() {
		return failedClasses;
	}

	/**
	 * Returns a list of filenames for loose classes that have been loaded out
	 * of directories.
	 * 
	 * @return List - the list of class filenames
	 */
	// public List getClassFilenamesFromDirectories() {
	// return loadedClassFilenames;
	// }
	/**
	 * Searches for the given class name on the defined classpath -
	 * directories are checked before JARs.
	 * 
	 * @param className -
	 *            the name of the class to find
	 * @return Class - the loaded class
	 * @throws ClassNotFoundException
	 */
	protected synchronized Class findClass(String className) throws ClassNotFoundException {
		Class oldClass = findLoadedClass(className);
		if (oldClass != null) {
			if (DEBUG)
				System.out.println(">> TaglibClassLoader " + this + " returning existing class: " + className); //$NON-NLS-1$ //$NON-NLS-2$
			return oldClass;
		}
		if (failedClasses.containsKey(className)) {
			if (DEBUG)
				System.out.println(">> TaglibClassLoader " + this + " known missing class: " + className); //$NON-NLS-1$ //$NON-NLS-2$
			throw new ClassNotFoundException();
		}

		if (DEBUG)
			System.out.println(">> TaglibClassLoader " + this + " finding class: " + className); //$NON-NLS-1$ //$NON-NLS-2$

		Class newClass = null;
		JarFile jarfile = null;
		JarEntry entry = null;

		// get the correct name of the actual .class file to search for
		String fileName = calculateClassFilename(className);
		InputStream stream = null;
		try {
			// first try searching the classpath directories
			Iterator dirs = dirsList.iterator();
			File f;
			String dirName;
			String fileToFind = ""; //$NON-NLS-1$
			while (dirs.hasNext()) {
				dirName = (String) dirs.next();
				fileToFind = dirName + "/" + fileName; //$NON-NLS-1$

				f = new File(fileToFind);
				if (f.exists()) {
					stream = new FileInputStream(f);
					usedDirs.add(dirName);
					// loadedClassFilenames.add(fileToFind);
					if (DEBUG)
						System.out.println(">> added file from dir: " + dirName + "/" + fileName); //$NON-NLS-1$ //$NON-NLS-2$
					break;

				}
			}

			if (stream != null) {
				// found a class from a directory
				ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
				byte[] buffer = new byte[2048];
				while (stream.available() > 0) {
					int amountRead = stream.read(buffer);
					if(amountRead > 0) {
						byteStream.write(buffer, 0, amountRead);
					}
				}

				byte[] byteArray = byteStream.toByteArray();
				try {
					if (DEBUG)
						System.out.println(">> defining newClass:" + className); //$NON-NLS-1$
					newClass = defineClass(className, byteArray, 0, byteArray.length);
					resolveClass(newClass);
				}
				catch (ClassCircularityError e) {
					/*
					 * j9 can give ClassCircularityError parent should already
					 * have the class then try parent loader
					 */
					try {
						Class c = getParent().loadClass(className);
						if (DEBUG)
							System.out.println(">> loaded: " + className + " with: " + getParent()); //$NON-NLS-1$ //$NON-NLS-2$
						return c;
					}
					catch (ClassNotFoundException cnf) {
						if (DEBUG)
							cnf.printStackTrace();
					}
					Logger.logException("Unrecoverable error loading TEI class " + className, e);
				}
				catch (Throwable t) {
					Logger.logException("Error loading TEI class " + className, t);
				}
				stream.close();
			}

			if (stream == null) {
				// still haven't found the class, so now try searching the
				// jars
				// search each of the jars until we find an entry matching the
				// classname
				Iterator jars = jarsList.iterator();
				String jarName;
				while (jars.hasNext()) {
					jarName = (String) jars.next();

					// make sure the file exists or "new JarFile()" will throw
					// an exception
					f = new File(jarName);
					if (!f.exists()) {
						continue;
					}
					try {
						jarfile = new JarFile(jarName);
					}
					catch (IOException e) {
						if (DEBUG)
							Logger.logException("bad jar file", e); //$NON-NLS-1$
					}
					if (jarfile == null) {
						continue;
					}

					entry = jarfile.getJarEntry(fileName);

					if (DEBUG)
						System.out.println("looking for filename: " + fileName + " in: " + jarfile.getName()); //$NON-NLS-1$ //$NON-NLS-2$
					if (entry != null) {
						if (DEBUG)
							System.out.println("found the entry: " + entry + " for filename: " + fileName); //$NON-NLS-1$ //$NON-NLS-2$
						// found the class
						if (!usedJars.contains(jarName)) {
							// add the jar to the list of in-use jars
							usedJars.add(jarName);
						}
						break;
					}
					jarfile.close();
				}

				if (entry != null) {
					// we've found an entry for the desired class
					stream = jarfile.getInputStream(entry);
					ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
					long byteLength = entry.getSize();
					long totalBytesRead = 0;
					int bytesRead;
					byte[] byteBuffer = new byte[10000];
					while (totalBytesRead < byteLength) {
						bytesRead = stream.read(byteBuffer);
						if (bytesRead == -1) {
							break;
						}
						totalBytesRead = totalBytesRead + bytesRead;
						byteStream.write(byteBuffer, 0, bytesRead);
					}

					byte[] byteArray = byteStream.toByteArray();
					try {
						if (DEBUG)
							System.out.println(">> defining newClass:" + className); //$NON-NLS-1$
						// define the class from the byte array
						newClass = defineClass(className, byteArray, 0, byteArray.length);
						resolveClass(newClass);
					}
					catch (ClassCircularityError e) {
						/*
						 * j9 can give ClassCircularityError parent should already
						 * have the class then try parent loader
						 */
						try {
							Class c = getParent().loadClass(className);
							if (DEBUG)
								System.out.println(">> loaded: " + className + " with: " + getParent()); //$NON-NLS-1$ //$NON-NLS-2$
							return c;
						}
						catch (ClassNotFoundException cnf) {
							if (DEBUG)
								cnf.printStackTrace();
						}
						Logger.logException("Unrecoverable error loading TEI class " + className, e);
					}
					catch (Throwable t) {
						Logger.logException("Error loading TEI class " + className, t);
					}
					stream.close();
					jarfile.close();
				}
			}
		}
		catch (Throwable t) {
			failedClasses.put(className, t);
			return null;
		}
		finally {
			try {
				if (stream != null) {
					stream.close();
				}
				if (jarfile != null) {
					jarfile.close();
				}
			}
			catch (IOException ioe) {
				// ioe.printStackTrace();
				// just trying to close down anyway - ignore
			}
		}

		if (newClass != null) {
			if (DEBUG)
				System.out.println(">> loaded: " + newClass + " with: " + this); //$NON-NLS-1$ //$NON-NLS-2$
			return newClass;
		}

//		failedClasses.add(className);
		throw new ClassNotFoundException();
	}

	/**
	 * Replaces '.' in the classname with '/' and appends '.class' if needed.
	 * 
	 * @return String - the properly-formed class name
	 */
	private String calculateClassFilename(String name) {
		StringBuffer buffer = new StringBuffer(name.replace('.', '/'));
		if (!name.endsWith(".class")) { //$NON-NLS-1$
			buffer.append(".class"); //$NON-NLS-1$
		}
		return buffer.toString();
	}
}