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.Iterator;
import java.util.List;
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("com.ibm.sse.model.jsp/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 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);
			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);
		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);
	        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);
		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;
	}

	/**
	 * 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 {
	    
	    if(DEBUG) System.out.println(">> TaglibClassLoader finding class: " + className); //$NON-NLS-1$

		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();
				while (stream.available() > 0) {
					byteStream.write(stream.read());
				}

				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){
				    
				    // 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) {
					    // 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();
				        }
					}					    			
					stream.close();
					jarfile.close();
				}
			}
		} catch (Throwable 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;
		}
		
		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();
	}
}
