/*******************************************************************************
 * Copyright (c) 2003, 2010 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
 * yyyymmdd bug      Email and other contact information
 * -------- -------- -----------------------------------------------------------
 * 20060509   125094 sengpl@ca.ibm.com - Seng Phung-Lu, Use WorkspaceModifyOperation
 * 20060515   115225 sengpl@ca.ibm.com - Seng Phung-Lu
 * 20060517   142342 kathy@ca.ibm.com - Kathy Chan
 * 20060828	  155439 mahutch@ca.ibm.com - Mark Hutchinson
 * 20070501   184505 kathy@ca.ibm.com - Kathy Chan
 * 20070502   184505 kathy@ca.ibm.com - Kathy Chan, Update JAR sizes
 * 20071102   208620 kathy@ca.ibm.com - Kathy Chan, Update JAR sizes
 * 20071102   202222 kathy@ca.ibm.com - Kathy Chan
 * 20080122   216165 kathy@ca.ibm.com - Kathy Chan
 * 20080326   224148 makandre@ca.ibm.com - Andrew Mak, Web service scenarios broke in latest builds with Equinox p2
 * 20100304   304385 mahutch@ca.ibm.com - Mark Hutchinson, Allow users to disable copying axis jars
 *******************************************************************************/
package org.eclipse.jst.ws.internal.axis.consumption.ui.task;


import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.FileLocator;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Status;
import org.eclipse.jdt.core.IClasspathEntry;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jst.ws.internal.axis.consumption.ui.AxisConsumptionUIMessages;
import org.eclipse.jst.ws.internal.axis.consumption.ui.plugin.WebServiceAxisConsumptionUIPlugin;
import org.eclipse.jst.ws.internal.common.J2EEUtils;
import org.eclipse.jst.ws.internal.common.ResourceUtils;
import org.eclipse.jst.ws.internal.consumption.ConsumptionMessages;
import org.eclipse.wst.command.internal.env.common.FileResourceUtils;
import org.eclipse.wst.command.internal.env.core.common.ProgressUtils;
import org.eclipse.wst.command.internal.env.core.common.StatusUtils;
import org.eclipse.wst.command.internal.env.core.context.ResourceContext;
import org.eclipse.wst.command.internal.env.core.context.TransientResourceContext;
import org.eclipse.wst.common.environment.IEnvironment;
import org.eclipse.wst.common.frameworks.datamodel.AbstractDataModelOperation;
import org.eclipse.wst.ws.internal.common.BundleUtils;


public class CopyAxisJarCommand extends AbstractDataModelOperation {

	public static String AXIS_JAR = "axis.jar"; //$NON-NLS-1$
	public static String AXIS_RUNTIME_PLUGIN_ID = "org.apache.axis"; //$NON-NLS-1$
	public static String COMMON_DISCOVERY_PLUGIN_ID = "org.apache.commons.discovery"; //$NON-NLS-1$
	public static String COMMON_DISCOVERY_JAR = "commons-discovery-0.2.jar"; //$NON-NLS-1$
	public static String JAVAX_XML_RPC_PLUGIN_ID = "javax.xml.rpc"; //$NON-NLS-1$
	public static String JAVAX_XML_RPC_JAR = "jaxrpc.jar"; //$NON-NLS-1$
	public static String JAVAX_XML_SOAP_PLUGIN_ID = "javax.xml.soap"; //$NON-NLS-1$
	public static String JAVAX_XML_SOAP_JAR = "saaj.jar"; //$NON-NLS-1$
	public static String JAVAX_WSDL_PLUGIN_ID = "javax.wsdl"; //$NON-NLS-1$
	public static String JAVAX_WSDL_JAR = "wsdl4j.jar"; //$NON-NLS-1$
	public static String COMMON_LOGGING_PLUGIN_ID = "org.apache.commons.logging"; //$NON-NLS-1$
	public static String COMMON_LOGGING_JAR = "commons-logging.jar"; //$NON-NLS-1$
	private static long AXIS_JAR_SIZE = 1588063L;
	private static long COMMON_DISCOVERY_JAR_SIZE = 71451L;
	private static long JAVAX_XML_RPC_JAR_SIZE = 32361L;
	private static long JAVAX_XML_SOAP_JAR_SIZE = 19582L;
	private static long JAVAX_WSDL_JAR_SIZE = 134085L;
	private static long COMMON_LOGGING_JAR_SIZE = 39353L;

// Web Services Jars Used in previous Versions of WTP but now obsolete
	private static String[] OBSOLETE_JARS = new String[]{"commons-discovery.jar", "commons-logging-1.0.4.jar", "log4j-1.2.4.jar", "log4j-1.2.8.jar", "wsdl4j-1.5.1.jar", "axis-ant.jar"};

	public static String PATH_TO_JARS_IN_PLUGIN = "lib/";

