package org.eclipse.epf.library.validation;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.eclipse.core.resources.IMarker;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.MultiStatus;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.epf.library.LibraryPlugin;
import org.eclipse.epf.library.LibraryResources;
import org.eclipse.epf.library.edit.LibraryEditPlugin;
import org.eclipse.epf.library.edit.LibraryEditResources;
import org.eclipse.epf.library.edit.util.LibraryEditUtil;
import org.eclipse.epf.library.edit.util.Misc;
import org.eclipse.epf.library.edit.util.TngUtil;
import org.eclipse.epf.library.edit.validation.ValidationStatus;
import org.eclipse.epf.library.util.LibraryUtil;
import org.eclipse.epf.persistence.FileManager;
import org.eclipse.epf.uma.MethodElement;
import org.eclipse.epf.uma.MethodPlugin;
import org.eclipse.epf.uma.UmaPackage;
import org.eclipse.epf.uma.util.UmaUtil;
import org.eclipse.epf.validation.LibraryEValidator;

public class UndeclaredDependencyCheck extends ValidationAction {
	
	private Map<MethodPlugin, Set<MethodPlugin>> baseMap;
	private Map<MethodPlugin, Set<MethodPlugin>> problemPluginMap;
	private Map<String, Set<MethodElement>> problemElementMap;
	private boolean skipContent = true;

	public UndeclaredDependencyCheck(ValidationManager mgr) {
		super(mgr);
	}
	
	@Override
	public void run() {
		Set<MethodPlugin> pluginSet = getMgr().getPluginSet();
		if (pluginSet == null || pluginSet.isEmpty()) {
			return;
		}

		//Initialization
		problemPluginMap = new HashMap<MethodPlugin, Set<MethodPlugin>>();
		problemElementMap = new HashMap<String, Set<MethodElement>>();
		baseMap = new HashMap<MethodPlugin, Set<MethodPlugin>>();

		Misc.clearCachedMap();
		for (MethodPlugin plugin : pluginSet) {
			Set baseSet = new HashSet();
			baseSet.addAll(Misc.getAllBase1(plugin));
			baseMap.put(plugin, baseSet);
		}
		Misc.clearCachedMap();

		//Validation check
		Set<MethodElement> processed = new HashSet<MethodElement>();
		for (MethodPlugin plugin : pluginSet) {
			checkReferences(plugin, processed);
		}
		

		MultiStatus multiStatus = new MultiStatus(LibraryPlugin.PLUGIN_ID, 0, "", null); //$NON-NLS-1$
		//Build markers
		for (Map.Entry<MethodPlugin, Set<MethodPlugin>> entry : problemPluginMap
				.entrySet()) {
			MethodPlugin plugin = entry.getKey();
			Set<MethodPlugin> set = entry.getValue();
			
			String msg0 = LibraryResources.bind(LibraryResources.UndeclaredDep_MarkerTxt1, (new String[] {plugin.getName()}));
			for (MethodPlugin p : set) {
				IMarker marker = getMgr().createMarker(plugin);
				String msg = msg0 + " '" + p.getName() + "'";	 //$NON-NLS-1$  //$NON-NLS-2$
				String key = plugin.getGuid() + p.getGuid();
				Set<MethodElement> elements = problemElementMap.get(key);
				if (elements != null && !elements.isEmpty()) {
					String line2msg0 = ". \n" + LibraryResources.UndeclaredDep_MarkerTxt2 + " ";	//$NON-NLS-1$ //$NON-NLS-2$
					String line2msg = line2msg0;
					for (MethodElement e : elements) {
						if (line2msg.length() > 155) {
							line2msg += " ... ";	 //$NON-NLS-1$  
							break;
						}
						if (line2msg != line2msg0) {
							line2msg += "; ";		 //$NON-NLS-1$  
						}
						line2msg += TngUtil.getLabelWithPath(e);
					}
					msg += line2msg;
				}							
				try {
					marker.setAttribute(IMarker.MESSAGE, msg);
					
					marker.setAttribute(IMarker.SEVERITY,
							IMarker.SEVERITY_WARNING);
					
					marker.setAttribute(IMarker.LOCATION, TngUtil.getLabelWithPath(plugin));
					marker.setAttribute(ValidationManager.validationType, ValidationManager.validationType_undeclaredDependancyCheck);
										
					MarkerInfo markerInfo = new MarkerInfo(plugin, p, elements);
					getMgr().addToMarkInfoMap(marker, markerInfo);
					
					multiStatus.add(new ValidationStatus(IStatus.WARNING, 0, LibraryResources.UndeclaredDep_MarkerTxt0, plugin, null));					
					
				} catch (Exception e) {
					LibraryPlugin.getDefault().getLogger().logError(e);
				}
			}
		}
		
		LibraryEValidator.appendDiagnostics(multiStatus, getMgr().getDiagnostics());		
		//Clear
		problemPluginMap = null;
		problemElementMap = null;
		baseMap =null;
	}
	
