//------------------------------------------------------------------------------
// 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.persistence.util;

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

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.emf.common.CommonPlugin;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.epf.common.service.versioning.EPFVersions;
import org.eclipse.epf.common.service.versioning.VersionUtil;
import org.eclipse.epf.library.persistence.ILibraryResource;
import org.eclipse.epf.library.persistence.ILibraryResourceSet;
import org.eclipse.epf.persistence.FileManager;
import org.eclipse.epf.persistence.MultiFileResourceSetImpl;
import org.eclipse.epf.persistence.MultiFileSaveUtil;
import org.eclipse.epf.persistence.PersistencePlugin;
import org.eclipse.epf.persistence.migration.internal.Migrator;
import org.eclipse.epf.persistence.refresh.internal.RefreshEvent;
import org.eclipse.epf.uma.ContentDescription;
import org.eclipse.epf.uma.DescribableElement;
import org.eclipse.epf.uma.MethodElement;
import org.eclipse.epf.uma.MethodLibrary;
import org.eclipse.epf.uma.UmaPackage;
import org.osgi.framework.Version;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

/**
 * Utility class with static helper methods for library persistence
 * 
 * @author Phong Nguyen Le
 * @since 1.0
 */
public class PersistenceUtil {

	/**
	 * Gets the current namespace URI of UMA.
	 */
	public static final String getUMANsURI() {
		return UmaPackage.eNS_URI;
	}

