/*******************************************************************************
 * Copyright (c) 2007, 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 API and implementation
 *******************************************************************************/
package org.eclipse.wst.validation;

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

import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceVisitor;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.core.runtime.preferences.IEclipsePreferences;
import org.eclipse.core.runtime.preferences.InstanceScope;
import org.eclipse.wst.validation.internal.DebugConstants;
import org.eclipse.wst.validation.internal.DependencyIndex;
import org.eclipse.wst.validation.internal.MarkerManager;
import org.eclipse.wst.validation.internal.Misc;
import org.eclipse.wst.validation.internal.PerformanceMonitor;
import org.eclipse.wst.validation.internal.ValManager;
import org.eclipse.wst.validation.internal.ValOperation;
import org.eclipse.wst.validation.internal.ValidationRunner;
import org.eclipse.wst.validation.internal.operations.ValidationBuilder;
import org.eclipse.wst.validation.internal.operations.WorkbenchReporter;
import org.eclipse.wst.validation.internal.plugin.ValidationPlugin;
import org.eclipse.wst.validation.internal.provisional.core.IReporter;


/**
 * The central class of the Validation Framework.
 * <p>
 * This is a singleton class that is accessed through the getDefault() method. 
 * @author karasiuk
 *
 */
public final class ValidationFramework {
	
	private IDependencyIndex 			_dependencyIndex;
	private IPerformanceMonitor			_performanceMonitor;
	
	private Set<IProject> 				_suspendedProjects;
	private boolean 					_suspendAllValidation;

	private static ValidationFramework 	_me;
	
	/** 
	 * Answer the singleton, default instance of this class.
	 */
	public static ValidationFramework getDefault(){
		if (_me == null)_me = new ValidationFramework();
		return _me;
	}
	
	private ValidationFramework(){}
	
	/**
	 * Clear any validation markers that may have been set by this validator.
	 *  
	 * @param resource the resource that may have it's markers cleared
	 * @param validatorId the id of validator that created the marker
	 */
	public void clearMessages(IResource resource, String validatorId) throws CoreException {
		MarkerManager.getDefault().clearMarker(resource, validatorId);
	}
	
	/**
	 * Answer the dependency index. Validators can use this to determine which resources depend on which
	 * other resources.
	 */
	public IDependencyIndex getDependencyIndex(){
		if (_dependencyIndex != null)return _dependencyIndex;
		return getDependencyIndex2();
	}

	private synchronized IDependencyIndex getDependencyIndex2() {
		if (_dependencyIndex == null)_dependencyIndex = new DependencyIndex();
		return _dependencyIndex;
	}
	
	public synchronized IPerformanceMonitor getPerformanceMonitor(){
		if (_performanceMonitor == null){
			boolean traceTimes = Misc.debugOptionAsBoolean(DebugConstants.TraceTimes);
			String traceFile = Platform.getDebugOption(DebugConstants.TraceTimesFile);

			_performanceMonitor = PerformanceMonitor.create(traceTimes, traceFile);
		}
		return _performanceMonitor;
	}
	
	/**
	 * Answer the preference store that holds the global validation settings.
	 */
	public IEclipsePreferences getPreferenceStore(){
		return new InstanceScope().getNode(ValidationPlugin.PLUGIN_ID);
	}
	
	public IReporter getReporter(IProject project, IProgressMonitor monitor){
		return new WorkbenchReporter(project, monitor);
	}
	
	/**
	 * Answer all the validators that are applicable for the given resource, even if the
	 * validator has been turned off by the user.
	 * <p>
	 * The caller may still need to test if the validator has been turned off by the
	 * user, by using the isBuildValidation() and isManualValidation() methods.
	 * </p>
	 * @param resource the resource that determines which validators are applicable.
	 * 
	 * @param isManual if true then the validator must be turned on for manual validation. 
	 * If false then the isManualValidation setting isn't used to filter out validators.
	 *   
	 * @param isBuild if true then the validator must be turned on for build based validation.
	 * If false then the isBuildValidation setting isn't used to filter out validators.  
	 * 
	 * @see Validator#isBuildValidation()
	 * @see Validator#isManualValidation()
	 */
	public Validator[] getValidatorsFor(IResource resource, boolean isManual, boolean isBuild){
		IProject project = resource.getProject();
		List<Validator> list = new LinkedList<Validator>();
		for (Validator val : ValManager.getDefault().getValidators(project)){
			if (val.shouldValidate(resource, isManual, isBuild))list.add(val);
		}
		
		Validator[] result = new Validator[list.size()];
		list.toArray(result);
		return result;
	}
	