	private IProject project;
	private Boolean projectRestartRequired_ = Boolean.FALSE;
	private IClasspathEntry[] oldClasspath;
	private ArrayList newJarNamesList = new ArrayList();

	/**
	 * Default CTOR;
	 */
	public CopyAxisJarCommand() {
	}

	/**
	 * Execute the command
	 */
	public IStatus execute(IProgressMonitor monitor, IAdaptable adaptable) {
		
		if (WebServiceAxisConsumptionUIPlugin.getInstance().getPluginPreferences().getBoolean("disableAxisJarCopy")) {
			//IStatus status = new Status(IStatus.WARNING, WebServiceAxisConsumptionUIPlugin.ID,"Copying of Apache Axis Web Services jars has been disabled");
			//WebServiceAxisConsumptionUIPlugin.getInstance().getLog().log(status);
			return Status.OK_STATUS;
		}

		IEnvironment env = getEnvironment();
		IStatus status = Status.OK_STATUS;
		ProgressUtils.report(monitor, AxisConsumptionUIMessages.PROGRESS_INFO_COPY_AXIS_CFG);

		if (J2EEUtils.isWebComponent(project)) {
			copyAxisJarsToProject(project, status, env, monitor);
		}
		else {
			// Check if it's a plain old Java project
			if (J2EEUtils.isJavaComponent(project)) {
				status = addAxisJarsToBuildPath(project, env, monitor);
				if (status.getSeverity() == Status.ERROR) {
					env.getStatusHandler().reportError(status);
					return status;
				}
			}
			else {
				status = StatusUtils.errorStatus(AxisConsumptionUIMessages.MSG_WARN_NO_JAVA_NATURE);
				env.getStatusHandler().reportError(status);
				return status;
			}

		}

		return status;

	}

	private void copyAxisJarsToProject(IProject project, IStatus status, IEnvironment env, IProgressMonitor monitor) {

		IPath webModulePath = J2EEUtils.getWebContentPath(project);
		if (webModulePath == null) {
			status = StatusUtils.errorStatus(ConsumptionMessages.MSG_ERROR_PROJECT_NOT_FOUND);
			env.getStatusHandler().reportError(status);
			return;
		}

		deleteObsoleteJars(webModulePath);


		copyIFile(AXIS_RUNTIME_PLUGIN_ID, "lib/" + AXIS_JAR, webModulePath, "WEB-INF/lib/" + AXIS_JAR, status, env, monitor);
		if (status.getSeverity() == Status.ERROR) {
			return;
		}
		copyIFile(COMMON_DISCOVERY_PLUGIN_ID, "lib/" + COMMON_DISCOVERY_JAR, webModulePath, "WEB-INF/lib/" + COMMON_DISCOVERY_JAR, status, env, monitor);
		if (status.getSeverity() == Status.ERROR) {
			return;
		}
		copyIFile(JAVAX_XML_RPC_PLUGIN_ID, "lib/" + JAVAX_XML_RPC_JAR, webModulePath, "WEB-INF/lib/" + JAVAX_XML_RPC_JAR, status, env, monitor);
		if (status.getSeverity() == Status.ERROR) {
			return;
		}
		copyIFile(JAVAX_XML_SOAP_PLUGIN_ID, "lib/" + JAVAX_XML_SOAP_JAR, webModulePath, "WEB-INF/lib/" + JAVAX_XML_SOAP_JAR, status, env, monitor);
		if (status.getSeverity() == Status.ERROR) {
			return;
		}
		copyPluginJar(JAVAX_WSDL_PLUGIN_ID, webModulePath, "WEB-INF/lib/" + JAVAX_WSDL_JAR, status, env, monitor);
		if (status.getSeverity() == Status.ERROR) {
			return;
		}

		copyPluginJar(COMMON_LOGGING_PLUGIN_ID, webModulePath, "WEB-INF/lib/" + COMMON_LOGGING_JAR, status, env, monitor);
		if (status.getSeverity() == Status.ERROR) {
			return;
		}
		return;
	}

	/**
	 * 
	 */
	private void copyIFile(String pluginId, String source, IPath targetPath, String targetFile, IStatus status, IEnvironment env, IProgressMonitor monitor) {
		IPath target = targetPath.append(new Path(targetFile));
		ProgressUtils.report(monitor, ConsumptionMessages.PROGRESS_INFO_COPYING_FILE);

		try {
			ResourceContext context = new TransientResourceContext();
			context.setOverwriteFilesEnabled(true);
			context.setCreateFoldersEnabled(true);
			context.setCheckoutFilesEnabled(true);
			URL sourceURL = BundleUtils.getURLFromBundle(pluginId, source);
			IFile resource = ResourceUtils.getWorkspaceRoot().getFile(target);
			if (!resource.exists()) {
				IFile file = FileResourceUtils.createFile(context, target, sourceURL.openStream(), monitor, env.getStatusHandler());
				if ((projectRestartRequired_.booleanValue() == false) && file.exists()) {
					projectRestartRequired_ = Boolean.TRUE;
				}

			}
		}
		catch (Exception e) {
			status = StatusUtils.errorStatus(AxisConsumptionUIMessages.MSG_ERROR_FILECOPY, e);
			env.getStatusHandler().reportError(status);

		}
	}

