//------------------------------------------------------------------------------
// Copyright (c) 2005, 2007 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.authoring.ui.util;

import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.Path;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.epf.authoring.ui.AuthoringUIPlugin;
import org.eclipse.epf.common.utils.ExtensionHelper;
import org.eclipse.epf.common.utils.IMarkerAttributeContributer;
import org.eclipse.epf.library.LibraryService;
import org.eclipse.epf.library.LibraryServiceListener;
import org.eclipse.epf.library.configuration.closure.IConfigurationError;
import org.eclipse.epf.library.edit.navigator.ConfigurationsItemProvider;
import org.eclipse.epf.library.edit.util.TngUtil;
import org.eclipse.epf.library.project.MethodLibraryProject;
import org.eclipse.epf.persistence.FileManager;
import org.eclipse.epf.uma.MethodConfiguration;
import org.eclipse.epf.uma.MethodElement;
import org.eclipse.epf.uma.MethodLibrary;
import org.eclipse.ui.ide.IDE;
import org.eclipse.ui.views.markers.MarkerViewUtil;

/**
 *  Helper class to handle Configuration error markers
 * @author Jeff Hardy
 * @author Jinhua Xi
 *
 */
public class ConfigurationMarkerHelper {	
	public static final ConfigurationMarkerHelper INSTANCE = new ConfigurationMarkerHelper();
	public static final String ATTR_ERROR_ID = "errorID"; //$NON-NLS-1$
	public static final String ATTR_CONFIG_GUID = "configGuid"; //$NON-NLS-1$
	public static final String ATTR_MESSAGE_ID = "messageId"; //$NON-NLS-1$
	public static final String ATTR_ERROR_ELEMENT_GUID = "elementGuid"; //$NON-NLS-1$
	public static final String ATTR_CAUSE_ELEMENT_GUID = "causeGuid"; //$NON-NLS-1$

	// marker ID
	public static final String MARKER_ID = "org.eclipse.epf.authoring.ui.configuration"; //$NON-NLS-1$

	
//	private Map<ElementDependencyError, IMarker> errorMarkerMap = new HashMap<ElementDependencyError, IMarker>();
	
	// private constructor
	private ConfigurationMarkerHelper() {
	}
	
	private static class ContainerMap extends HashMap<Object, Integer> {
		/**
		 * 
		 */
		private static final long serialVersionUID = 1L;

		public ContainerMap() {
			super();
			initMap();
			LibraryService.getInstance().addListener(new LibraryServiceListener() {
				public void libraryOpened(MethodLibrary library) {
					initMap();
				}
				
				public void libraryClosed(MethodLibrary library) {
					clear();
				}
				
				public void libraryReopened(MethodLibrary library) {
					initMap();
				}				
			});
		}
		
		private void initMap() {
			clear();
			
			// fill this set with containers of marked objects
			//
			MethodLibrary lib = LibraryService.getInstance().getCurrentMethodLibrary();
			if(lib != null) {
				IProject prj = MethodLibraryProject.findProject(lib);
				if(prj != null) {
					try {
						IMarker[] markers = prj.findMarkers(INSTANCE.getMarkerID(), false, IResource.DEPTH_INFINITE);
						for (int i = 0; i < markers.length; i++) {
							IMarker marker = markers[i];
							String guid = (String) marker.getAttribute(ATTR_CONFIG_GUID);
							MethodElement e = LibraryService.getInstance().getCurrentLibraryManager().getMethodElement(guid);
							if(e != null) {
								// remove its containers from containersOfMarkedObjects
								//
								markContainers(e);
							}
						}
					} catch (CoreException e) {
					}
				}
			}
		}
		
		private void increment(Object object) {
			Integer count;
			if (containsKey(object)) {
				count = get(object);
			} else {
				count = new Integer(0);
			}
			count++;
			put(object, count);
		}

		private void decrement(Object object) {
			if (containsKey(object)) {
				Integer count = get(object);
				if (count == 1) {
					// remove object
					remove(object);
				} else {
					count--;
					put(object, count);
				}
			}
		}
		
		private void markContainers(MethodElement e) {
			for(EObject container = e.eContainer(); container != null; container = container.eContainer()) {
				increment(container);
			}
		}

		private void unmarkContainers(MethodElement e) {
			for(EObject container = e.eContainer(); container != null; container = container.eContainer()) {
				decrement(container);
			}
		}
	}
	
