/*******************************************************************************
 * Copyright (c) 2003, 2004 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
 * 
 * Contributors:
 * IBM Corporation - initial API and implementation
 *******************************************************************************/
/*
 * Created on Mar 17, 2004
 *
 * To change the template for this generated file go to
 * Window&gt;Preferences&gt;Java&gt;Code Generation&gt;Code and Comments
 */
package org.eclipse.jst.j2ee.internal.project;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.InputStream;
import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;

import org.eclipse.core.internal.runtime.Assert;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IProjectDescription;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.IncrementalProjectBuilder;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.ILibrary;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IPluginDescriptor;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.SubProgressMonitor;
import org.eclipse.emf.codegen.CodeGenPlugin;
import org.eclipse.emf.codegen.jet.JETCompiler;
import org.eclipse.emf.codegen.jet.JETEmitter;
import org.eclipse.emf.codegen.jet.JETException;
import org.eclipse.jdt.core.IClasspathEntry;
import org.eclipse.jdt.core.IJavaModel;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IPackageFragmentRoot;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.internal.core.ClasspathEntry;
import org.eclipse.jdt.launching.JavaRuntime;

import com.ibm.wtp.common.logger.proxy.Logger;

/**
 * @author schacher, mdelder
 * 
 * To change the template for this generated type comment go to
 * Window&gt;Preferences&gt;Java&gt;Code Generation&gt;Code and Comments
 */
public class WTPJETEmitter extends JETEmitter {

	private Map variables;

	private boolean intelligentLinkingEnabled = false;

	private JETCompiler jetCompiler;

	/**
	 * @param templateURI
	 */
	public WTPJETEmitter(String templateURI) {
		super(templateURI);
	}

	/**
	 * @param templateURIPath
	 * @param relativeTemplateURI
	 */
	public WTPJETEmitter(String[] templateURIPath, String relativeTemplateURI) {
		super(templateURIPath, relativeTemplateURI);
	}

	/**
	 * @param templateURI
	 * @param classLoader
	 */
	public WTPJETEmitter(String templateURI, ClassLoader classLoader) {
		super(templateURI, classLoader);
	}

	/**
	 * @param templateURIPath
	 * @param relativeTemplateURI
	 * @param classLoader
	 */
	public WTPJETEmitter(String[] templateURIPath, String relativeTemplateURI, ClassLoader classLoader) {
		super(templateURIPath, relativeTemplateURI, classLoader);
	}

