/***************************************************************************************************
 * Copyright (c) 2005 Eteration A.S. 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: Eteration A.S. - initial API and implementation
 **************************************************************************************************/
package org.eclipse.jst.j2ee.ejb.annotations.internal.xdoclet;

import java.util.Map;

import org.eclipse.core.resources.ICommand;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IProjectDescription;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceDelta;
import org.eclipse.core.resources.IResourceDeltaVisitor;
import org.eclipse.core.resources.IResourceVisitor;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.IncrementalProjectBuilder;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IExecutableExtension;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.content.IContentDescription;
import org.eclipse.core.runtime.content.IContentType;
import org.eclipse.core.runtime.jobs.ISchedulingRule;

public class XDocletBuilder extends IncrementalProjectBuilder implements IExecutableExtension {

	private static final String JAVASOURCE_TYPE = "org.eclipse.jdt.core.javaSource"; //$NON-NLS-1$

	private static final boolean performValidateEdit = false;

	private static final String[] XDOCLETBUILDINCLUDEFILES = { "ejb-jar.xml", "web.xml", "bean.java", "servlet.java",
			"controller.java", "ejb.java", "mdb.java" };

	private static boolean isGloballyEnabled = true;

	/**
	 * Add the XDocletBuilder to the build spec of a single IProject
	 * 
	 * @param project -
	 *            the IProject to add to, when needed
	 */
	public static void add(IProgressMonitor monitor, IProject project, Object validateEditContext) {
		if (project == null || !project.isAccessible()) {
			return;
		}
		boolean isBuilderPresent = false;
		try {
			IFile descriptionFile = project.getFile(IProjectDescription.DESCRIPTION_FILE_NAME);
			if (descriptionFile.exists() && descriptionFile.isAccessible()) {
				IProjectDescription description = project.getDescription();
				ICommand[] commands = description.getBuildSpec();
				if (commands != null) {
					for (int i = 0; i < commands.length; i++) {
						String builderName = commands[i].getBuilderName();
						// builder name will be null if it has not been set
						if (builderName != null && builderName.equals(getBuilderId())) {
							isBuilderPresent = true;
							break;
						}
					}
				}
				if (!isBuilderPresent && !monitor.isCanceled()) {
					// validate for edit
					IStatus status = null;
					if (performValidateEdit) {
						ISchedulingRule validateEditRule = null;
						try {

							IFile[] validateFiles = new IFile[] { descriptionFile };
							IWorkspace workspace = descriptionFile.getWorkspace();
							validateEditRule = workspace.getRuleFactory().validateEditRule(validateFiles);
							Platform.getJobManager().beginRule(validateEditRule, monitor);
							status = workspace.validateEdit(validateFiles, null);
						} finally {
							if (validateEditRule != null) {
								Platform.getJobManager().endRule(validateEditRule);
							}
						}
					}
					if (status == null || status.isOK()) {
						// add the builder
						ICommand newCommand = description.newCommand();
						newCommand.setBuilderName(getBuilderId());
						ICommand[] newCommands = null;
						if (commands != null) {
							newCommands = new ICommand[commands.length + 1];
							System.arraycopy(commands, 0, newCommands, 0, commands.length);
							newCommands[commands.length] = newCommand;
						} else {
							newCommands = new ICommand[1];
							newCommands[0] = newCommand;
						}
						description.setBuildSpec(newCommands);
						/*
						 * This 'refresh' was added since unit tests were
						 * throwing exceptions about being out of sync. That may
						 * indicate a "deeper" problem such as needing to use
						 * scheduling rules, (although there don't appear to be
						 * examples of that) or something similar.
						 */
						// project.refreshLocal(IResource.DEPTH_ZERO,
						// subMonitorFor(monitor, 1,
						// IProgressMonitor.UNKNOWN));
						try {
							project.setDescription(description, monitor);
						} catch (CoreException e) {
							if (performValidateEdit) {
								Logger
										.log(
												Logger.WARNING,
												"Description for project \"" + project.getName() + "\" could not be updated despite successful build"); //$NON-NLS-2$//$NON-NLS-1$					
							} else {
								Logger.log(Logger.WARNING,
										"Description for project \"" + project.getName() + "\" could not be updated"); //$NON-NLS-2$//$NON-NLS-1$					
							}
						}
					}
				}
			} else {
				Logger.log(Logger.WARNING, "Description for project \"" + project.getName() + "\" could not be updated"); //$NON-NLS-2$//$NON-NLS-1$
			}
		} catch (Exception e) {
			// if we can't read the information, the project isn't open,
			// so it can't run auto-validate
			Logger.logException("Exception caught when adding Model Builder", e); //$NON-NLS-1$
		}
	}