	private static ContainerMap containersOfMarkedObjects = new ContainerMap();	
	
	
	protected String getMarkerID() {
		return MARKER_ID;
	}
	                                                                                                                             
	/* (non-Javadoc)
	 * @see org.eclipse.emf.common.ui.MarkerHelper#getFile(org.eclipse.emf.common.util.URI)
	 */
	protected IFile getFile(URI uri) {
		if(uri.isFile()) {
			return (IFile) FileManager.getResourceForLocation(uri.toFileString());
		}
	    String scheme = uri.scheme();
	    if ("platform".equals(scheme) && uri.segmentCount() > 1 && "resource".equals(uri.segment(0))) //$NON-NLS-1$ //$NON-NLS-2$
	    {
	      StringBuffer platformResourcePath = new StringBuffer();
	      for (int j = 1, size = uri.segmentCount(); j < size; ++j)
	      {
	        platformResourcePath.append('/');
	        platformResourcePath.append(URI.decode(uri.segment(j)));
	      }
	      return ResourcesPlugin.getWorkspace().getRoot().getFile(new Path(platformResourcePath.toString()));
	    }
	    return null;
	}
		
	/**
	 * Used by decorators to determine to put an error tick on the Object
	 * @param object
	 * @return
	 */
	public static boolean isInvalid(Object object) {
		if (object instanceof ConfigurationsItemProvider) {
			Collection children = ((ConfigurationsItemProvider)object).getChildren(object);
			for (Iterator iter = children.iterator(); iter.hasNext();) {
				Object obj = TngUtil.unwrap(iter.next());
				if(containersOfMarkedObjects.containsKey(obj)) {
					return true;
				}				
				if (obj instanceof MethodConfiguration) {
					if (INSTANCE.hasMarkers((MethodConfiguration)obj)) {
						return true;
					}
				}
			}
			return false;
		} else if (object instanceof MethodConfiguration) {
			if (INSTANCE.hasMarkers((MethodConfiguration)object)) {
				return true;
			}
		}
		return containersOfMarkedObjects.containsKey(object);
	}
		    
    public void deleteMarker(MethodConfiguration config, IConfigurationError error) {
    	try {
	    	IMarker marker = getMarker(config, error);
	    	if (marker != null) {
	    		marker.delete();
	    		containersOfMarkedObjects.unmarkContainers(config);
	    	}
		} catch (CoreException e) {
			AuthoringUIPlugin.getDefault().getLogger().logError(e);
		}
    }
	
    public IMarker createMarker(MethodConfiguration config, IConfigurationError error) {
//    	if (error.getErrorMethodElement() == null) return null;
//    	if (error.getCauseMethodElement() == null) return null;
    	
    	IMarker existingMarker = getMarker(config, error);
    	if (existingMarker != null) {
    		adjustMarker(existingMarker, config, error);
    		return existingMarker;
    	}
    	try {
	    	IResource resource = getIResource(config);
	    	if (resource != null && resource.exists()) {
	    		IMarker marker = resource.createMarker(getMarkerID());
	    		marker.setAttribute(IDE.EDITOR_ID_ATTR, "org.eclipse.epf.authoring.ui.editors.ConfigurationEditor"); //$NON-NLS-1$
	    		adjustMarker(marker, config, error);
	    		containersOfMarkedObjects.markContainers(config);
	    		return marker;
	    	}
		} catch (CoreException e) {
			AuthoringUIPlugin.getDefault().getLogger().logError(e);
		}
		return null;
    }
    
    public void adjustMarker(IMarker marker, MethodConfiguration config, IConfigurationError error) {
    	if (config == null || error == null) return;
       	try {
       		if (marker == null) {
       			// try to find marker
       			marker = getMarker(config, error);
       		}
       		if (marker == null) return;
			marker.setAttribute(IMarker.SEVERITY, error.getSeverity());
	    	String message = getMessage(error);
			marker.setAttribute(IMarker.MESSAGE, message);
			marker.setAttribute(IMarker.LINE_NUMBER, 0);
			marker.setAttribute(ATTR_CONFIG_GUID, config.getGuid());
			marker.setAttribute(ATTR_ERROR_ID, error.getId());
			marker.setAttribute(ATTR_MESSAGE_ID, error.getMessageId());
			
	    	if (error.getErrorMethodElement() != null) {
				marker.setAttribute(IMarker.LOCATION, TngUtil.getLabelWithPath(error.getErrorMethodElement()));
				marker.setAttribute(ATTR_ERROR_ELEMENT_GUID, error.getErrorMethodElement().getGuid());
				marker.setAttribute(MarkerViewUtil.NAME_ATTRIBUTE, error.getErrorMethodElement().getName());
	    	}
	    	if (error.getCauseMethodElement() != null) {
	    		marker.setAttribute(ATTR_CAUSE_ELEMENT_GUID, error.getCauseMethodElement().getGuid());
	    	}
	    	
			IMarkerAttributeContributer attAdder = ExtensionHelper.getMarkerAttributeContributer();
			if (attAdder != null) {
				attAdder.addAddtionalAttributes(marker, error);
			}
			
		} catch (CoreException e) {
			AuthoringUIPlugin.getDefault().getLogger().logError(e);
		}
   }
    	
