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 (Throwable t) {
					Logger.logException("Error loading TEI class " + className, t);

					// 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();
					}
				}
				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 (Throwable t) {
						Logger.logException("Error loading TEI class " + className, t);
						// j9 can give ClassCircularityError
						// parent should already have the class then

						// try parent
						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();
							failedClasses.put(className, cnf);
						}
					}
					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();
	}
}