//------------------------------------------------------------------------------
// Copyright (c) 2005, 2008 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.util.ArrayList;
import java.util.Collection;
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.IFile;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Status;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.epf.common.utils.RestartableJob;
import org.eclipse.epf.library.ILibraryManager;
import org.eclipse.epf.library.ILibraryService;
import org.eclipse.epf.library.LibraryPlugin;
import org.eclipse.epf.library.LibraryResources;
import org.eclipse.epf.library.LibraryService;
import org.eclipse.epf.library.LibraryServiceListener;
import org.eclipse.epf.library.LibraryServiceUtil;
import org.eclipse.epf.library.events.ILibraryChangeListener;
import org.eclipse.epf.services.ILibraryPersister;
import org.eclipse.epf.uma.MethodLibrary;
import org.eclipse.epf.uma.MethodPlugin;

/**
 * The class for monitor library problems.
 * 
 * (1) Wake up regularly (say every 30 seconds) 
 *     to schedule job if any change is registered during sleep
 *     
 * (2) Goes to sleep again immediately after "waking up/do nothing" or
 *     "waking up/scheduling a job"    
 *     
 * (3) Job (finding library problems) runs to end only there is no change during run.
 * 
 * (4) Job run is aborted (by throwing a RestartInterruptException)
 *     whenever a change is detected during run, and a new job scheduled 
 *     with a delay time (say 1 second).
 *      
 * (5) Make sure there is always at most one job running
 * 
 * @author Weiping Lu
 * @since 1.5
 */

public class LibraryProblemMonitor extends RestartableJob implements ILibraryChangeListener {
	
	public static final String UnresolvedBasedPluginMARKER_ID = LibraryPlugin.getDefault().getId() + ".unresolvedBasePlugins"; //$NON-NLS-1$
	
	public static final String Name = "name"; //$NON-NLS-1$
	public static final String Guid = "guid"; //$NON-NLS-1$
	public static final String UnresolvedBaseGuids = "unresolvedBaseGuids"; //$NON-NLS-1$
	
	private long delay = 30000L;
	private long restartDelay = 1000L;
	private boolean hasChange = false;
	private Thread monitorThread;
	private boolean stopMonitor = false;
	private MethodLibrary library;
	private Map<MethodPlugin, IMarker> pluginMarkerMap = new HashMap<MethodPlugin, IMarker>();
	
	public LibraryProblemMonitor() {
		super(LibraryResources.libraryProblemMonitor);
		
		LibraryServiceListener libServiceListener = new LibraryServiceListener() {
			public void librarySet(MethodLibrary lib) {
				ILibraryService libService = LibraryService.getInstance();				
				if (library != null && library != lib) {
					ILibraryManager libMgr = libService.getLibraryManager(library);
					if (libMgr != null) {
						libMgr.removeListener(LibraryProblemMonitor.this);
					}
				}
				
				if (lib != null && lib != library) {
					ILibraryManager libMgr = libService.getLibraryManager(lib);
					if (libMgr != null) {
						libMgr.addListener(LibraryProblemMonitor.this);
					}
					kickToRun();
				}
			
				library = lib;
			}
		};
		LibraryService.getInstance().addListener(libServiceListener);
		startMonitor();
	}
	
	public void startMonitor() {
		Runnable runnable = new Runnable() {
			public void run() {
				while (! stopMonitor) {
					try {
						Thread.sleep(delay);
					} catch (Exception e) {
						LibraryPlugin.getDefault().getLogger().logError(e);
						return;
					}
					if (hasChange) {
						hasChange = false;
						guardedSchedule(0L);
					}
				}
			}
		};
		
		stopMonitor = false;
		if (monitorThread == null) {
			monitorThread = new Thread(runnable);
		}
		monitorThread.start();
	}
	
	public void stopMonitor() {
		stopMonitor = true;
	}
	
	
	public void libraryChanged(int option, Collection<Object> changedItems) {
		if (changedItems != null && changedItems.size() > 0) {
			hasChange = true;
			enableToRestart();
		}
	}
	
	// Update will abort and re-schedule a job if new change detected
	private void update()  throws RestartInterruptException {
		if (localDebug) {
			System.out.println("LD> update"); //$NON-NLS-1$
		}
		MethodLibrary lib = getLibrary();
		if (lib == null) {
			return;
		}
		checkRestartInterruptException(restartDelay);		

		cleanUp();
		
		List<MethodPlugin> plugins = new ArrayList<MethodPlugin>();
		plugins.addAll(lib.getMethodPlugins());
		
		Set<MethodPlugin> pluginSet = new HashSet<MethodPlugin>(plugins);
		for (MethodPlugin plugin: plugins) {
			checkRestartInterruptException(restartDelay);
			List<MethodPlugin> baseList = plugin.getBases();
			boolean missing = false;
			for (MethodPlugin base: baseList) {
				checkRestartInterruptException(restartDelay);
				if (! pluginSet.contains(base)) {					
					if (! missing) {
						if (localDebug) {
							System.out.println("LD> plugin: " + plugin); //$NON-NLS-1$
							System.out.println("LD> " + plugin.getName() + " references unresolved bases:"); //$NON-NLS-1$ //$NON-NLS-2$
						}
						missing = true;
					}
					if (localDebug) {
						System.out.println("LD> base: " + base); //$NON-NLS-1$
					}
					addMissingBasePluginError(plugin, base);
				}
			}
			if (missing) {
				System.out.println(""); //$NON-NLS-1$
			}
		}		
		
	}
	
