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

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;
		private Map<MethodConfiguration, Map<String, IMarker>> configMakerMap;

		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();			
			configMakerMap =  new HashMap<MethodConfiguration, Map<String, IMarker>>();
			
			// 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);
			}
		}
		
		public Map<MethodConfiguration, Map<String, IMarker>> getConfigMakerMap() {
			return configMakerMap;
		}
	}
	
	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);
	    		unregisterMarker(config, error.getId());
	    	}
		} 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);
	    		registerNewMarker(config, error.getId(), marker);
	    		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;
    	}
    	
   		return findMarker(config, error.getId());
    	    	
//    	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;
	}

	private void registerNewMarker(MethodConfiguration config, String id, IMarker marker) {
		Map<String, IMarker> map = containersOfMarkedObjects.getConfigMakerMap().get(config);
		if (map == null) {
			map = new HashMap<String, IMarker>(); 
			containersOfMarkedObjects.getConfigMakerMap().put(config, map);
		}
		map.put(id, marker);
	}
	
	private void unregisterMarker(MethodConfiguration config, String id) {
		Map<String, IMarker> map = containersOfMarkedObjects.getConfigMakerMap().get(config);
		if (map == null) {
			return;
		}
		map.remove(id);
	}
	
	private IMarker findMarker(MethodConfiguration config, String id) {
		Map<String, IMarker> map = containersOfMarkedObjects.getConfigMakerMap().get(config);
		if (map == null) {
			return null;
		}		
		return map.get(id);
	}
	
	public void removeAllMarkers(MethodConfiguration config) {
		Map<String, IMarker> map = containersOfMarkedObjects.getConfigMakerMap().remove(config);
		if (map == null) {
			return;
		}
		for (IMarker marker : map.values()) {
			try {
				marker.delete();
			} catch (CoreException e) {
				AuthoringUIPlugin.getDefault().getLogger().logError(e);
			}
		}
	}
	
}