	/**
	 * Copy plugins that has been JARed
	 */
	private void copyPluginJar(String pluginId, IPath targetPath, String targetFile, IStatus status, IEnvironment env, IProgressMonitor monitor) {
		IPath target = targetPath.append(new Path(targetFile));
		ProgressUtils.report(monitor, ConsumptionMessages.PROGRESS_INFO_COPYING_FILE);

		try {
			ResourceContext context = new TransientResourceContext();
			context.setOverwriteFilesEnabled(true);
			context.setCreateFoldersEnabled(true);
			context.setCheckoutFilesEnabled(true);

			File jarFile = FileLocator.getBundleFile(Platform.getBundle(pluginId));
			if (jarFile != null && jarFile.isFile()) {
				IFile resource = ResourceUtils.getWorkspaceRoot().getFile(target);

				if (!resource.exists()) {
					InputStream is = new FileInputStream(jarFile);
					IFile file = FileResourceUtils.createFile(context, target, is, monitor, env.getStatusHandler());
					if ((projectRestartRequired_.booleanValue() == false) && file.exists()) {
						projectRestartRequired_ = Boolean.TRUE;
					}

				}
			}
		}
		catch (Exception e) {
			status = StatusUtils.errorStatus(AxisConsumptionUIMessages.MSG_ERROR_FILECOPY, e);
			env.getStatusHandler().reportError(status);

		}
	}

	/*
	 * Check for any obsolete Jars in WEB-INF/lib folder Obsolete jars would
	 * be found in projects migrated from older versions of WTP
	 */
	private void deleteObsoleteJars(IPath webModulePath) {
		// First check for Any jars that have names that are known to be
		// obsolete
		for (int i = 0; i < OBSOLETE_JARS.length; i++) {
			IPath path = webModulePath.append("WEB-INF/lib/" + OBSOLETE_JARS[i]);

			IFile resource = ResourceUtils.getWorkspaceRoot().getFile(path);
			if (resource.exists()) {
				deleteResource(resource);
			}
		}

		// delete older JARs of the same name
		deleteOldJar(webModulePath.append("WEB-INF/lib/" + AXIS_JAR), AXIS_JAR_SIZE);
		deleteOldJar(webModulePath.append("WEB-INF/lib/" + COMMON_DISCOVERY_JAR), COMMON_DISCOVERY_JAR_SIZE);
		deleteOldJar(webModulePath.append("WEB-INF/lib/" + JAVAX_XML_RPC_JAR), JAVAX_XML_RPC_JAR_SIZE);
		deleteOldJar(webModulePath.append("WEB-INF/lib/" + JAVAX_XML_SOAP_JAR), JAVAX_XML_SOAP_JAR_SIZE);
		deleteOldJar(webModulePath.append("WEB-INF/lib/" + JAVAX_WSDL_JAR), JAVAX_WSDL_JAR_SIZE);
		deleteOldJar(webModulePath.append("WEB-INF/lib/" + COMMON_LOGGING_JAR), COMMON_LOGGING_JAR_SIZE);

	}

	private void deleteOldJar(IPath jarPath, long jarSize) {
		IFile resource = ResourceUtils.getWorkspaceRoot().getFile(jarPath);
		if (resource.exists()) {
			// calculate the size of the resource by getting the java.io.File
			long fileSize = resource.getLocation().toFile().length();
			if (fileSize != jarSize) {
				deleteResource(resource);
			}
		}
	}

	private void deleteResource(IFile resource) { // delete the resource
		try {
			// System.out.println("Obsolete Jar!! " + resource.getName());
			resource.delete(true, null);
		}
		catch (Exception e) { // e.printStackTrace();
		}
	}