	public static final String getUMANsURI(String libPath) {
		try {
			DocumentBuilder builder = DocumentBuilderFactory.newInstance()
					.newDocumentBuilder();
			Document doc = builder.parse(new File(libPath));
			Element root = doc.getDocumentElement();
			String nsURI = root.getAttribute("xmlns:com.ibm.uma"); //$NON-NLS-1$
			if (nsURI == null || nsURI.equals("")) { //$NON-NLS-1$
				nsURI = root.getAttribute("xmlns:org.eclipse.epf.uma"); //$NON-NLS-1$
			}
			if (nsURI == null || nsURI.equals("")) { //$NON-NLS-1$
				nsURI = root.getAttribute("xmlns:uma") + "/uma.ecore"; //$NON-NLS-1$ //$NON-NLS-2$
			}
			return nsURI;
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}

	public static final boolean conversionRequired(String libPath) {
		String currentNsURI = PersistenceUtil.getUMANsURI();
		String libNsURI = PersistenceUtil.getUMANsURI(libPath);
		if (currentNsURI.equals(libNsURI))
			return false;
		if (Migrator.OLD_UMA_NS_URI.equals(libNsURI))
			return true;
		return false;
	}

	public static final IResource getWorkspaceResource(Object obj) {
		Resource resource = null;
		if (obj instanceof DescribableElement) {
			DescribableElement e = (DescribableElement) obj;
			ContentDescription content = e.getPresentation();
			resource = content.eResource();
			if (resource == null) {
				resource = e.eResource();
			}
		} else if (obj instanceof EObject) {
			resource = ((EObject) obj).eResource();
		} else if (obj instanceof Resource) {
			resource = (Resource) obj;
		}
		if (resource != null && resource.getURI().isFile()) {
			return FileManager.getResourceForLocation(resource.getURI()
					.toFileString());
		}
		return null;
	}

	public static final Collection<EObject> getProxies(EObject obj) {
		Collection<EObject> proxies = new ArrayList<EObject>();
		for (Iterator iter = obj.eAllContents(); iter.hasNext();) {
			EObject o = (EObject) iter.next();
			if (o.eIsProxy()) {
				proxies.add(o);
			}
		}
		return proxies;
	}

	/**
	 * Checks the primary tool version stored in the given resource
	 * 
	 * @param resource
	 * @return <li> < 0 if the version of the primary tool stored in the given resource is missing or older than current
	 *         <li> 0 if the primary tool version in the given resource matches the current version
	 *         <li> > 0 if  the primary tool version in the given resource is newer than the current version
	 */
	public static final int checkToolVersion(Resource resource) {
		File file = new File(resource.getURI().toFileString());
		Map fileVersionMap = VersionUtil.readVersionsFromFile(file);
		if(fileVersionMap != null) {
			String version = (String) fileVersionMap.get(VersionUtil.getPrimaryToolID());
			if(version != null) {
				EPFVersions versions = VersionUtil.getVersions(VersionUtil.getPrimaryToolID());
				return versions.getCurrentVersion().compareToolVersionTo(new Version(version));
			}
		}
		return -1;
	}

	/**
	 * Gets the first method element in contents of the given resource.
	 *  
	 * @param resource
	 * @return
	 */
	public static MethodElement getMethodElement(Resource resource) {
		for (Iterator iter = resource.getContents().iterator(); iter.hasNext();) {
			Object element = iter.next();
			if (element instanceof MethodElement) {
				return (MethodElement) element;
			}
		}
		return null;
	}
	
	/**
	 * Resolves the proxy and its containers
	 * 
	 * @param proxy
	 * @return
	 */
	public static EObject resolve(EObject proxy, ResourceSet resourceSet) {
		EObject resolved;
		try {
			resolved = EcoreUtil.resolve(proxy, resourceSet);
		} catch (Exception e) {
			resolved = proxy;
		}
		EObject container = proxy.eContainer();
		if (resolved.eContainer() == null && container != null) {
			if (container.eIsProxy()) {
				container = resolve(container, resourceSet);
			}
			EReference ref = proxy.eContainmentFeature();
			if (ref.isMany()) {
				List values = (List) container.eGet(ref);
				for (Iterator iter = values.iterator(); iter.hasNext(); iter
						.next())
					;
			} else {
				container.eGet(ref);
			}
		}
		return resolved;
	}
	
	public static Resource getResource(IPath path, ResourceSet resourceSet) {
		return getResource(path.toOSString(), resourceSet);
	}
	
	public static Resource getResource(String path, ResourceSet resourceSet) {
		URI uri = URI.createFileURI(path);
		for (Iterator iter = new ArrayList<Resource>(resourceSet.getResources())
				.iterator(); iter.hasNext();) {
			Resource resource = (Resource) iter.next();
			if (uri.equals(MultiFileSaveUtil.getFinalURI(resource))) {
				return resource;
			}
		}
		return null;

	}
	
	/**
	 * Resolves container of the MethodElement in the given resource.
	 * 
	 * @param resource
	 */
	public static void resolveContainer(Resource resource) {
		ResourceSet resourceSet = resource.getResourceSet();
		if(resourceSet instanceof MultiFileResourceSetImpl) {
			((MultiFileResourceSetImpl)resourceSet).resolveContainer(resource);
		}
	}

	public static MethodElement getMethodElement(IResource iResource, ResourceSet resourceSet) {
		MethodElement element = null;
		URI uri = URI.createFileURI(iResource.getLocation().toOSString());
		Resource resource = resourceSet.getResource(uri, true);		
		if (resource != null) { 
			if(resourceSet instanceof MultiFileResourceSetImpl) {
				((MultiFileResourceSetImpl)resourceSet).resolveContainer(resource);
			}
			element = PersistenceUtil.getMethodElement(resource);
			if (element instanceof ContentDescription) {
				EObject container = ((ContentDescription)element).eContainer();
				if (container instanceof MethodElement) {
					element = (MethodElement)container;
				}
			}
		}
		return element;
	}
	
	public static void loadAllLibraryResources(MethodLibrary lib) {
		for (Iterator iter = lib.eAllContents(); iter.hasNext();) {
			EObject element = (EObject) iter.next();
			if (element instanceof MethodElement) {
				try {
					for (Iterator iterator = element.eCrossReferences()
							.iterator(); iterator.hasNext();) {
						iterator.next();
					}
				} catch (Exception e) {
					CommonPlugin.INSTANCE.log(e);
				}
			}
		}
	}
	
	public static String getTopAttribute(File file, final String attributeName) {
		// Create the SAX parser factory.
		SAXParserFactory spf = SAXParserFactory.newInstance();

		// Create the SAX parser.
		try {
			SAXParser saxParser = spf.newSAXParser();
			final String[] valueHolder = new String[1];
			try {
			saxParser.parse(file, new DefaultHandler() {	
				private boolean started;
				@Override
				public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
					if(started) {
						throw new OperationCanceledException();
					}
//					System.out.println("uri: " + uri);
//					System.out.println("localName: " + localName);
//					System.out.println("qName: " + qName);
					valueHolder[0] = attributes.getValue(attributeName);
					started = true;
				}
			});
			}
			catch(OperationCanceledException e) {
				//
			}
			return valueHolder[0];
		} catch (Exception e) {
			PersistencePlugin.getDefault().getLogger().logError(e);
		}
		return null;
	}
		
