//------------------------------------------------------------------------------
// 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() + " " + LibraryResources.references_unresolved_base_txt; //$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;
	}

}