    public boolean hasMarker(MethodConfiguration config, IConfigurationError error) {
		if (getMarker(config, error) != null) {
			return true;
		}
   		return false;
    }
    
    /**                                                                                                
     * Returns whether the a maker with id equals to the return of {@link #getMarkerID()}              
     * is available in the IResource computed from the specified object.                               
     * @param object                                                                                   
     * @return boolean                                                                                 
     */
    public boolean hasMarkers(MethodConfiguration config) {
    	IResource resource = getIResource(config);
        if (resource != null && resource.exists()) {
        	try {
				IMarker[] markers = resource.findMarkers(getMarkerID(), true, IResource.DEPTH_ZERO);
				return markers.length > 0;
	  		} catch (CoreException e) {
				AuthoringUIPlugin.getDefault().getLogger().logError(e);
			}
        }
        return false;
    }
    
    public IMarker getMarker(MethodConfiguration config, IConfigurationError error) {
    	if (config == null || error == null) {
    		return null;
    	}
    	try {
	    	IResource resource = getIResource(config);                                                     
	        if (resource != null) {                                                     
				IMarker[] markers = resource.findMarkers(getMarkerID(), false, IResource.DEPTH_ZERO);
				for (int i = 0; i < markers.length; i++) {
					IMarker marker = markers[i];
					String markerErrorId = (String) marker.getAttribute(ATTR_ERROR_ID);
					if (error.getId().equals(markerErrorId)) {
						return marker;
					}
				}
	        }
		} catch (CoreException e) {
			AuthoringUIPlugin.getDefault().getLogger().logError(e);
		}
		return null;
    }
    
    private String getMessage(IConfigurationError error) {
    	return error.getErrorMessage();
    }
    
    private IResource getIResource(MethodConfiguration config) {
    	Resource resource = config.eResource();
        URI uri = resource.getURI();
        uri = resource.getResourceSet().getURIConverter().normalize(uri);
        return getFile(uri);

    }
	
	public MethodConfiguration getConfig(IMarker marker) {
		if (marker == null) {
			return null;
		}
		try {
			String configGuid = (String) marker.getAttribute(ATTR_CONFIG_GUID);
			MethodElement e = LibraryService.getInstance().getCurrentLibraryManager().getMethodElement(configGuid);
			if (e instanceof MethodConfiguration) {
				return (MethodConfiguration)e;
			}
		} catch (CoreException e) {
			AuthoringUIPlugin.getDefault().getLogger().logError(e);
		}
		return null;
	}
	
	public MethodElement getErrorMethodElement(IMarker marker) {
		if (marker == null) {
			return null;
		}
		try {
			String errorGuid = (String) marker.getAttribute(ATTR_ERROR_ELEMENT_GUID);
			if (errorGuid != null) {
				MethodElement e = LibraryService.getInstance().getCurrentLibraryManager().getMethodElement(errorGuid);
				if (e instanceof MethodElement) {
					return (MethodElement)e;
				}
			}
		} catch (CoreException e) {
			AuthoringUIPlugin.getDefault().getLogger().logError(e);
		}
		return null;
	}

	public MethodElement getCauseMethodElement(IMarker marker) {
		if (marker == null) {
			return null;
		}
		try {
			String causeGuid = (String) marker.getAttribute(ATTR_CAUSE_ELEMENT_GUID);
			if (causeGuid != null) {
				MethodElement e = LibraryService.getInstance().getCurrentLibraryManager().getMethodElement(causeGuid);
				if (e instanceof MethodElement) {
					return (MethodElement)e;
				}
			}
		} catch (CoreException e) {
			AuthoringUIPlugin.getDefault().getLogger().logError(e);
		}
		return null;
	}

}
