/*******************************************************************************
 * Copyright (c) 2003, 2008 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
 *******************************************************************************/
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.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.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) {

		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);

			IPath jarPath = BundleUtils.getJarredPluginPath(pluginId);
			if (jarPath != null) {
				IFile resource = ResourceUtils.getWorkspaceRoot().getFile(target);

				if (!resource.exists()) {
					InputStream is = new FileInputStream(new File(jarPath.toString()));
					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;
		}

	}
}
