//------------------------------------------------------------------------------
// Copyright (c) 2005, 2006 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 implementation
//------------------------------------------------------------------------------
package org.eclipse.epf.library.util;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EAttribute;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.epf.common.utils.FileUtil;
import org.eclipse.epf.common.utils.NetUtil;
import org.eclipse.epf.library.ILibraryManager;
import org.eclipse.epf.library.LibraryPlugin;
import org.eclipse.epf.library.LibraryResources;
import org.eclipse.epf.library.LibraryService;
import org.eclipse.epf.library.edit.command.MethodElementAddCommand.BasicResourceManager;
import org.eclipse.epf.library.edit.util.TngUtil;
import org.eclipse.epf.uma.ContentDescription;
import org.eclipse.epf.uma.DescribableElement;
import org.eclipse.epf.uma.GuidanceDescription;
import org.eclipse.epf.uma.MethodElement;
import org.eclipse.epf.uma.MethodPlugin;
import org.eclipse.epf.uma.util.UmaUtil;
import org.eclipse.osgi.util.NLS;

/**
 * utility class to copy attachmeents to another location
 * @author Jeff Hardy
 * @sicne 1.0
 *
 */
public class CopyAttachmentsToNewLocation extends BasicResourceManager {

	private Collection modifiedResourceSet;

	private boolean debug;

	private Map elementToOldPluginMap;

	private MethodPlugin lastOldPlugin = null;

	public CopyAttachmentsToNewLocation() {
		debug = LibraryPlugin.getDefault().isDebugging();
	}

	/**
	 * Copy attachments within a library, from one plugin to another
	 */
	public Collection copyReferencedContents(Collection elements,
			Map elementToOldPluginMap) {
		lastOldPlugin = null;
		modifiedResourceSet = new HashSet();
		if (elementToOldPluginMap == null) {
			return modifiedResourceSet;
		}
		this.elementToOldPluginMap = elementToOldPluginMap;

		Iterator iter = elements.iterator();
		while (iter.hasNext()) {
			Object o = iter.next();
			if (o instanceof Resource) {
				Resource r = (Resource) o;
				Iterator resourceIter = r.getContents().iterator();
				while (resourceIter.hasNext()) {
					EObject e = (EObject) resourceIter.next();
					HandleAttachmentsPlugin(e);
				}
			} else if (o instanceof EObject) {
				EObject e = (EObject) o;
				HandleAttachmentsPlugin(e);
			}
		}
		return modifiedResourceSet;
	}