	/**
	 * Answer all the validators that should not validate the resource, either because
	 * their filters don't support the resource, or the validator has been disabled for
	 * both build validation and manual validation.
	 * @param resource
	 */
	public Set<Validator> getDisabledValidatorsFor(IResource resource){
		IProject project = resource.getProject();
		Set<Validator> set = new HashSet<Validator>(10);
		for (Validator val : ValManager.getDefault().getValidators(project)){
			boolean validateIt = false;
			if (val.shouldValidate(resource, false, false)){
				validateIt = val.isBuildValidation() || val.isManualValidation();
			}
			if (!validateIt)set.add(val);
		}
		return set;
	}
	
	/**
	 * Answer the global validator with the given id.
	 * 
	 * @deprecated Use getValidator(String id, IProject project) with a null project instead.
	 * 
	 * @param id
	 * @return null if the validator is not found
	 */
	public Validator getValidator(String id){
		return ValManager.getDefault().getValidatorWithId(id, null);
	}
	
	/**
	 * Answer the validator with the given id that is in effect for the given project.
	 * <p>
	 * Individual projects may override the global validation preference settings. If this is allowed and if
	 * the project has it's own settings, then those validators are returned via this method.
	 * </p>
	 * <p>
	 * The following approach is used. For version 1 validators, the validator is only returned if it
	 * is defined to operate on this project type. This is the way that the previous version of the framework
	 * did it. For version 2 validators, they are all returned.
	 * </p>
	 * 
	 * @param id validator id.
	 * @param project this can be null, in which case all the registered validators are checked.
	 * @return null if the validator is not found
	 */
	public Validator getValidator(String id, IProject project){
		return ValManager.getDefault().getValidatorWithId(id, project);
	}
	
	/**
	 * Answer all the validators that are applicable for the given resource.
	 * 
	 * @param resource the resource that determines which validators are applicable.
	 */
	public Validator[] getValidatorsFor(IResource resource){
		List<Validator> list = new LinkedList<Validator>();
		for (Validator v : getValidatorsFor(resource, false, false)){
			if (v.isBuildValidation() || v.isManualValidation())list.add(v);
		}
		Validator[] vals = new Validator[list.size()];
		return list.toArray(vals);
	}
	
	/**
	 * Answer true if the resource has any enabled validators.
	 * 
	 * @param resource a file, folder or project.
	 * 
	 * @param isManual if true then the validator must be turned on for manual validation. 
	 * If false then the isManualValidation setting isn't used to filter out validators.
	 *   
	 * @param isBuild if true then the validator must be turned on for build based validation.
	 * If false then the isBuildValidation setting isn't used to filter out validators.  
	 */
	public boolean hasValidators(IResource resource, boolean isManual, boolean isBuild){
		return ValManager.getDefault().hasValidators(resource, isManual, isBuild);
	}
	
	/**
	 * Waits until all validation jobs are finished.  This method will block the 
	 * calling thread until all such jobs have finished executing, or until this thread is
	 * interrupted.   If there are no validation jobs in 
	 * that are currently waiting, running, or sleeping, this method returns 
	 * immediately.  Feedback on how the join is progressing is provided to a progress monitor.
	 * <p>
	 * If this method is called while the job manager is suspended, only jobs
	 * that are currently running will be joined; Once there are no jobs
	 * in the family in the {@link Job#RUNNING} state, this method returns.
	 * </p>
	 * <p>
	 * Note that there is a deadlock risk when using join.  If the calling thread owns
	 * a lock or object monitor that the joined thread is waiting for, deadlock 
	 * will occur. This method can also result in starvation of the current thread if
	 * another thread continues to add jobs of the given family, or if a
	 * job in the given family reschedules itself in an infinite loop.
	 * </p>
	 * 
	 * @param monitor Progress monitor for reporting progress on how the
	 * wait is progressing, or <code>null</code> if no progress monitoring is required.
	 * @exception InterruptedException if this thread is interrupted while waiting
	 * @exception OperationCanceledException if the progress monitor is canceled while waiting
	 */
	public void join(IProgressMonitor monitor) throws InterruptedException, OperationCanceledException {
		Job.getJobManager().join(ResourcesPlugin.FAMILY_AUTO_BUILD, monitor);
		Job.getJobManager().join(ValidationBuilder.FAMILY_VALIDATION_JOB, monitor);
	}
	