	private void addToProblemPluginMap(MethodPlugin plugin, MethodPlugin referencedPlugin) {
		Set<MethodPlugin> set = problemPluginMap.get(plugin);
		if (set == null) {
			set = new HashSet<MethodPlugin>();
			problemPluginMap.put(plugin, set);
		}
		set.add(referencedPlugin);
	}
	
	
	private void checkReferences(MethodElement me, Set<MethodElement> processed) {
		if (processed.contains(me)) {
			return;
		}
		processed.add(me);
		MethodPlugin ownerPlugin = UmaUtil.getMethodPlugin(me);
		if ( ! getMgr().getPluginSet().contains(ownerPlugin)) {
			return;
		}
		
		Set<MethodPlugin> baseSet = baseMap.get(ownerPlugin);
				
		EList<EReference> refList = me.eClass().getEAllReferences();
		if (refList == null || refList.isEmpty()) {
			return;
		}
		for (EReference ref : refList) {
			if (skipContent && LibraryUtil.isContentRef(ref)) {
				continue;
			}
			if (ref == UmaPackage.eINSTANCE.getRole_Modifies()) {
				continue;
			}
			Object obj = me.eGet(ref);
			if (obj instanceof MethodElement) {
				MethodElement referenced = (MethodElement) obj;
				recordOneHit(me, ownerPlugin, baseSet, referenced);				
				checkReferences(referenced, processed);
				
			} else if (obj instanceof List) {
				List list = (List) obj;
				for (Object itemObj : list) {
					if (itemObj instanceof MethodElement) {
						MethodElement referenced = (MethodElement) itemObj;					
						recordOneHit(me, ownerPlugin, baseSet, referenced);	
						checkReferences(referenced, processed);
					}
				}
			}
		}
	}

	private void recordOneHit(MethodElement me, MethodPlugin ownerPlugin,
			Set<MethodPlugin> baseSet, MethodElement referenced) {
		MethodPlugin referencedPlugin = UmaUtil.getMethodPlugin(referenced);
		if (referencedPlugin != null && referencedPlugin != ownerPlugin && !baseSet.contains(referencedPlugin)) {
			addToProblemPluginMap(ownerPlugin, referencedPlugin);
			String key = ownerPlugin.getGuid() + referencedPlugin.getGuid();
			Set<MethodElement> set = problemElementMap.get(key);
			if (set == null) {
				set = new HashSet<MethodElement>();
				problemElementMap.put(key, set);
			}
			set.add(me);
		}
	}
		
	public void clearResults() {		
	}