	private void HandleAttachmentsPlugin(EObject e) {
		// handle self
		MethodElement elementToProcess = null;
		// find the old plugin, if there is one
		if (elementToOldPluginMap != null
				&& (MethodPlugin) elementToOldPluginMap.get(e) != null) {
			lastOldPlugin = (MethodPlugin) elementToOldPluginMap.get(e);
		}

		if (lastOldPlugin != null) {
			if (e instanceof DescribableElement) {
				DescribableElement de = (DescribableElement) e;

				// Custom icons
				try {
					File libDirFile = new File(LibraryService.getInstance()
							.getCurrentMethodLibraryPath());
					// shape icon
					java.net.URI shapeIconUri = de.getShapeicon();
					if (shapeIconUri != null) {
						java.net.URI srcShapeUri = TngUtil.getFullPathURI(de,
								shapeIconUri);
						File srcFile = new File(srcShapeUri);
						File tgtFile = new File(srcFile.getAbsolutePath()
								.replaceFirst(
										"\\" + File.separator //$NON-NLS-1$
												+ lastOldPlugin.getName()
												+ "\\" + File.separator, //$NON-NLS-1$
										"\\" //$NON-NLS-1$
												+ File.separator
												+ UmaUtil.getMethodPlugin(de)
														.getName() + "\\" //$NON-NLS-1$
												+ File.separator));
						if (!tgtFile.exists()) {
							FileUtil.copyfile(srcFile, tgtFile);
						}
						java.net.URI newShapeIconUri = new java.net.URI(NetUtil
								.encodeFileURL(FileUtil.getRelativePath(
										tgtFile, libDirFile)));
						de.setShapeicon(newShapeIconUri);
						modifiedResourceSet.add(de.eResource());
					}

					// node icon
					java.net.URI nodeIconUri = de.getNodeicon();
					if (nodeIconUri != null) {
						java.net.URI srcNodeUri = TngUtil.getFullPathURI(de,
								nodeIconUri);
						File srcFile = new File(srcNodeUri);
						File tgtFile = new File(srcFile.getAbsolutePath()
								.replaceFirst(
										"\\" + File.separator //$NON-NLS-1$
												+ lastOldPlugin.getName()
												+ "\\" + File.separator, //$NON-NLS-1$
										"\\" //$NON-NLS-1$
												+ File.separator
												+ UmaUtil.getMethodPlugin(de)
														.getName() + "\\" //$NON-NLS-1$
												+ File.separator));
						if (!tgtFile.exists()) {
							FileUtil.copyfile(srcFile, tgtFile);
						}
						java.net.URI newNodeIconUri = new java.net.URI(NetUtil
								.encodeFileURL(FileUtil.getRelativePath(
										tgtFile, libDirFile)));
						de.setNodeicon(newNodeIconUri);
						modifiedResourceSet.add(de.eResource());
					}
				} catch (Exception ex) {
					LibraryPlugin.getDefault().getLogger().logError(ex);
				}
				HandleAttachmentsPlugin(de.getPresentation());
				return;
			} else if (e instanceof ContentDescription) {
				elementToProcess = (ContentDescription) e;
			} else if (e instanceof MethodElement) {
				elementToProcess = (MethodElement) e;
			} else {
				if (debug) {
					System.out
							.println("CopyAttachmentsToNewLocation.HandleAttachmentsPlugin: unknown type " + e); //$NON-NLS-1$
				}
			}

			if (elementToProcess != null
					&& elementToProcess.eResource() != null) {
				// set up ContentResourceScanner for this element
				// give ContentResourceScanner same directory for sourceRootPath
				// and targetRootPath
				ILibraryManager manager = (ILibraryManager) LibraryService
						.getInstance().getCurrentLibraryManager();
				
				URI elementURI = manager != null ? manager.getElementRelativeURI(elementToProcess) : null;
				if (elementURI == null || elementURI.segmentCount() < 1)
					return;
				String targetPluginDir = LibraryService.getInstance()
						.getCurrentMethodLibraryPath()
						+ File.separator
						+ NetUtil.decodedFileUrl(elementURI.segment(0));
				ContentResourceScanner scanner = new ContentResourceScanner(
						new File(targetPluginDir));
				scanner.setTargetRootPath(new File(targetPluginDir));

				// iterate thru element's content

				String contentPath = ResourceHelper
						.getElementPath((MethodElement) elementToProcess);
				if (contentPath.length() == 0) {
					LibraryPlugin
							.getDefault()
							.getLogger()
							.logWarning(
									NLS.bind(LibraryResources.CopyAttachmentsToNewLocation_log_noContentPath, (new Object[] { ((MethodElement) elementToProcess).getName() }))); 
					return;
				}

				String oldContentPath = contentPath.replaceFirst(UmaUtil
						.getMethodPlugin(elementToProcess).getName(),
						lastOldPlugin.getName());
				Iterator iter = elementToProcess.eClass().getEAllAttributes()
						.iterator();
				while (iter.hasNext()) {
					EAttribute attrib = (EAttribute) iter.next();
					Object o = elementToProcess.eGet(attrib);
					if (o instanceof String) {
						String content = (String) o;
						if (content.length() > 0) {
							String newContent = scanner.resolveResourcesPlugin(
									content, contentPath, oldContentPath);
							if (newContent != null
									&& newContent.trim().length() != 0
									&& !content.equals(newContent)) {
								elementToProcess.eSet(attrib, newContent);
								modifiedResourceSet.add(elementToProcess
										.eResource());
							}
						}
					}
				}

				// Template attachments
				if (elementToProcess instanceof GuidanceDescription) {
					String attachmentString = ((GuidanceDescription) elementToProcess)
							.getAttachments();
					List attachmentList = TngUtil
							.convertGuidanceAttachmentsToList(attachmentString);
					for (iter = attachmentList.iterator(); iter.hasNext();) {
						String attachment = (String) iter.next();
						if (attachment != null
								&& attachment.trim().length() > 0) {
							try {
								File srcContentPath = new File(LibraryService
										.getInstance()
										.getCurrentMethodLibraryPath(),
										oldContentPath);
								File srcFile = new File(srcContentPath,
										attachment);
								File tgtContentPath = new File(LibraryService
										.getInstance()
										.getCurrentMethodLibraryPath(),
										contentPath);
								File tgtFile = new File(tgtContentPath,
										attachment);
								if (!tgtFile.exists()) {
									FileUtil.copyfile(srcFile, tgtFile);
								}
							} catch (IOException ex) {
								LibraryPlugin.getDefault().getLogger()
										.logError(ex);
							}
						}
					}
				}
			}
		}

		// handle children
		Iterator iter = e.eAllContents();
		while (iter.hasNext()) {
			EObject child = (EObject) iter.next();
			HandleAttachmentsPlugin(child);
		}
	}

	/**
	 * Copy all attachments from one library to another
	 * 
	 * @param oldLibDir
	 *            Original library root
	 * @param newLibDir
	 *            New library root
	 * @param xmiList
	 *            list of xmi File's (pass null to process all files in
	 *            newLibDir)
	 * @param monitor
	 *            optional (can be null) IProgressMonitor
	 */
	public static void copyAttachmentsLibrary(String oldLibDir,
			String newLibDir, List xmiList, IProgressMonitor monitor) {

		// get list of .xmi files in newLibDir
		if (xmiList == null)
			xmiList = FileUtil.fileList(new File(newLibDir), "xmi"); //$NON-NLS-1$

		if (monitor != null)
			monitor.subTask(LibraryResources.copyingAttachmentsTask_name);

		Iterator iter = xmiList.iterator();
		while (iter.hasNext()) {
			if (monitor != null)
				monitor.worked(1);
			File xmiFile = (File) iter.next();
			if (xmiFile.exists()) {
				// parse xmi file
				SAXParserXMI parser = new SAXParserXMI(null);
				parser.parse(xmiFile.getAbsolutePath());
				// iterate thru it's elements, checking content for attachments
				ContentResourceScanner scanner = new ContentResourceScanner(
						new File(oldLibDir));
				scanner.setTargetRootPath(new File(newLibDir));
				HandleAttachments(parser.xmiMap, scanner, xmiFile.getParent()
						.substring(newLibDir.length()));
			}
		}
	}

	private static void HandleAttachments(HashMap eMap,
			ContentResourceScanner scanner, String contentPath) {
		// handle self
		String content = SAXParserXMI.getElementContent(eMap);
		if (content != null) {
			// scan content for attachments
			scanner.resolveResources(content, contentPath);
		}

		// handle children
		Iterator iter = ((ArrayList) eMap.get("children")).iterator(); //$NON-NLS-1$
		while (iter.hasNext()) {
			HashMap childMap = (HashMap) iter.next();
			HandleAttachments(childMap, scanner, contentPath);
		}
	}

}