	private void addMissingBasePluginError(MethodPlugin plugin, MethodPlugin base) {
		IMarker marker = pluginMarkerMap.get(plugin);
		if (marker == null) {
			Resource res = plugin.eResource();
			if (res == null) {
				return;
			}
		
			URI containerURI = res.getURI();
			IWorkspace workspace = ResourcesPlugin.getWorkspace();
			IPath path = new Path(containerURI.toFileString());
			IFile file = workspace.getRoot().getFileForLocation(path);
			if (file == null) {
				return;
			}
			String location = containerURI != null ? containerURI
					.toFileString() : ""; //$NON-NLS-1$	
			try {
				marker = file.createMarker(UnresolvedBasedPluginMARKER_ID);
				marker.setAttribute(IMarker.SEVERITY, IMarker.SEVERITY_ERROR);
				marker.setAttribute(Name, plugin.getName());
				marker.setAttribute(Guid, plugin.getGuid());
				marker.setAttribute(IMarker.LOCATION, location);
				marker.setAttribute(Guid, plugin.getGuid());	

			} catch (Exception e) {
				LibraryPlugin.getDefault().getLogger().logError(e);
			}
			if (marker == null) {
				return;
			}
			if (localDebug) {
				System.out.println("LD> marker: " + marker); //$NON-NLS-1$
			}
			pluginMarkerMap.put(plugin, marker);				
		
		}
		
		String unresolvedBaseGuidsValue = null;
		try {

			String errMsg = plugin.getName() + " references unresolved base "; //$NON-NLS-1$
			unresolvedBaseGuidsValue = (String) marker.getAttribute(UnresolvedBaseGuids);
			if (unresolvedBaseGuidsValue == null || unresolvedBaseGuidsValue.length() == 0) {
				unresolvedBaseGuidsValue = base.getGuid();
				errMsg += "plugin: "; //$NON-NLS-1$
			} else if (unresolvedBaseGuidsValue.indexOf(base.getGuid()) < 0) {
				unresolvedBaseGuidsValue += ", " + base.getGuid(); //$NON-NLS-1$
				errMsg += "plugins: "; //$NON-NLS-1$
			}
			errMsg += unresolvedBaseGuidsValue;
			marker.setAttribute(IMarker.MESSAGE, errMsg);
			marker.setAttribute(UnresolvedBaseGuids, unresolvedBaseGuidsValue);
		} catch (Exception e) {
			LibraryPlugin.getDefault().getLogger().logError(e);
		}

	}
	
	protected IStatus restartableRun(IProgressMonitor monitor) throws RestartInterruptException {
		update();
		return Status.OK_STATUS;
	}
	
	protected void resetToRestart() {
		if (localDebug) {
			System.out.println("LD> resetToRestart"); //$NON-NLS-1$
		}
		cleanUp();
	}
	
	private void cleanUp() {
		if (pluginMarkerMap.isEmpty()) {
			return;
		}
		for (IMarker marker: pluginMarkerMap.values()) {
			try {
				marker.delete();
			} catch (Exception e) {
				LibraryPlugin.getDefault().getLogger().logError(e);
			}
		}
		pluginMarkerMap = new HashMap<MethodPlugin, IMarker>();
	}

	public void kickToRun() {
		if (localDebug) {
			System.out.println("LD> kickToRun"); //$NON-NLS-1$
		}
		enableToRestart();
		guardedSchedule(0L);
	}
	
	//To do: allow a cached data to pased and return -> optimize fix of similar problems
	public void fixProblem(IMarker marker) {
		try {
			if (marker.getType() != UnresolvedBasedPluginMARKER_ID) {
				return;
			}
			MethodLibrary lib = getLibrary();
			if (lib == null) {
				return;
			}

			Map<String, MethodPlugin> guidToPluginMap = new HashMap<String, MethodPlugin>();
			for (MethodPlugin plugin : lib.getMethodPlugins()) {
				guidToPluginMap.put(plugin.getGuid(), plugin);
			}
			String guid = (String) marker.getAttribute(Guid); //$NON-NLS-1$

			MethodPlugin plugin = guidToPluginMap.get(guid);
			if (plugin == null || plugin.eResource() == null) {
				return;
			}
			
			if (localDebug) {
				System.out.println("LD> fixProblem, plugin: " + plugin); //$NON-NLS-1$
			}
			
			List<MethodPlugin> bases = new ArrayList<MethodPlugin>();
			bases.addAll(plugin.getBases());

			boolean modified = false;
			for (MethodPlugin base : bases) {
				if (! guidToPluginMap.containsKey(base.getGuid())) {
					modified = true;
					plugin.getBases().remove(base);
				}
			}
			if (! modified) {
				return;
			}
			
			Resource resource = plugin.eResource();
			ILibraryPersister.FailSafeMethodLibraryPersister persister = LibraryServiceUtil
					.getPersisterFor(resource).getFailSafePersister();
			try {
				persister.save(resource);
				persister.commit();
			}
			catch(Exception e) {
				LibraryPlugin.getDefault().getLogger().logError(e);
				persister.rollback();
			}

			kickToRun();
		} catch (Exception e) {
			LibraryPlugin.getDefault().getLogger().logError(e);
		}
	}
	
	public void dispose() {
		stopMonitor();
		cleanUp();
	}

	public MethodLibrary getLibrary() {
		return library;
	}

	public void setLibrary(MethodLibrary library) {
		this.library = library;
	}

}
