/*******************************************************************************
 * Copyright (c) 2008 SAP AG 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:
 * Kaloyan Raev, kaloyan.raev@sap.com - initial API and implementation
 *******************************************************************************/
package org.eclipse.jst.j2ee.internal.common.operations;

import static org.eclipse.jst.j2ee.internal.common.operations.INewJavaClassDataModelProperties.JAVA_PACKAGE;
import static org.eclipse.jst.j2ee.internal.common.operations.INewJavaClassDataModelProperties.JAVA_PACKAGE_FRAGMENT_ROOT;
import static org.eclipse.jst.j2ee.internal.common.operations.INewJavaClassDataModelProperties.SOURCE_FOLDER;
import static org.eclipse.wst.common.componentcore.internal.operation.IArtifactEditOperationDataModelProperties.PROJECT_NAME;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URL;

import org.eclipse.core.commands.ExecutionException;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.FileLocator;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Preferences;
import org.eclipse.emf.codegen.jet.JETException;
import org.eclipse.jdt.core.IJavaModelMarker;
import org.eclipse.jdt.core.IPackageFragment;
import org.eclipse.jdt.core.IPackageFragmentRoot;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jem.util.emf.workbench.ProjectUtilities;
import org.eclipse.jst.j2ee.internal.plugin.J2EEPlugin;
import org.eclipse.jst.j2ee.internal.project.WTPJETEmitter;
import org.eclipse.wst.common.frameworks.datamodel.AbstractDataModelOperation;
import org.eclipse.wst.common.frameworks.datamodel.IDataModel;
import org.eclipse.wst.common.frameworks.internal.WTPPlugin;
import org.eclipse.wst.common.frameworks.internal.enablement.nonui.WFTWrappedException;

public abstract class NewJavaEEArtifactClassOperation extends AbstractDataModelOperation {

	/**
	 * The extension name for a java class
	 */
	protected static final String DOT_JAVA = ".java"; //$NON-NLS-1$
	
	/**
	 * Method name of template implementation classes. 
	 */
	protected static final String GENERATE_METHOD = "generate"; //$NON-NLS-1$

	public NewJavaEEArtifactClassOperation(IDataModel dataModel) {
		super(dataModel);
	}

	@Override
	public IStatus execute(IProgressMonitor monitor, IAdaptable info)
			throws ExecutionException {
		return doExecute(monitor, info);
	}
	
	/**
	 * Subclasses may extend this method to add their own actions during
	 * execution. The implementation of the execute method drives the running of
	 * the operation. This implementation will create the java source folder,
	 * create the java package, and then if using annotations, will use
	 * templates to generate an annotated web artifact java class, or if it is
	 * not annotated, the web artifact java class file will be created without
	 * the annotated tags using templates. Optionally, subclasses may extend the
	 * generateUsingTemplates or createJavaFile method rather than extend the
	 * execute method. This method will accept a null parameter.
	 * 
	 * @see org.eclipse.wst.common.frameworks.internal.operation.WTPOperation#execute(org.eclipse.core.runtime.IProgressMonitor)
	 * @see NewWebClassOperation#generateUsingTemplates(IProgressMonitor,
	 *      IPackageFragment)
	 * 
	 * @param monitor
	 * @throws CoreException
	 * @throws InterruptedException
	 * @throws InvocationTargetException
	 */
	public IStatus doExecute(IProgressMonitor monitor, IAdaptable info) throws ExecutionException {
		// Create source folder if it does not exist
		createJavaSourceFolder();
		// Create java package if it does not exist
		IPackageFragment pack = createJavaPackage();
		// Generate using templates
		try {
			generateUsingTemplates(monitor, pack);
		} catch (Exception e) {
			return J2EEPlugin.createStatus(IStatus.ERROR, e.getMessage(), e);
		}
		return OK_STATUS;
	}
	
	protected abstract void generateUsingTemplates(IProgressMonitor monitor,
			IPackageFragment fragment) throws WFTWrappedException,
			CoreException;

	/**
	 * This method will return the java package as specified by the new java
	 * class data model. If the package does not exist, it will create the
	 * package. This method should not return null.
	 * 
	 * @see #JAVA_PACKAGE
	 * @see IPackageFragmentRoot#createPackageFragment(java.lang.String,
	 *      boolean, org.eclipse.core.runtime.IProgressMonitor)
	 * 
	 * @return IPackageFragment the java package
	 */
	protected final IPackageFragment createJavaPackage() {
		// Retrieve the package name from the java class data model
		String packageName = model.getStringProperty(JAVA_PACKAGE);
		IPackageFragmentRoot packRoot = (IPackageFragmentRoot) model.getProperty(JAVA_PACKAGE_FRAGMENT_ROOT);
		IPackageFragment pack = packRoot.getPackageFragment(packageName);
		// Handle default package
		if (pack == null) {
			pack = packRoot.getPackageFragment(""); //$NON-NLS-1$
		}
		// Create the package fragment if it does not exist
		if (!pack.exists()) {
			String packName = pack.getElementName();
			try {
				pack = packRoot.createPackageFragment(packName, true, null);
			} catch (JavaModelException e) {
				J2EEPlugin.logError(e);
			}
		}
		// Return the package
		return pack;
	}