	/**
	 * Adds the Builder to every project in the Workspace
	 * 
	 * @param root
	 */
	public synchronized static void add(IProgressMonitor monitor, IWorkspaceRoot root, Object validateEditContext) {
		IProject[] allProjects = root.getProjects();
		IProgressMonitor localMonitor = monitor;
		localMonitor.beginTask("Starting to add builder to projects with EJB modules", 1); //$NON-NLS-1$
		for (int i = 0; i < allProjects.length && !monitor.isCanceled(); i++) {
			if (XDocletPreferenceStore.forProject(allProjects[i]).getBooleanProperty(XDocletPreferenceStore.XDOCLETBUILDERACTIVE)) {
				add(localMonitor, allProjects[i], validateEditContext);
			}
			localMonitor.worked(1);
		}
		localMonitor.done();
	}

	public static String getBuilderId() {
		return "org.eclipse.jst.j2ee.ejb.annotations.internal.emitter.model.xdocletbuilder"; //$NON-NLS-1$
	}

	public static IProgressMonitor monitorFor(IProgressMonitor monitor) {
		if (monitor == null)
			return new NullProgressMonitor();
		return monitor;
	}

	private String fName = "XDoclet Builder"; //$NON-NLS-1$

	/**
	 * 
	 */
	public XDocletBuilder() {
		super();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.core.internal.events.InternalBuilder#build(int,
	 *      java.util.Map, org.eclipse.core.runtime.IProgressMonitor)
	 */
	protected IProject[] build(int kind, Map args, IProgressMonitor monitor) throws CoreException {
		IProject currentProject = getProject();
		// Currently, just use the Task Tags preference
		boolean locallyEnabled = XDocletPreferenceStore.forProject(currentProject).getBooleanProperty(
				XDocletPreferenceStore.XDOCLETBUILDERACTIVE);
		if (!locallyEnabled || currentProject == null || !currentProject.isAccessible()) {
			return new IProject[] { currentProject };
		}

		IResourceDelta delta = getDelta(currentProject);
		IProgressMonitor localMonitor = monitor;
		localMonitor.beginTask(getDisplayName(), 1);

		if (!localMonitor.isCanceled()) {
			// check the kind of delta if one was given
			if (kind == FULL_BUILD || kind == CLEAN_BUILD || delta == null) {
				doFullBuild(kind, args, localMonitor, getProject());
			} else {
				doIncrementalBuild(kind, args, localMonitor);
			}
		}
		localMonitor.worked(1);
		localMonitor.done();

		return new IProject[] { getProject() };
	}