	/**
	 * Suspends, or undoes the suspension of, validation on the current project. If "suspend" is
	 * true then validation is suspended and if it's "false" then validation is not suspended on the
	 * project. The value of this variable is not persisted.
	 * <p>
	 * Be VERY CAREFUL when you use this method! Turn validation back on in a finally block because
	 * if the code which suspended validation crashes, the user has no way to reset the suspension.
	 * The user will have to shut down and restart the workbench to get validation to work again.
	 * </p>
	 * @param project the project that is to be suspended or unsuspended.
	 * @param suspend if true validation on the project will be suspend. If false it will not be suspended.
	 */
	public void suspendValidation(IProject project, boolean suspend) {
		if (project == null)return;
		if (suspend)getSuspendedProjects().add(project);
		else getSuspendedProjects().remove(project);
	}
	
	private synchronized Set<IProject> getSuspendedProjects(){
		if (_suspendedProjects == null)_suspendedProjects = Collections.synchronizedSet(new HashSet<IProject>(20));
		return _suspendedProjects;
	}

	/**
	 * Suspends, or undoes the suspension of, validation on all projects in the workbench. If
	 * "suspend" is true then validation is suspended and if it's "false" then validation is not suspended.
	 * The value of this variable is not persisted.
	 * <p>
	 * Be VERY CAREFUL when you use this method! Turn validation back on in a finally block because
	 * if the code which suspended validation crashes, the user has no way to reset the suspension.
	 * The user will have to shut down and restart the workbench to get validation to work again.
	 */
	public void suspendAllValidation(boolean suspend) {
		_suspendAllValidation = suspend;
	}

	/**
	 * Return true if "suspend all" is enabled, false otherwise.
	 */
	public boolean isSuspended() {
		return _suspendAllValidation;
	}

	/**
	 * Returns true if validation will not run on the project because it's been suspended. This
	 * method checks only the suspension status; if validation cannot run for some other reason (for
	 * example, there are no enabled validators), yet the IProject is not suspended, this method
	 * will return true even though validation will not run.
	 */
	public boolean isSuspended(IProject project) {
		if (_suspendAllValidation)return true;
		if (project == null)return false;
		return getSuspendedProjects().contains(project);
	}

	/**
	 * This method should be called by any code that is preparing to suspend validation on a
	 * project. Rather than calling isSuspended(IProject), which will also return true if all validation
	 * has been suspended. 
	 * 
	 * @param project the project that is being tested
	 * @return boolean true if the project has been suspended
	 */
	public boolean isProjectSuspended(IProject project) {
		if (project == null)return false;
		return getSuspendedProjects().contains(project);
	}
	
	/**
	 * Validate the projects.
	 * 
	 * @param projects
	 *            The projects to be validated.
	 * 
	 * @param isManual
	 *            Is this being done as part of a manual validation? i.e. did
	 *            the user select the Validate menu item?
	 * 
	 * @param isBuild
	 *            Is this being done as part of a build?
	 * 
	 * @param monitor
	 * 
	 * @return the validation result which is the combined result for all the
	 *         resources that were validated.
	 */
	public ValidationResults validate(IProject[] projects, final boolean isManual, final boolean isBuild,
		IProgressMonitor monitor) throws CoreException{
		ValOperation vo = ValidationRunner.validate(createMap(projects), isManual, isBuild, monitor);
		return vo.getResults();
	}
	
	/**
	 * Answer all the resources in the projects as a map.
	 * @param projects
	 */
	private Map<IProject, Set<IResource>> createMap(IProject[] projects) throws CoreException{
		final HashMap<IProject, Set<IResource>> map = new HashMap<IProject, Set<IResource>>(1000);
			
		for (IProject p : projects){
			Set<IResource> set = new HashSet<IResource>(1000);
			ResourceAdder ra = new ResourceAdder(set);
			p.accept(ra);
			map.put(p, set);
		}
		return map;
	}
	
	public static class ResourceAdder implements IResourceVisitor {
		
		private Set<IResource> _set;
		
		/**
		 * A class that knows how to add resources to a set.
		 * @param set the set where the resources are added.
		 */
		public ResourceAdder(Set<IResource> set){
			_set = set;
		}

		public boolean visit(IResource resource) throws CoreException {
			_set.add(resource);
			return true;
		}
		
	}

}