	/**
	 * Addes Axis JARs to the build path of Java project
	 * 
	 * @param env
	 * @param monitor
	 * @return
	 */
	public IStatus addAxisJarsToBuildPath(IProject project, IEnvironment env, IProgressMonitor monitor) {

		IStatus status;

		try {
			getJavaProjectClasspath(env, monitor);

			addNewJarEntry(PATH_TO_JARS_IN_PLUGIN + AXIS_JAR, getTheJarPath(AXIS_RUNTIME_PLUGIN_ID, PATH_TO_JARS_IN_PLUGIN + AXIS_JAR));
			addNewJarEntry(PATH_TO_JARS_IN_PLUGIN + COMMON_DISCOVERY_JAR, getTheJarPath(COMMON_DISCOVERY_PLUGIN_ID, PATH_TO_JARS_IN_PLUGIN + COMMON_DISCOVERY_JAR));
			addNewJarEntry(PATH_TO_JARS_IN_PLUGIN + JAVAX_XML_RPC_JAR, getTheJarPath(JAVAX_XML_RPC_PLUGIN_ID, PATH_TO_JARS_IN_PLUGIN + JAVAX_XML_RPC_JAR));
			addNewJarEntry(PATH_TO_JARS_IN_PLUGIN + JAVAX_XML_SOAP_JAR, getTheJarPath(JAVAX_XML_SOAP_PLUGIN_ID, PATH_TO_JARS_IN_PLUGIN + JAVAX_XML_SOAP_JAR));

			IPath javaxWsdlJarPath = BundleUtils.getJarredPluginPath(JAVAX_WSDL_PLUGIN_ID);
			if (javaxWsdlJarPath != null) {
				addNewJarEntry(javaxWsdlJarPath.toString(), javaxWsdlJarPath);
			}
			
			IPath commonLoggingJarPath = BundleUtils.getJarredPluginPath(COMMON_LOGGING_PLUGIN_ID);
			if (commonLoggingJarPath != null) {
				addNewJarEntry(commonLoggingJarPath.toString(), commonLoggingJarPath);
			}
			updateClasspath(monitor);
		}
		catch (Exception e) {
			status = StatusUtils.errorStatus(AxisConsumptionUIMessages.MSG_ERROR_BAD_BUILDPATH, e);
			return status;
		}

		return Status.OK_STATUS;
	}

	/**
	 * @param env
	 * @param monitor
	 * @return The Java project classpath
	 * @throws JavaModelException
	 */
	private IStatus getJavaProjectClasspath(IEnvironment env, IProgressMonitor monitor) throws JavaModelException {

		IStatus status = Status.OK_STATUS;

		IJavaProject javaProject_ = null;
		oldClasspath = null;
		javaProject_ = JavaCore.create(project);

		oldClasspath = javaProject_.getRawClasspath();

		return status;
	}

	/**
	 * Store new JAR name in newJarNamesList if it's not already on build path
	 * 
	 * @param jarName
	 *            name of the JAR
	 * @param jarPath
	 *            Absolute path to the JAR
	 */
	private void addNewJarEntry(String jarName, IPath jarPath) {

		boolean found = false;
		for (int i = 0; i < oldClasspath.length; i++) {
			found = oldClasspath[i].getPath().toString().toLowerCase().endsWith(jarName.toLowerCase());
			if (found) {
				break;
			}
		}

		if (!found) {
			newJarNamesList.add(new JarEntry(jarName, jarPath));
		}

	}

	/**
	 * Update the Java project classpath adding classpath from newJarNamesList
	 * to oldClasspath
	 * 
	 * @param monitor
	 * @return
	 * @throws JavaModelException
	 */
	private IStatus updateClasspath(IProgressMonitor monitor) throws JavaModelException {

		IStatus status = Status.OK_STATUS;

		if (newJarNamesList.size() > 0) {
			JarEntry[] newJarEntries = (JarEntry[]) newJarNamesList.toArray(new JarEntry[]{});

			IClasspathEntry[] newClasspath = new IClasspathEntry[oldClasspath.length + newJarEntries.length];
			int i = 0;
			// Add oldClasspath entries
			while (i < oldClasspath.length) {
				newClasspath[i] = oldClasspath[i];
				i++;
			}

			int m = 0;
			while (i < newClasspath.length) {
				newClasspath[i] = JavaCore.newLibraryEntry(newJarEntries[m].getJarPath(), null, null);
				m++;
				i++;
			}

			//
			// Then update the project classpath.
			//

			IJavaProject javaProject = JavaCore.create(project);
			javaProject.setRawClasspath(newClasspath, monitor);

		}

		return status;

	}

	//
	// Returns the local native pathname of the jar.
	//
	private IPath getTheJarPath(String pluginId, String theJar) throws MalformedURLException, IOException {
		if (pluginId != null) {
			URL localURL = Platform.asLocalURL(BundleUtils.getURLFromBundle(pluginId, theJar));
			return new Path(localURL.getFile());
		}
		else {
			return new Path(theJar);
		}

	}

	public void setProject(IProject project) {
		this.project = project;
	}

	public boolean getProjectRestartRequired() {
		return projectRestartRequired_.booleanValue();
	}

	public class JarEntry {
		private String jarName;
		private IPath jarPath;

		public JarEntry(String name, IPath path) {
			jarName = name;
			jarPath = path;
		}

		public String getJarName() {
			return jarName;
		}

		public IPath getJarPath() {
			return jarPath;
		}

	}
}
