//------------------------------------------------------------------------------
// 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, lastOldPlugin);

				// 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();
		if (e.eContents() == null) {
			return;
		}
		Iterator iter = e.eContents().iterator();
		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, MethodPlugin sourcePlugin) {
		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;
		File tgt_root = new File(resMgr.getPhysicalPluginPath(owner));
		File src_root = new File(resMgr.getPhysicalPluginPath(sourcePlugin));
		
		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);
		}
	}

}
