/*******************************************************************************
 * Copyright (c) 2003, 2004, 2005 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
 *******************************************************************************/
package org.eclipse.wst.common.componentcore.internal.builder;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;

import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
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.NullProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Status;
import org.eclipse.emf.common.util.URI;
import org.eclipse.jem.util.logger.proxy.Logger;
import org.eclipse.wst.common.componentcore.UnresolveableURIException;
import org.eclipse.wst.common.componentcore.datamodel.properties.IReferencedComponentBuilderDataModelProperties;
import org.eclipse.wst.common.componentcore.internal.StructureEdit;
import org.eclipse.wst.common.componentcore.internal.impl.ModuleURIUtil;
import org.eclipse.wst.common.componentcore.internal.util.IModuleConstants;
import org.eclipse.wst.common.componentcore.internal.util.ZipFileExporter;
import org.eclipse.wst.common.componentcore.resources.IVirtualComponent;
import org.eclipse.wst.common.componentcore.resources.IVirtualReference;
import org.eclipse.wst.common.frameworks.datamodel.AbstractDataModelOperation;
import org.eclipse.wst.common.frameworks.datamodel.IDataModel;
import org.eclipse.wst.common.internal.emfworkbench.integration.EMFWorkbenchEditPlugin;


public class ReferencedComponentBuilderOperation extends AbstractDataModelOperation implements IReferencedComponentBuilderDataModelProperties {
	private static String ERROR_EXPORTING_MSG = "Zip Error Message"; //$NON-NLS-1$

	private ZipFileExporter exporter = null;

	private List errorTable = new ArrayList(1); // IStatus

	private boolean useCompression = true;

	// private boolean createLeadupStructure = false;
	private boolean generateManifestFile = false;

	private IProgressMonitor monitor;

	private int inputContainerSegmentCount;

	/**
	 * @param model
	 */
	public ReferencedComponentBuilderOperation(IDataModel model) {
		super(model);

	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.core.commands.operations.IUndoableOperation#execute(org.eclipse.core.runtime.IProgressMonitor,
	 *      org.eclipse.core.runtime.IAdaptable)
	 */
	public IStatus execute(IProgressMonitor monitor, IAdaptable info) {
		try {
			this.monitor = monitor;
			IVirtualReference vReference = (IVirtualReference) model.getProperty(VIRTUAL_REFERENCE);
			IVirtualComponent enclosingComponent = vReference.getEnclosingComponent();

			IPath absoluteOutputContainer = getAbsoluteOutputContainer(vReference);
			if (absoluteOutputContainer == null) // Project not accessible
				return OK_STATUS;
			// create output container folder if it does not exist
			IFolder outputContainerFolder = createFolder(absoluteOutputContainer);

			IVirtualComponent referencedComponent = vReference.getReferencedComponent();
			IPath absoluteInputContainer = getAbsoluteInputContainer(referencedComponent);

			if (absoluteOutputContainer == null) {
				return OK_STATUS;
			} else if (absoluteInputContainer == null || !referencedComponent.getProject().getFolder(absoluteInputContainer).exists()) {
				if (vReference.getReferencedComponent().isBinary()) {
					try {
						String fileString = ModuleURIUtil.getArchiveName(URI.createURI(referencedComponent.getComponentHandle().toString()));
						IPath path = new Path(fileString);
						String osPath = path.toOSString();
						if (vReference.getDependencyType() == IVirtualReference.DEPENDENCY_TYPE_CONSUMES) {
							expandZipFile(osPath, outputContainerFolder);
						} else {
							copyFile(osPath, outputContainerFolder);
						}
						return OK_STATUS;
					} catch (UnresolveableURIException e) {
						Logger.getLogger().logError(e);
					}
				}
			}

			if (vReference.getDependencyType() == IVirtualReference.DEPENDENCY_TYPE_CONSUMES) {
				// if consumes simply copy resources to output directory
				IResource sourceResource = getResource(absoluteInputContainer);
				if (sourceResource == null)
					return OK_STATUS;
				ComponentStructuralBuilder.smartCopy(sourceResource, absoluteOutputContainer, new NullProgressMonitor());
			} else {
				String zipName = getZipFileName(referencedComponent);
				IPath zipNameDestination = absoluteOutputContainer.append(zipName);
				IResource dependentZip = getResource(zipNameDestination);
				// TODO: this is needed to stop the copying of large dependent module. Incremental
				// build in M4 should allow for this
				// code to be removed.
				if (dependentZip == null || dependentZip.exists())
					return OK_STATUS;
				zipAndCopyResource(getResource(absoluteInputContainer), dependentZip);
				getResource(absoluteOutputContainer).refreshLocal(IResource.DEPTH_INFINITE, monitor);
			}

		} catch (CoreException ex) {
			Logger.getLogger().log(ex.getMessage());
		}
		return OK_STATUS;
	}