	/**
	 * This method checks the
	 * {@link J2EEPlugin#DYNAMIC_TRANSLATION_OF_JET_TEMPLATES_PREF_KEY}
	 * preference to determine the method for generating the source code of the
	 * Java EE artifact:
	 * <ul>
	 * 		<li>dynamically using the provided JET template file, or</li>
	 * 		<li>using the statically build-in template implementation class. </li> 
	 * </ul>
	 * 
	 * @param plugin
	 *            - the plugin which calls the current method
	 * @param templateModel
	 *            - a template model that is used by the JET template file or
	 *            the template implementation class
	 * @param templateFile
	 *            - a Java JET template file
	 * @param templateImpl
	 *            - a Java JET template implementation class
	 * @param monitor
	 *            - a monitor to report the progress of the code generation
	 * @param templateImpl
	 *            - a Java JET template implementation class
	 * 
	 * @return a String object with the generated source code
	 * 
	 * @throws JETException
	 *             if a problem occurs in during code generation
	 * 
	 * @see #generateTemplateSource(WTPPlugin,
	 *      CreateJavaEEArtifactTemplateModel, String, IProgressMonitor)
	 * @see #generateTemplateSource(CreateJavaEEArtifactTemplateModel, Object)
	 */
	protected String generateTemplateSource(WTPPlugin plugin, CreateJavaEEArtifactTemplateModel templateModel, String templateFile, Object templateImpl, IProgressMonitor monitor) 
			throws JETException {
		Preferences preferences = J2EEPlugin.getDefault().getPluginPreferences();
		boolean dynamicTranslation = preferences.getBoolean(J2EEPlugin.DYNAMIC_TRANSLATION_OF_JET_TEMPLATES_PREF_KEY);
		
		if (dynamicTranslation) {
			return generateTemplateSource(plugin, templateModel, templateFile, monitor);
		}
		return generateTemplateSource(templateModel, templateImpl);
	}
	
	/**
	 * This method uses the statically built-in template implementation class to
	 * generate the source code of the Java EE artifact with the given template
	 * model.
	 * 
	 * @param templateModel
	 *            - a template model that is used by the template implementation
	 *            class
	 * @param templateImpl
	 *            - a Java JET template implementation class
	 * 
	 * @return a String object with the generated source code
	 * 
	 * @throws JETException
	 *             if a problem occurs in during code generation
	 */
	protected String generateTemplateSource(CreateJavaEEArtifactTemplateModel templateModel, Object templateImpl) 
			throws JETException {
		try {
			Method method = templateImpl.getClass().getMethod(GENERATE_METHOD, new Class[] { Object.class });
			return (String) method.invoke(templateImpl, templateModel);
		} catch (SecurityException e) {
			throw new JETException(e);
		} catch (NoSuchMethodException e) {
			throw new JETException(e);
		} catch (IllegalArgumentException e) {
			throw new JETException(e);
		} catch (IllegalAccessException e) {
			throw new JETException(e);
		} catch (InvocationTargetException e) {
			throw new JETException(e);
		}
	}

	/**
	 * This method uses the WTPJETEmitter to generate the source code of the
	 * Java EE artifact with the given template model and template file.
	 * 
	 * @param plugin
	 *            - the plugin which calls the current method
	 * @param templateModel
	 *            - a template model that is used by the JET template file
	 * @param templateFile
	 *            - a Java JET template file
	 * @param monitor
	 *            - a monitor to report the progress of the code generation
	 * 
	 * @return a String object with the generated source code
	 * 
	 * @throws JETException
	 *             if a problem occurs in the JET emitter
	 */
	protected String generateTemplateSource(WTPPlugin plugin, CreateJavaEEArtifactTemplateModel templateModel, String templateFile, IProgressMonitor monitor) 
			throws JETException {
		URL templateURL = FileLocator.find(plugin.getBundle(), new Path(templateFile), null);
		cleanUpOldEmitterProject();
		WTPJETEmitter emitter = new WTPJETEmitter(templateURL.toString(), this.getClass().getClassLoader());
		emitter.setIntelligentLinkingEnabled(true);
		emitter.addVariable(J2EEPlugin.getPlugin().getPluginID(), J2EEPlugin.getPlugin().getPluginID());
		emitter.addVariable(plugin.getPluginID(), plugin.getPluginID());
		return emitter.generate(monitor, new Object[] { templateModel });
	}

	protected void cleanUpOldEmitterProject() {
		IProject project = ProjectUtilities.getProject(WTPJETEmitter.PROJECT_NAME);
		if (project == null || !project.exists())
			return;
		try {
			IMarker[] markers = project.findMarkers(IJavaModelMarker.BUILDPATH_PROBLEM_MARKER, false, IResource.DEPTH_ZERO);
			for (int i = 0, l = markers.length; i < l; i++) {
				if (((Integer) markers[i].getAttribute(IMarker.SEVERITY)).intValue() == IMarker.SEVERITY_ERROR) {
					project.delete(true, new NullProgressMonitor());
					break;
				}
			}
		} catch (Exception e) {
			J2EEPlugin.logError(e);
		}
	}
	
	/**
	 * This method will return the java source folder as specified in the java
	 * class data model. It will create the java source folder if it does not
	 * exist. This method may return null.
	 * 
	 * @see #SOURCE_FOLDER
	 * @see IFolder#create(boolean, boolean,
	 *      org.eclipse.core.runtime.IProgressMonitor)
	 * 
	 * @return IFolder the java source folder
	 */
	protected final IFolder createJavaSourceFolder() {
		// Get the source folder name from the data model
		IFolder folder = getSourceFolder();
		// If folder does not exist, create the folder with the specified path
		if (!folder.exists()) {
			try {
				folder.create(true, true, null);
			} catch (CoreException e) {
				J2EEPlugin.logError(e);
			}
		}
		// Return the source folder
		return folder;
	}

	public IProject getTargetProject() {
		String projectName = model.getStringProperty(PROJECT_NAME);
		return ProjectUtilities.getProject(projectName);
	}
	
	protected IFolder getSourceFolder() {
		String folderFullPath = model.getStringProperty(SOURCE_FOLDER);
		IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
		return root.getFolder(new Path(folderFullPath));
	}	

}