	public String addPluginFix(IMarker marker) {
		String emptyStr = "";	//$NON-NLS-1$ 
		
		Object obj = getMgr().getMarkInfo(marker);
		MarkerInfo info = obj instanceof MarkerInfo ? (MarkerInfo) obj : null;
		if (info == null) {
			return emptyStr;
		}
		if (info.referencing == null || info.referenced == null || info.referencing == info.referenced) {
			return emptyStr;
		}
		
		if (Misc.isBaseOf(info.referencing, info.referenced, new HashMap())) {
			return LibraryEditResources.circular_dependency_error_msg;	
		}
		
		info.referencing.getBases().add(info.referenced);
		Resource resource = info.referencing.eResource();
		if (resource == null || !LibraryEditUtil.getInstance().save(Collections.singleton(resource))) {			
			info.referencing.getBases().remove(info.referenced);
			LibraryPlugin.getDefault().getLogger().logError("addPluginFix falied at save");//$NON-NLS-1$ 
			return emptyStr;
		}
		
		getMgr().removeFromMarkInfoMap(marker);
		return emptyStr;
	}
	
	public String removeReferenceFix(IMarker marker) {
		String emptyStr = ""; //$NON-NLS-1$ 
		
		Object infoObj = getMgr().getMarkInfo(marker);
		MarkerInfo info = infoObj instanceof MarkerInfo ? (MarkerInfo) infoObj : null;
		if (info == null || info.referenced == null) {
			return emptyStr;
		}
		Set<MethodElement> offenderElements = info.offenderElements;
		if (offenderElements == null || offenderElements.isEmpty()) {
			return emptyStr;
		}
		Set<Resource> resources = new HashSet<Resource>();
		for (MethodElement e : offenderElements) {
			Resource res = e.eResource();
			if (res != null) {
				resources.add(res);
			}
		}
		List<String> pathList = new ArrayList<String>();
		for (Resource res : resources) {
			pathList.add(res.getURI().toFileString());
		}
		
		IStatus status = FileManager.getInstance().checkModify(pathList.toArray(new String[pathList.size()]), LibraryPlugin.getDefault().getContext());
		if (!status.isOK()) {
			info.referencing.getBases().remove(info.referenced);
			LibraryPlugin.getDefault().getLogger().logError("addPluginFix falied at file check");//$NON-NLS-1$ 
			return emptyStr;
		}

		for (MethodElement me : offenderElements) {				
			EList<EReference> refList = me.eClass().getEAllReferences();
			if (refList == null) {
				continue;
			}
			for (EReference ref : refList) {				
				if (skipContent && LibraryUtil.isContentRef(ref)) {
					continue;
				}
				if (ref == UmaPackage.eINSTANCE.getRole_Modifies()) {
					continue;
				}
				Object obj = me.eGet(ref);
				if (obj instanceof MethodElement) {
					MethodElement referenced = (MethodElement) obj;
					if (info.referenced == UmaUtil.getMethodPlugin(referenced)) {
						me.eSet(ref, null);
					}
					
				} else if (obj instanceof List) {
					List list = (List) obj;
					for (int i = list.size() - 1; i >= 0 ; i--) {
						Object itemObj = list.get(i);
						if (itemObj instanceof MethodElement) {
							MethodElement referenced = (MethodElement) itemObj;	
							if (info.referenced == UmaUtil.getMethodPlugin(referenced)) {
								list.remove(i);
							}
						}
					}
				}
			}

		}
		
		if (!LibraryEditUtil.getInstance().save(resources)) {			
			info.referencing.getBases().remove(info.referenced);
			LibraryPlugin.getDefault().getLogger().logError("addPluginFix falied at save");//$NON-NLS-1$ 
			return emptyStr;
		}
		
		getMgr().removeFromMarkInfoMap(marker);
		return emptyStr;
	}
	
	static class MarkerInfo {
		MethodPlugin referencing;
		MethodPlugin referenced;
		Set<MethodElement> offenderElements;
		public MarkerInfo(MethodPlugin referencing, MethodPlugin referenced, Set<MethodElement> offenderElements) {
			this.referencing = referencing;
			this.referenced = referenced;
			this.offenderElements = offenderElements;
		}
	}
	
}