	public static void unload(Collection<Resource> removedResources) {
		Map<MultiFileResourceSetImpl, Collection<Resource>> resourceSetToUnloadedResourcesMap = new HashMap<MultiFileResourceSetImpl, Collection<Resource>>();
		for (Resource resource : removedResources) {
			ResourceSet resourceSet = resource.getResourceSet();
			boolean unloaded = false;
			try {
				if(resourceSet instanceof ILibraryResourceSet) {
					if(((ILibraryResourceSet)resourceSet).unload(resource, Collections.EMPTY_MAP)) {
						resourceSet.getResources().remove(resource);
						unloaded = true;
					}
				}
				else {
					if(resource.isLoaded()) {
						resource.unload();
						unloaded = true;
					}
					if(resourceSet != null) {
						resourceSet.getResources().remove(resource);
					}
				}
			} catch (Exception e) {
				PersistencePlugin.getDefault().getLogger().logError(e);
			}	
			if(unloaded && resourceSet instanceof MultiFileResourceSetImpl) {
				Collection<Resource> unloadedResources = resourceSetToUnloadedResourcesMap.get(resourceSet);
				if(unloadedResources == null) {
					unloadedResources = new ArrayList<Resource>();
					resourceSetToUnloadedResourcesMap.put((MultiFileResourceSetImpl) resourceSet, unloadedResources);
				}
				unloadedResources.add(resource);
			}
		}
		for (Map.Entry<MultiFileResourceSetImpl, Collection<Resource>> entry : resourceSetToUnloadedResourcesMap.entrySet()) {
			entry.getKey().notifyRefreshListeners(new RefreshEvent(entry.getValue()));
		}
	}
	
	/**
	 * Checks if the given method element has a GUID that is the same as GUID of
	 * one element in the given elements list.
	 * 
	 * @param e
	 * @param elements
	 * @return true if the given method element has duplicate GUID
	 */
	public static boolean hasDuplicateGUID(MethodElement e, Collection<? extends MethodElement> elements) {
		for (MethodElement element : elements) {
			if(e.getGuid().equals(element.getGuid())) {
				return true;
			}
		}
		return false;
	}
	
	private static String toPrefix(String path) {
		return path.endsWith(File.separator) ? path : path + File.separator;
	}
	
	public static void replaceURIPrefix(Collection<Resource> resources, String oldPrefix, String newPrefix) {
		URI oldPrefixURI = URI.createFileURI(toPrefix(oldPrefix));
		URI newPrefixURI = URI.createFileURI(toPrefix(newPrefix));
		for(Resource resource : resources) {
			URI uri = resource.getURI();
			URI newURI = null;
			try {
				newURI = uri.replacePrefix(oldPrefixURI, newPrefixURI);
			}
			catch(Exception e) {
				
			}
			if(newURI != null) {
				resource.setURI(newURI);
			}
		}
	}
	
	public static URI getProxyURI(EObject object) {
		Resource resource = object.eResource();
		URI uri = null;
		if(resource instanceof ILibraryResource) {
			ILibraryResource libResource = (ILibraryResource) resource;
			uri = libResource.getProxyURI(object);			
		}
		else {
			uri = resource.getURI().appendFragment(resource.getURIFragment(object));
		}
		return uri;
	}
	
	public static MultiFileResourceSetImpl getImportPluginResourceSet() {
		MultiFileResourceSetImpl resourceSet;
		resourceSet = new MultiFileResourceSetImpl(false) {
			protected void demandLoad(Resource resource) throws IOException {
				if (! skipDemandLoad(resource)) {
					super.demandLoad(resource);
				}
			}
			private boolean skipDemandLoad(Resource res) {
				File file = new File(res.getURI().toFileString());
				if (! file.exists() && file.getName().equals(MultiFileSaveUtil.DEFAULT_PLUGIN_MODEL_FILENAME)) {
					return true;
				}
				return false;
			}
		};
		return resourceSet;
	}

	
	public static void main(String[] args) {
		String attrib = getTopAttribute(new File(args[0]), args[1]);
		System.out.println(attrib);
	}
}