/*******************************************************************************
 * Copyright (c) 2006, 2010 Soyatec (http://www.soyatec.com) 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:
 * Soyatec - initial API and implementation
 * Sopot Cela - ongoing enhancements
 *******************************************************************************/
package org.eclipse.e4.internal.tools.wizards.project;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.lang.reflect.InvocationTargetException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.zip.ZipEntry;
import java.util.zip.ZipException;
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.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.e4.internal.tools.ToolsPlugin;
import org.eclipse.pde.internal.ui.PDEUIMessages;
import org.eclipse.pde.ui.templates.IVariableProvider;
import org.eclipse.ui.actions.WorkspaceModifyOperation;

public class TemplateOperation extends WorkspaceModifyOperation implements
IVariableProvider {

	private final URL templateDirectory;
	private final IContainer target;
	private final Map<String, String> keys;
	private final Set<String> binaryExtentions;
	private final boolean isMinimalist;

	public TemplateOperation(URL source, IContainer target,
		Map<String, String> keys, Set<String> binaryExtentions, boolean justProduct) {
		templateDirectory = source;
		this.binaryExtentions = binaryExtentions;
		this.target = target;
		this.keys = keys;
		isMinimalist = justProduct;
	}

	@Override
	protected void execute(IProgressMonitor monitor) throws CoreException,
	InvocationTargetException, InterruptedException {
		monitor.setTaskName(PDEUIMessages.AbstractTemplateSection_generating);

		if ("jar".equals(templateDirectory.getProtocol())) { //$NON-NLS-1$
			final String file = templateDirectory.getFile();
			final int exclamation = file.indexOf('!');
			if (exclamation < 0) {
				return;
			}
			URL fileUrl = null;
			try {
				fileUrl = new URL(file.substring(0, exclamation));
			} catch (final MalformedURLException mue) {
				ToolsPlugin.logError(mue);
				return;
			}
			final File pluginJar = new File(fileUrl.getFile());
			if (!pluginJar.exists()) {
				return;
			}
			final String templateDirectory = file.substring(exclamation + 1); // "/some/path/"
			final IPath path = new Path(templateDirectory);
			ZipFile zipFile = null;
			try {
				zipFile = new ZipFile(pluginJar);
				generateFiles(zipFile, path, target, monitor);
			} catch (final ZipException ze) {
			} catch (final IOException ioe) {
			} finally {
				if (zipFile != null) {
					try {
						zipFile.close();
					} catch (final IOException e) {
					}
				}
			}
		} else if ("file".equals(templateDirectory.getProtocol())) { //$NON-NLS-1$
			final File directory = new File(templateDirectory.getFile());
			if (!directory.exists()) {
				return;
			}
			generateFiles(directory, target, true, monitor);
		}
	}

	private void generateFiles(File src, IContainer dst, boolean firstLevel,
		IProgressMonitor monitor) throws CoreException {
		if (!firstLevel && isMinimalist) {
			return;
		}
		final File[] members = src.listFiles();

		for (int i = 0; i < members.length; i++) {
			final File member = members[i];
			final String name = member.getName();
			if (member.isDirectory()) {
				if (".svn".equals(name) || "cvs".equalsIgnoreCase(name)) { //$NON-NLS-1$ //$NON-NLS-2$
					continue;
				}
				IContainer dstContainer = null;

				if (dstContainer == null) {
					final String folderName = getProcessedString(name, name);
					dstContainer = dst.getFolder(new Path(folderName));
				}
				if (dstContainer != null && !dstContainer.exists()) {
					((IFolder) dstContainer).create(true, true, monitor);
				}

				generateFiles(member, dstContainer, false, monitor);
			} else {
				InputStream in = null;
				try {
					in = new FileInputStream(member);
					copyFile(name, in, dst, monitor);
				} catch (final IOException ioe) {
				} finally {
					if (in != null) {
						try {
							in.close();
						} catch (final IOException ioe2) {
						}
					}
				}
			}
		}
	}

	/**
	 *
	 *
	 * @param zipFile
	 * @param path
	 * @param dst
	 * @param monitor
	 * @throws CoreException
	 */
	private void generateFiles(ZipFile zipFile, IPath path, IContainer dst,
		IProgressMonitor monitor) throws CoreException {
		final int pathLength = path.segmentCount();
		// Immidiate children
		final Map childZipEntries = new HashMap(); // "dir/" or "dir/file.java"

		for (final Enumeration zipEntries = zipFile.entries(); zipEntries
			.hasMoreElements();) {
			final ZipEntry zipEntry = (ZipEntry) zipEntries.nextElement();
			final IPath entryPath = new Path(zipEntry.getName());
			if (entryPath.segmentCount() <= pathLength) {
				// ancestor or current directory
				continue;
			}
			if (!path.isPrefixOf(entryPath)) {
				// not a descendant
				continue;
			}
			if (entryPath.segmentCount() == pathLength + 1) {
				childZipEntries.put(zipEntry.getName(), zipEntry);
			} else {
				final String name = entryPath.uptoSegment(pathLength + 1)
					.addTrailingSeparator().toString();
				if (!childZipEntries.containsKey(name)) {
					final ZipEntry dirEntry = new ZipEntry(name);
					childZipEntries.put(name, dirEntry);
				}
			}
		}

		for (final Iterator it = childZipEntries.values().iterator(); it.hasNext();) {
			final ZipEntry zipEnry = (ZipEntry) it.next();
			final String name = new Path(zipEnry.getName()).lastSegment().toString();
			if (zipEnry.isDirectory()) {
				IContainer dstContainer = null;

				if (dstContainer == null) {
					final String folderName = getProcessedString(name, name);
					dstContainer = dst.getFolder(new Path(folderName));
				}
				if (dstContainer != null && !dstContainer.exists()) {
					((IFolder) dstContainer).create(true, true, monitor);
				}
				generateFiles(zipFile, path.append(name), dstContainer, monitor);
			} else {
				InputStream in = null;
				try {
					in = zipFile.getInputStream(zipEnry);
					copyFile(name, in, dst, monitor);
				} catch (final IOException ioe) {
				} finally {
					if (in != null) {
						try {
							in.close();
						} catch (final IOException ioe2) {
						}
					}
				}
			}
		}
	}

	private void copyFile(String fileName, InputStream input, IContainer dst,
		IProgressMonitor monitor) throws CoreException {
		final String targetFileName = getProcessedString(fileName, fileName);

		monitor.subTask(targetFileName);
		final IFile dstFile = dst.getFile(new Path(targetFileName));

		try {
			final InputStream stream = isBinary(fileName) ? input
				: getProcessedStream(fileName, input);
			if (dstFile.exists()) {
				dstFile.setContents(stream, true, true, monitor);
			} else {
				dstFile.create(stream, true, monitor);
			}
			stream.close();

		} catch (final IOException e) {
		}
	}

	protected void copyFile(String fileName, InputStream input, IContainer dst,
		final String destPath, IProgressMonitor monitor)
			throws CoreException {
		String targetFileName = null;
		if (destPath == null) {
			targetFileName = getProcessedString(fileName, fileName);
		} else {
			targetFileName = destPath;
		}

		monitor.subTask(targetFileName);
		final IFile dstFile = dst.getFile(new Path(targetFileName));

		try {
			final InputStream stream = isBinary(fileName) ? input
				: getProcessedStream(fileName, input);
			if (dstFile.exists()) {
				dstFile.setContents(stream, true, true, monitor);
			} else {
				dstFile.create(stream, true, monitor);
			}
			stream.close();

		} catch (final IOException e) {
		}
	}

	/**
	 *
	 * @param fileName
	 * @param input
	 * @param dst
	 * @param basePath
	 * @param monitor
	 * @throws CoreException
	 */
	public void copyFile(String fileName, InputStream input, IContainer dst,
		final String basePath, final String destName,
		IProgressMonitor monitor) throws CoreException {
		if (basePath == null || basePath.equals("")) { //$NON-NLS-1$
			copyFile(fileName, input, dst, monitor);
		}

		final String targetFileName = destName == null ? getProcessedString(fileName,
			fileName) : destName;

		monitor.subTask(targetFileName);
		final IFile dstFile = dst.getFile(new Path(basePath + targetFileName));

		try {
			final InputStream stream = isBinary(fileName) ? input
				: getProcessedStream(fileName, input);
			if (dstFile.exists()) {
				dstFile.setContents(stream, true, true, monitor);
			} else {
				dstFile.create(stream, true, monitor);
			}
			stream.close();

		} catch (final IOException e) {
		}
	}

	private boolean isBinary(String fileName) {
		if (binaryExtentions == null) {
			return false;
		}

		final String ext = getfileExtention(fileName);
		if (ext == null) {
			return false;
		}
		return binaryExtentions.contains(ext);
	}

	private String getfileExtention(String name) {
		final int indexOf = name.lastIndexOf('.');
		if (indexOf == -1) {
			return null;
		}
		return name.substring(indexOf);
	}

	private InputStream getProcessedStream(String fileName, InputStream stream)
		throws IOException, CoreException {
		final InputStreamReader reader = new InputStreamReader(stream);
		final int bufsize = 1024;
		final char[] cbuffer = new char[bufsize];
		int read = 0;
		final StringBuffer keyBuffer = new StringBuffer();
		final StringBuffer outBuffer = new StringBuffer();

		boolean replacementMode = false;
		boolean almostReplacementMode = false;
		boolean escape = false;
		while (read != -1) {
			read = reader.read(cbuffer);
			for (int i = 0; i < read; i++) {
				final char c = cbuffer[i];

				if (escape) {
					final StringBuffer buf = outBuffer;
					buf.append(c);
					escape = false;
					continue;
				}

				if (c == '@') {
					if (replacementMode && almostReplacementMode) {
						almostReplacementMode = false;
					} else if (replacementMode) {
						replacementMode = false;
						final String key = keyBuffer.toString();
						final String value = key.length() == 0 ? "@@" //$NON-NLS-1$
							: getReplacementString(key);
						outBuffer.append(value);
						keyBuffer.delete(0, keyBuffer.length());
					} else if (almostReplacementMode) {
						replacementMode = true;
					} else {
						almostReplacementMode = true;
					}
				} else {
					if (replacementMode) {
						keyBuffer.append(c);
					} else {
						if (almostReplacementMode) {
							outBuffer.append('@');
						}
						outBuffer.append(c);
						almostReplacementMode = false;
					}
				}
			}
		}
		return new ByteArrayInputStream(outBuffer.toString().getBytes());
		// return new
		// ByteArrayInputStream(outBuffer.toString().getBytes(project.
		// getDefaultCharset()));
	}

	private String getProcessedString(String fileName, String source) {
		if (source.indexOf('$') == -1) {
			return source;
		}
		int loc = -1;
		final StringBuffer buffer = new StringBuffer();
		boolean replacementMode = false;
		for (int i = 0; i < source.length(); i++) {
			final char c = source.charAt(i);
			if (c == '$') {
				if (replacementMode) {
					final String key = source.substring(loc, i);
					final String value = key.length() == 0 ? "$" : getReplacementString(key); //$NON-NLS-1$
					buffer.append(value);
					replacementMode = false;
				} else {
					replacementMode = true;
					loc = i + 1;
					continue;
				}
			} else if (!replacementMode) {
				buffer.append(c);
			}
		}
		return buffer.toString();
	}

	public String getReplacementString(String key) {
		final String result = keys.get(key);
		return result != null ? result : key;
	}

	@Override
	public Object getValue(String variable) {
		return getReplacementString(variable);
	}

}