	/**
	 * @param templateURIPath
	 * @param relativeTemplateURI
	 * @param classLoader
	 * @param encoding
	 */
	public WTPJETEmitter(String[] templateURIPath, String relativeTemplateURI, ClassLoader classLoader, String encoding) {
		super(templateURIPath, relativeTemplateURI, classLoader, encoding);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.emf.codegen.jet.JETEmitter#initialize(org.eclipse.core.runtime.IProgressMonitor)
	 */
	public void initialize(IProgressMonitor progressMonitor) throws JETException {

		progressMonitor.beginTask("", 10); //$NON-NLS-1$
		progressMonitor.subTask(CodeGenPlugin.getPlugin().getString("_UI_GeneratingJETEmitterFor_message", new Object[]{templateURI})); //$NON-NLS-1$

		try {
			// This ensures that the JRE variables are initialized.
			//
			try {
				JavaRuntime.getDefaultVMInstall();
			} catch (Throwable throwable) {
				// This is kind of nasty to come here.
				//
				URL jreURL = new URL(Platform.getPlugin("org.eclipse.emf.codegen").getDescriptor().getInstallURL(), "plugin.xml"); //$NON-NLS-1$ //$NON-NLS-2$
				IPath jrePath = new Path(Platform.asLocalURL(jreURL).getFile());
				jrePath = jrePath.removeLastSegments(1).append(new Path("../../jre/lib/rt.jar")); //$NON-NLS-1$
				if (!jrePath.equals(JavaCore.getClasspathVariable(JavaRuntime.JRELIB_VARIABLE))) {
					JavaCore.setClasspathVariable(JavaRuntime.JRELIB_VARIABLE, jrePath, null);
				}
			}

			/*
			 * final JETCompiler jetCompiler = templateURIPath == null ? new
			 * MyJETCompiler(templateURI, encoding) :
			 */

			getJetCompiler();

			progressMonitor.subTask(CodeGenPlugin.getPlugin().getString("_UI_JETParsing_message", new Object[]{jetCompiler.getResolvedTemplateURI()})); //$NON-NLS-1$
			jetCompiler.parse();
			progressMonitor.worked(1);

			ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
			jetCompiler.generate(outputStream);
			final InputStream contents = new ByteArrayInputStream(outputStream.toByteArray());

			final IWorkspace workspace = ResourcesPlugin.getWorkspace();
			IJavaModel javaModel = JavaCore.create(ResourcesPlugin.getWorkspace().getRoot());
			if (!javaModel.isOpen()) {
				javaModel.open(new SubProgressMonitor(progressMonitor, 1));
			} else {
				progressMonitor.worked(1);
			}

			final IProject project = workspace.getRoot().getProject(getProjectName());
			progressMonitor.subTask(CodeGenPlugin.getPlugin().getString("_UI_JETPreparingProject_message", new Object[]{project.getName()})); //$NON-NLS-1$

			IJavaProject javaProject;
			if (!project.exists()) {
				javaProject = createJavaProject(progressMonitor, workspace, project);

				initializeJavaProject(progressMonitor, project, javaProject);

				javaProject.close();
			} else {
				project.open(new SubProgressMonitor(progressMonitor, 5));
				javaProject = JavaCore.create(project);
			}

			IPackageFragmentRoot sourcePackageFragmentRoot = openJavaProjectIfNecessary(progressMonitor, project, javaProject);

			String packageName = jetCompiler.getSkeleton().getPackageName();
			StringTokenizer stringTokenizer = new StringTokenizer(packageName, "."); //$NON-NLS-1$
			IProgressMonitor subProgressMonitor = new SubProgressMonitor(progressMonitor, 1);
			subProgressMonitor.beginTask("", stringTokenizer.countTokens() + 4); //$NON-NLS-1$
			subProgressMonitor.subTask(CodeGenPlugin.getPlugin().getString("_UI_CreateTargetFile_message")); //$NON-NLS-1$
			IContainer sourceContainer = (IContainer) sourcePackageFragmentRoot.getCorrespondingResource();
			while (stringTokenizer.hasMoreElements()) {
				String folderName = stringTokenizer.nextToken();
				sourceContainer = sourceContainer.getFolder(new Path(folderName));
				if (!sourceContainer.exists()) {
					((IFolder) sourceContainer).create(false, true, new SubProgressMonitor(subProgressMonitor, 1));
				}
			}
			IFile targetFile = sourceContainer.getFile(new Path(jetCompiler.getSkeleton().getClassName() + ".java")); //$NON-NLS-1$
			if (!targetFile.exists()) {
				subProgressMonitor.subTask(CodeGenPlugin.getPlugin().getString("_UI_JETCreating_message", new Object[]{targetFile.getFullPath()})); //$NON-NLS-1$
				targetFile.create(contents, true, new SubProgressMonitor(subProgressMonitor, 1));
			} else {
				subProgressMonitor.subTask(CodeGenPlugin.getPlugin().getString("_UI_JETUpdating_message", new Object[]{targetFile.getFullPath()})); //$NON-NLS-1$
				targetFile.setContents(contents, true, true, new SubProgressMonitor(subProgressMonitor, 1));
			}

			boolean errors = performBuild(project, subProgressMonitor, targetFile);

			if (!errors) {
				loadClass(workspace, project, javaProject, packageName, subProgressMonitor);
			}

			subProgressMonitor.done();
		} catch (CoreException exception) {
			throw new JETException(exception);
		} catch (Exception exception) {
			throw new JETException(exception);
		} finally {
			progressMonitor.done();
		}

	}

	/**
	 * @param progressMonitor
	 * @param project
	 * @param javaProject
	 * @return
	 * @throws JavaModelException
	 */
	protected IPackageFragmentRoot openJavaProjectIfNecessary(IProgressMonitor progressMonitor, final IProject project, IJavaProject javaProject) throws JavaModelException {
		progressMonitor.subTask(CodeGenPlugin.getPlugin().getString("_UI_JETOpeningJavaProject_message", new Object[]{project.getName()})); //$NON-NLS-1$
		javaProject.open(new SubProgressMonitor(progressMonitor, 1));

		IPackageFragmentRoot[] packageFragmentRoots = javaProject.getPackageFragmentRoots();
		IPackageFragmentRoot sourcePackageFragmentRoot = null;
		for (int j = 0; j < packageFragmentRoots.length; ++j) {
			IPackageFragmentRoot packageFragmentRoot = packageFragmentRoots[j];
			if (packageFragmentRoot.getKind() == IPackageFragmentRoot.K_SOURCE) {
				sourcePackageFragmentRoot = packageFragmentRoot;
				break;
			}
		}
		return sourcePackageFragmentRoot;
	}

	/**
	 * @param progressMonitor
	 * @param project
	 * @param javaProject
	 * @throws CoreException
	 * @throws JavaModelException
	 */
	protected void initializeJavaProject(IProgressMonitor progressMonitor, final IProject project, IJavaProject javaProject) throws CoreException, JavaModelException {
		progressMonitor.subTask(CodeGenPlugin.getPlugin().getString("_UI_JETInitializingProject_message", new Object[]{project.getName()})); //$NON-NLS-1$
		IClasspathEntry classpathEntry = JavaCore.newSourceEntry(new Path("/" + project.getName() + "/src")); //$NON-NLS-1$ //$NON-NLS-2$

		IClasspathEntry jreClasspathEntry = JavaCore.newVariableEntry(new Path(JavaRuntime.JRELIB_VARIABLE), new Path(JavaRuntime.JRESRC_VARIABLE), new Path(JavaRuntime.JRESRCROOT_VARIABLE));

		List classpath = new ArrayList();
		classpath.add(classpathEntry);
		classpath.add(jreClasspathEntry);
		classpath.addAll(classpathEntries);

		IFolder sourceFolder = project.getFolder(new Path("src")); //$NON-NLS-1$
		if (!sourceFolder.exists()) {
			sourceFolder.create(false, true, new SubProgressMonitor(progressMonitor, 1));
		}
		IFolder runtimeFolder = project.getFolder(new Path("runtime")); //$NON-NLS-1$
		if (!runtimeFolder.exists()) {
			runtimeFolder.create(false, true, new SubProgressMonitor(progressMonitor, 1));
		}

		IClasspathEntry[] classpathEntryArray = (IClasspathEntry[]) classpath.toArray(new IClasspathEntry[classpath.size()]);

		javaProject.setRawClasspath(classpathEntryArray, new SubProgressMonitor(progressMonitor, 1));

		javaProject.setOutputLocation(new Path("/" + project.getName() + "/runtime"), new SubProgressMonitor(progressMonitor, 1)); //$NON-NLS-1$ //$NON-NLS-2$

		// appended from previous implementation
		createClasspathEntries(project);
	}

	/**
	 * @param progressMonitor
	 * @param workspace
	 * @param project
	 * @return
	 * @throws CoreException
	 */
	private IJavaProject createJavaProject(IProgressMonitor progressMonitor, final IWorkspace workspace, final IProject project) throws CoreException {
		IJavaProject javaProject;
		progressMonitor.subTask("JET creating project " + project.getName()); //$NON-NLS-1$
		project.create(new SubProgressMonitor(progressMonitor, 1));
		progressMonitor.subTask(CodeGenPlugin.getPlugin().getString("_UI_JETCreatingProject_message", new Object[]{project.getName()})); //$NON-NLS-1$
		IProjectDescription description = workspace.newProjectDescription(project.getName());
		description.setNatureIds(new String[]{JavaCore.NATURE_ID});
		description.setLocation(null);
		project.open(new SubProgressMonitor(progressMonitor, 1));
		project.setDescription(description, new SubProgressMonitor(progressMonitor, 1));

		javaProject = JavaCore.create(project);
		return javaProject;
	}

	/**
	 * @param workspace
	 * @param project
	 * @param javaProject
	 * @param packageName
	 * @param subProgressMonitor
	 * @throws JavaModelException
	 * @throws MalformedURLException
	 * @throws ClassNotFoundException
	 * @throws SecurityException
	 */
	protected void loadClass(final IWorkspace workspace, final IProject project, IJavaProject javaProject, String packageName, IProgressMonitor subProgressMonitor) throws JavaModelException, MalformedURLException, ClassNotFoundException, SecurityException {
		//IContainer targetContainer =
		// workspace.getRoot().getFolder(javaProject.getOutputLocation());

		subProgressMonitor.subTask(CodeGenPlugin.getPlugin().getString("_UI_JETLoadingClass_message", new Object[]{jetCompiler.getSkeleton().getClassName() + ".class"})); //$NON-NLS-1$ //$NON-NLS-2$

		// Construct a proper URL for relative lookup.
		//
		URL url = new File(project.getLocation() + "/" + javaProject.getOutputLocation().removeFirstSegments(1) + "/").toURL(); //$NON-NLS-1$ //$NON-NLS-2$
		URLClassLoader theClassLoader = new URLClassLoader(new URL[]{url}, classLoader);
		Class theClass = theClassLoader.loadClass((packageName.length() == 0 ? "" : packageName + ".") + jetCompiler.getSkeleton().getClassName()); //$NON-NLS-1$ //$NON-NLS-2$
		String methodName = jetCompiler.getSkeleton().getMethodName();
		Method[] methods = theClass.getDeclaredMethods();
		for (int i = 0; i < methods.length; ++i) {
			if (methods[i].getName().equals(methodName)) {
				setMethod(methods[i]);
				break;
			}
		}
	}

	/**
	 * @param project
	 * @param subProgressMonitor
	 * @param targetFile
	 * @return
	 * @throws CoreException
	 */
	protected boolean performBuild(final IProject project, IProgressMonitor subProgressMonitor, IFile targetFile) throws CoreException {
		subProgressMonitor.subTask(CodeGenPlugin.getPlugin().getString("_UI_JETBuilding_message", new Object[]{project.getName()})); //$NON-NLS-1$
		project.build(IncrementalProjectBuilder.INCREMENTAL_BUILD, new SubProgressMonitor(subProgressMonitor, 1));

		IMarker[] markers = targetFile.findMarkers(IMarker.PROBLEM, true, IResource.DEPTH_INFINITE);
		boolean errors = false;
		for (int i = 0; i < markers.length; ++i) {
			IMarker marker = markers[i];
			if (marker.getAttribute(IMarker.SEVERITY, IMarker.SEVERITY_INFO) == IMarker.SEVERITY_ERROR) {
				errors = true;
				subProgressMonitor.subTask(marker.getAttribute(IMarker.MESSAGE) + " : " + (CodeGenPlugin.getPlugin().getString("jet.mark.file.line", new Object[]{targetFile.getLocation(), marker.getAttribute(IMarker.LINE_NUMBER)}))); //$NON-NLS-1$ //$NON-NLS-2$
			}
		}
		return errors;
	}

	/**
	 * Create the correct classpath entries for the given project
	 * 
	 * @param project
	 */
	protected void createClasspathEntries(IProject project) {
		Assert.isNotNull(project, "A valid project is required in order to append to a classpath"); //$NON-NLS-1$
		String variableName = null;
		String pluginId = null;
		for (Iterator variablesKeyIterator = getVariables().keySet().iterator(); variablesKeyIterator.hasNext();) {
			variableName = (String) variablesKeyIterator.next();
			pluginId = (String) getVariables().get(variableName);
			if (hasOutputDirectory(pluginId))
				addLinkedFolderAsLibrary(project, variableName, pluginId);
			else
				addRuntimeJarsAsLibrary(project, pluginId);
		}
	}

	/**
	 * @param pluginId
	 * @return
	 */
	protected boolean hasOutputDirectory(String pluginId) {
		IPluginDescriptor pluginDescriptor = Platform.getPlugin(pluginId).getDescriptor();
		URL outputDirectory = pluginDescriptor.find(new Path("bin")); //$NON-NLS-1$
		if (outputDirectory == null)
			return false;
		java.io.File outputDirectoryFile = new File(outputDirectory.getPath());
		return outputDirectoryFile.canRead() && outputDirectoryFile.isDirectory() && outputDirectoryFile.listFiles().length > 0;
	}

	/**
	 * @param project
	 * @param variableName
	 * @param pluginId
	 */
	protected void addRuntimeJarsAsLibrary(IProject project, String pluginId) {
		IPluginDescriptor pluginDescriptor = Platform.getPlugin(pluginId).getDescriptor();
		ILibrary[] runtimeLibs = pluginDescriptor.getRuntimeLibraries();
		IClasspathEntry entry = null;
		IPath runtimeLibFullPath = null;
		URL fullurl = null;
		for (int i = 0; i < runtimeLibs.length; i++) {
			fullurl = pluginDescriptor.find(runtimeLibs[i].getPath());
			// fix the problem with leading slash that caused dup classpath entries
			File file = new File(fullurl.getPath());
			runtimeLibFullPath = new Path(file.toString());
			entry = new ClasspathEntry(IPackageFragmentRoot.K_BINARY, IClasspathEntry.CPE_LIBRARY, runtimeLibFullPath, ClasspathEntry.INCLUDE_ALL, ClasspathEntry.EXCLUDE_NONE, null, /*
																																													   * Source
																																													   * attachment
																																													   * root
																																													   */
			null, /* Source attachment root */
			null, /* specific output folder */
			false); /* is exported ? *///JavaCore.newLibraryEntry(runtimeLibFullPath, null, null);
			try {
				J2EEProjectUtilities.appendJavaClassPath(project, entry);
			} catch (JavaModelException e) {
				Logger.getLogger().logError("Problem appending \"" + entry.getPath() + "\" to classpath of Project \"" + project.getName() + "\"."); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
				Logger.getLogger().logError(e);
			}
		}
	}

	/**
	 * @param progressMonitor
	 */
	protected void updateProgress(IProgressMonitor progressMonitor, String key) {
		progressMonitor.subTask(getMessage(key));
	}

	/**
	 * @param progressMonitor
	 */
	protected void updateProgress(IProgressMonitor progressMonitor, String key, Object[] args) {
		progressMonitor.subTask(getMessage(key, args));
	}

	protected String getMessage(String key) {
		return CodeGenPlugin.getPlugin().getString(key);
	}

	protected String getMessage(String key, Object[] args) {
		return CodeGenPlugin.getPlugin().getString(key, args);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.emf.codegen.jet.JETEmitter#addVariable(java.lang.String, java.lang.String)
	 */
	public void addVariable(String variableName, String pluginID) throws JETException {
		if (!isIntelligentLinkingEnabled())
			super.addVariable(variableName, pluginID);
		else {
			getVariables().put(variableName, pluginID);
			IWorkspace workspace = ResourcesPlugin.getWorkspace();
			IProject project = workspace.getRoot().getProject(getProjectName());
			if (project != null && project.exists())
				createClasspathEntries(project);
		}

	}

	/**
	 * @return
	 */
	private boolean isIntelligentLinkingEnabled() {
		return intelligentLinkingEnabled;
	}

	/**
	 * @return
	 */
	private Map getVariables() {
		if (variables == null)
			variables = new HashMap();
		return variables;
	}

	protected void addLinkedFolderAsLibrary(IProject project, String variableName, String pluginID) {
		try {
			IPluginDescriptor pluginDescriptor = Platform.getPlugin(pluginID).getDescriptor();
			URL outputDirectory = pluginDescriptor.find(new Path("bin")); //$NON-NLS-1$
			String pathString = Platform.asLocalURL(outputDirectory).getPath();
			if (pathString.endsWith("/")) //$NON-NLS-1$
				pathString = pathString.substring(0, pathString.length() - 1);
			if (pathString.startsWith("/")) //$NON-NLS-1$
				pathString = pathString.substring(1, pathString.length());
			IPath path = new Path(pathString).makeAbsolute();

			String binDirectoryVariable = variableName + "_BIN"; //$NON-NLS-1$
			IFolder linkedDirectory = project.getFolder(binDirectoryVariable);
			if (!linkedDirectory.exists()) {
				linkedDirectory.createLink(path, IResource.ALLOW_MISSING_LOCAL, null);
				linkedDirectory.setDerived(true);
				project.refreshLocal(IResource.DEPTH_INFINITE, null);
			}
			IClasspathEntry entry = new ClasspathEntry(IPackageFragmentRoot.K_BINARY, IClasspathEntry.CPE_LIBRARY, linkedDirectory.getFullPath(), ClasspathEntry.INCLUDE_ALL, ClasspathEntry.EXCLUDE_NONE, null, // source
						// attachment
						null, // source attachment root
						null, // custom output location
						false);

			J2EEProjectUtilities.appendJavaClassPath(project, entry);

		} catch (Exception e) {
			Logger.getLogger().logError(e);
		}
	}

	/**
	 * @param intelligentLinkingEnabled
	 *            The intelligentLinkingEnabled to set.
	 */
	public void setIntelligentLinkingEnabled(boolean intelligentLinkingEnabled) {
		this.intelligentLinkingEnabled = intelligentLinkingEnabled;
	}

	protected JETCompiler getJetCompiler() {
		try {
			if (jetCompiler == null) {
				jetCompiler = templateURIPath == null ? new MyJETCompiler(templateURI, encoding) : new MyJETCompiler(templateURIPath, templateURI, encoding);
			}
		} catch (JETException e) {
			Logger.getLogger().logError(e);
		}
		return jetCompiler;
	}
}