	void build(int kind, Map args, IResource resource, IContentType[] types, IProgressMonitor monitor) {
		if (!monitor.isCanceled() && resource.getType() == IResource.FILE) {
			XDocletAntProjectBuilder antProjectBuilder = XDocletAntProjectBuilder.Factory.newInstance(resource);
			if (antProjectBuilder != null)
				antProjectBuilder.buildUsingAnt(resource, monitor);

		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.core.resources.IncrementalProjectBuilder#clean(org.eclipse.core.runtime.IProgressMonitor)
	 */
	protected void clean(IProgressMonitor monitor) throws CoreException {
		super.clean(monitor);
		IProject currentProject = getProject();
		if (!isGloballyEnabled || currentProject == null || !currentProject.isAccessible()) {
			return;
		}
		// doFullBuild(IncrementalProjectBuilder.CLEAN_BUILD, new HashMap(0),
		// monitor, getProject());
	}

	boolean isXDocletAnnotatedResource(IResource resource) {
		IContentType[] types = null;
		if (resource.getType() == IResource.FILE && resource.isAccessible()) {
			IContentDescription d = null;
			try {
				// optimized description lookup, might not succeed
				d = ((IFile) resource).getContentDescription();
				if (d != null && JAVASOURCE_TYPE.equals(d.getContentType().getId())) {
					return XDoxletAnnotationUtil.isXDocletAnnotatedResource(resource);
				}
			} catch (CoreException e) {
				// should not be possible given the accessible and file type
				// check above
			}
			if (types == null) {
				types = Platform.getContentTypeManager().findContentTypesFor(resource.getName());
				for (int i = 0; i < types.length; i++) {
					IContentType type = types[i];
					if (JAVASOURCE_TYPE.equals(type.getId())) {
						return XDoxletAnnotationUtil.isXDocletAnnotatedResource(resource);
					}
				}
			}
			return false;
		} else if (resource.getType() == IResource.FILE && !resource.isAccessible()) {
			// Deleted - Check to see if this is an xdoclet bean!
			// This is a crude hack to make sure the build runs is a resource is
			// deleted.
			// **Bean.java **Servlet.java **Mdb.java and deployment descriptors
			String name = resource.getName();
			for (int i = 0; name != null && i < XDOCLETBUILDINCLUDEFILES.length; i++) {
				String fileName = XDOCLETBUILDINCLUDEFILES[i];
				if (name.toLowerCase().endsWith(fileName))
					return true;

			}
		}
		return false;
	}

	/**
	 * Iterate through the list of resources and build each one
	 * 
	 * @param monitor
	 * @param resources
	 */
	protected void doFullBuild(int kind, Map args, IProgressMonitor monitor, IProject project) {

		final IProgressMonitor subMonitor = monitor;
		final int localKind = kind;
		final Map localArgs = args;

		final IProgressMonitor visitorMonitor = monitor;
		IResourceVisitor internalBuilder = new IResourceVisitor() {
			// xdoclet builder completes the whole project at once so no need to
			// repeat the build with each annotated bean. Stop after the first
			// one
			boolean buildComplete = false;

			public boolean visit(IResource resource) throws CoreException {
				if (resource.getType() == IResource.FILE && buildComplete == false) {
					// for any supported file type, record the resource
					if (!buildComplete && isXDocletAnnotatedResource(resource)) {
						build(localKind, localArgs, resource, null, subMonitor);
						buildComplete = true;
						visitorMonitor.worked(1);
					}
					return false;
				}
				return true;
			}

		};
		try {
			project.accept(internalBuilder);
		} catch (CoreException e) {
			Logger.logException(e);
		}
	}

	/**
	 * 
	 */
	protected void doIncrementalBuild(int kind, Map args, IProgressMonitor monitor) {
		IResourceDelta projectDelta = getDelta(getProject());
		if (projectDelta == null) {
			throw new IllegalArgumentException("delta is null, should do a full build"); //$NON-NLS-1$
		}

		final Map localArgs = args;
		final int localKind = kind;
		final IProgressMonitor localMonitor = monitor;
		IResourceDeltaVisitor participantVisitor = new IResourceDeltaVisitor() {
			// xdoclet builder completes the whole project at once so no need to
			// repeat the build with each annotated bean. Stop after the first
			// one
			boolean buildComplete = false;

			public boolean visit(IResourceDelta delta) throws CoreException {
				if (!localMonitor.isCanceled() && delta.getResource().getType() == IResource.FILE) {
					if (!buildComplete && isXDocletAnnotatedResource(delta.getResource())) {
						build(localKind, localArgs, delta.getResource(), null, localMonitor);
						buildComplete = true;
					}
				}
				return delta.getAffectedChildren().length > 0;
			}
		};
		try {
			projectDelta.accept(participantVisitor);
		} catch (CoreException e) {
			Logger.logException(e);
		}
		monitor.worked(1);
	}

	private String getDisplayName() {
		return fName;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.core.runtime.IExecutableExtension#setInitializationData(org.eclipse.core.runtime.IConfigurationElement,
	 *      java.lang.String, java.lang.Object)
	 */
	public void setInitializationData(IConfigurationElement config, String propertyName, Object data) throws CoreException {
		if (config != null) {
			fName = config.getDeclaringExtension().getLabel();
		}
	}

	public static void shutdown() {
		// Default
	}

	public static void startup() {
		// Default
	}
}