	private void copyFile(String osPath, IFolder outputContainerFolder) {
		File diskFile = new File(osPath);
		FileInputStream inputStream = null;
		try {
			IFile iFile = outputContainerFolder.getFile(new Path(diskFile.getName()));
			if (!iFile.exists()) {
				inputStream = new FileInputStream(diskFile);
				createFolder(iFile.getParent().getFullPath());
				iFile.create(inputStream, true, null);
			}
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (CoreException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			if (null != inputStream) {
				try {
					inputStream.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
	}

	private void expandZipFile(String filePath, IFolder absoluteOutputContainer) {
		ZipFile zipFile;
		try {
			zipFile = new ZipFile(filePath);
			Enumeration entries = zipFile.entries();
			ZipEntry entry = null;
			InputStream inputStream = null;
			IFile file = null;
			while (entries.hasMoreElements()) {
				entry = (ZipEntry) entries.nextElement();
				entry.getName();
				try {
					file = absoluteOutputContainer.getFile(new Path(entry.getName()));
					if (!file.exists()) {
						inputStream = zipFile.getInputStream(entry);
						createFolder(file.getParent().getFullPath());
						file.create(inputStream, true, null);
					}
				} catch (CoreException e) {
					Logger.getLogger().logError(e);
				} finally {
					if (null != inputStream) {
						inputStream.close();
						inputStream = null;
					}
				}
			}
		} catch (IOException e) {
			Logger.getLogger().logError(e);
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.core.commands.operations.IUndoableOperation#redo(org.eclipse.core.runtime.IProgressMonitor,
	 *      org.eclipse.core.runtime.IAdaptable)
	 */
	public IStatus redo(IProgressMonitor monitor, IAdaptable info) {
		// TODO Auto-generated method stub
		return null;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.core.commands.operations.IUndoableOperation#undo(org.eclipse.core.runtime.IProgressMonitor,
	 *      org.eclipse.core.runtime.IAdaptable)
	 */
	public IStatus undo(IProgressMonitor monitor, IAdaptable info) {
		// TODO Auto-generated method stub
		return null;
	}

	/**
	 * @param inputResource
	 * @param zipName
	 * @return
	 */
	private void zipAndCopyResource(IResource inputResource, IResource outputResource) {
		try {
			String osPath = outputResource.getLocation().toOSString();
			exporter = new ZipFileExporter(osPath, true);
			inputContainerSegmentCount = inputResource.getFullPath().segmentCount();
			exportResource(inputResource);
			exporter.finished();
		} catch (IOException ioEx) {
			ioEx.printStackTrace();
		} catch (InterruptedException iEx) {
			iEx.printStackTrace();
		}
	}

	/**
	 * @return an IPath or null if not accessable
	 */
	private IPath getAbsoluteOutputContainer(IVirtualReference vReference) {
		IVirtualComponent vComponent = vReference.getEnclosingComponent();
		IFolder localWorkbenchModuleOuptutContainer = null;
		localWorkbenchModuleOuptutContainer = StructureEdit.getOutputContainerRoot(vComponent);
		if (localWorkbenchModuleOuptutContainer == null) // Project not found or is not
			// accessible
			return null;

		IPath localWorkbenchModuleOuptutContainerPath = localWorkbenchModuleOuptutContainer.getFullPath();
		return localWorkbenchModuleOuptutContainerPath.append(vReference.getRuntimePath().toString());
	}

	/**
	 * @return
	 */
	private IPath getAbsoluteInputContainer(IVirtualComponent virtualComponent) {
		return StructureEdit.getOutputContainerRoot(virtualComponent).getFullPath();
	}

	private String getZipFileName(IVirtualComponent vComponent) {
		String typeID = vComponent.getComponentTypeId();
		String zipFileName = vComponent.getName();
		zipFileName = zipFileName.replace('.', '_');
		if (typeID == null)
			return zipFileName;
		if (typeID.equals(IModuleConstants.JST_APPCLIENT_MODULE) || typeID.equals(IModuleConstants.JST_EJB_MODULE) || typeID.equals(IModuleConstants.JST_UTILITY_MODULE))
			return zipFileName + ".jar";
		else if (typeID.equals(IModuleConstants.JST_WEB_MODULE))
			return zipFileName + ".war";
		else if (typeID.equals(IModuleConstants.JST_CONNECTOR_MODULE))
			return zipFileName + ".rar";
		else if (typeID.equals(IModuleConstants.JST_EAR_MODULE))
			return zipFileName + ".ear";
		return zipFileName;
	}

	/**
	 * Get resource for given absolute path
	 * 
	 * @exception com.ibm.itp.core.api.resources.CoreException
	 */
	private IResource getResource(IPath absolutePath) throws CoreException {
		IResource resource = null;
		if (absolutePath != null && !absolutePath.isEmpty()) {
			resource = ResourcesPlugin.getWorkspace().getRoot().getFolder(absolutePath);
			if (resource == null || !(resource instanceof IFolder)) {
				resource = ResourcesPlugin.getWorkspace().getRoot().getFile(absolutePath);
			}
		}
		return resource;
	}

	/**
	 * Create a folder for given absolute path
	 * 
	 * @exception com.ibm.itp.core.api.resources.CoreException
	 */
	public IFolder createFolder(IPath absolutePath) throws CoreException {
		if (absolutePath == null || absolutePath.isEmpty())
			return null;
		IFolder folder = ResourcesPlugin.getWorkspace().getRoot().getFolder(absolutePath);
		// check if the parent is there
		IContainer parent = folder.getParent();
		if (parent != null && !parent.exists() && (parent instanceof IFolder))
			createFolder(parent.getFullPath());
		if (!folder.exists())
			folder.create(true, true, new NullProgressMonitor());
		return folder;
	}

	/**
	 * Export the passed resource to the destination .zip
	 * 
	 * @param resource
	 *            org.eclipse.core.resources.IResource
	 * @param depth -
	 *            the number of resource levels to be included in the path including the resourse
	 *            itself.
	 */
	protected boolean exportResource(IResource resource) throws InterruptedException {
		if (!resource.isAccessible())
			return false;

		if (resource.getType() == IResource.FILE) {
			return writeResource(resource);
		} else {
			IResource[] children = null;

			try {
				children = ((IContainer) resource).members();
			} catch (CoreException e) {
				// this should never happen because an #isAccessible check is
				// done before #members is invoked
				addError(format(ERROR_EXPORTING_MSG, new Object[]{resource.getFullPath()}), e); //$NON-NLS-1$
			}

			boolean writeFolder = true;
			for (int i = 0; i < children.length; i++) {
				writeFolder = !exportResource(children[i]) && writeFolder;
			}
			if (writeFolder) {
				writeResource(resource);
			}
			return true;

		}
	}

	private boolean writeResource(IResource resource) throws InterruptedException {
		// if (resource.isDerived())
		// return false;
		String destinationName;
		IPath fullPath = resource.getFullPath();
		destinationName = fullPath.removeFirstSegments(inputContainerSegmentCount).toString();
		monitor.subTask(destinationName);

		try {
			if (resource.getType() == IResource.FILE)
				exporter.write((IFile) resource, destinationName);
			else
				exporter.writeFolder(destinationName);
		} catch (IOException e) {
			addError(format(ERROR_EXPORTING_MSG, //$NON-NLS-1$
						new Object[]{resource.getFullPath().makeRelative(), e.getMessage()}), e);
			return false;
		} catch (CoreException e) {
			addError(format(ERROR_EXPORTING_MSG, //$NON-NLS-1$
						new Object[]{resource.getFullPath().makeRelative(), e.getMessage()}), e);
			return false;
		}

		monitor.worked(1);
		return true;
	}

	/**
	 * @param ERROR_EXPORTING_MSG
	 * @param objects
	 * @return
	 */
	private String format(String pattern, Object[] arguments) {
		return MessageFormat.format(pattern, arguments);
	}

	/**
	 * Add a new entry to the error table with the passed information
	 */
	protected void addError(String message, Throwable e) {
		errorTable.add(new Status(IStatus.ERROR, EMFWorkbenchEditPlugin.ID, 0, message, e));
	}
}
