//------------------------------------------------------------------------------
// 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.net.URISyntaxException;
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 java.util.regex.Matcher;

import org.eclipse.core.runtime.IProgressMonitor;
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.ILibraryResourceManager;
import org.eclipse.epf.library.LibraryPlugin;
import org.eclipse.epf.library.LibraryResources;
import org.eclipse.epf.library.edit.command.MethodElementAddCommand.BasicResourceManager;
import org.eclipse.epf.library.edit.util.TngUtil;
import org.eclipse.epf.library.layout.IContentValidator;
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 {
					// shape icon
					java.net.URI shapeIconUri = de.getShapeicon();
					if (shapeIconUri != null) {
						// To handle the shapeIcon/nodeIcon uri got changed, its relative to pluginPath.
						java.net.URI newShapeIconUri = handleIconURI(de,
								shapeIconUri);
						if (newShapeIconUri != null) {
							de.setShapeicon(newShapeIconUri);
							modifiedResourceSet.add(de.eResource());
						}
					}

					// node icon
					java.net.URI nodeIconUri = de.getNodeicon();
					if (nodeIconUri != null) {
						java.net.URI newNodeIconUri = handleIconURI(de,
								nodeIconUri);
						if (newNodeIconUri != null) {
							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;
				
				
				ILibraryResourceManager resMgr = ResourceHelper.getResourceMgr(elementToProcess);
				ILibraryResourceManager lastOldPluginResMgr = ResourceHelper.getResourceMgr(lastOldPlugin);
				
				ContentResourceScanner scanner = getScanner(elementToProcess);

				// iterate thru element's content
				String contentPath = ResourceHelper
						.getElementPath((MethodElement) elementToProcess);
				if (contentPath == null || contentPath.length() == 0) {
					LibraryPlugin
							.getDefault()
							.getLogger()
							.logWarning(
									NLS.bind(LibraryResources.CopyAttachmentsToNewLocation_log_noContentPath, (new Object[] { ((MethodElement) elementToProcess).getName() }))); 
					return;
				}

				// FIXME: this is not always correct this relative of the element's folder might have been changed
				// during move/copy
				String oldContentPath = contentPath.replaceFirst(UmaUtil
						.getMethodPlugin(elementToProcess).getName(),
						lastOldPlugin.getName());
				
				//Commented out the following and rolled back to the above to fix a bug
				//with attached file in content paste. But why it was introduced? Without it
				//the shape and node icon appear to be working fine.
				//String oldContentPath = ResourceHelper
				//	.getElementPath(lastOldPlugin);				

				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
//				String libRoot = ResourceHelper.getVirtualLibraryRoot(elementToProcess);
				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) {
							Matcher m = ResourceHelper.p_template_attachment_url.matcher(attachment);
							if (!m.find()) {
								File srcContentPath = new File(lastOldPluginResMgr.resolve(lastOldPlugin, oldContentPath));
								File srcFile = new File(srcContentPath,
										attachment);
								File tgtContentPath = new File(resMgr.getPhysicalPath(elementToProcess));
								File tgtFile = new File(tgtContentPath,
										attachment);
								if (!tgtFile.exists()) {
									FileUtil.copyFile(srcFile, tgtFile);
								}
							}
						}
					}
				}
			}
		}

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

	/**
	 * 
	 * @param de
	 * @param iconUri
	 * @return the new Icon URI (relative path, so its ready to be persisted to the model)
	 * @throws URISyntaxException
	 */
	private java.net.URI handleIconURI(DescribableElement de,
			java.net.URI iconUri) throws URISyntaxException {
		java.net.URI srcUri = TngUtil.getFullPathURI(de,
				iconUri);
		String iconPath = NetUtil.decodedFileUrl(iconUri.getPath());
		
		if(iconPath.indexOf(lastOldPlugin.getName()) < 0){
			srcUri = new File(ResourceHelper.getPluginPath(lastOldPlugin) + File.separator + iconPath).toURI();
		}
		File srcFile = new File(srcUri);
		java.net.URI tgtUri = new File(ResourceHelper.getPluginPath(de) + File.separator + iconPath).toURI();
		File tgtFile = new File(tgtUri);
		if (!tgtFile.exists()) {
			FileUtil.copyFile(srcFile, tgtFile);
		}
		java.net.URI newIconUri = new java.net.URI(NetUtil
				.encodeFileURL(FileUtil.getRelativePath(
						tgtFile, new File(ResourceHelper.getPluginPath(de)))));
		return newIconUri;
	}

	/**
	 * Returns the content resource scanner for the element.
	 */
	private ContentResourceScanner getScanner(MethodElement owner) {
		ILibraryResourceManager resMgr = ResourceHelper.getResourceMgr(owner);
		if ( resMgr == null ) {
			return null;
		}
		
		String rootContentPath = resMgr.getLogicalPluginPath(owner);
		File src_root = new File(resMgr.getPhysicalPluginPath(owner));
		File tgt_root = src_root;
		ContentResourceScanner scanner = new ContentResourceScanner(src_root, tgt_root, rootContentPath, getValidator());

		return scanner;
	}
	
	public IContentValidator getValidator() {
		return null;
	}

	
	/**
	 * 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), new File(newLibDir), null);
				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);
		}
	}

}
