/*******************************************************************************
 * Copyright (c) 2001, 2004 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.internal;


import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
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.expressions.Expression;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.QualifiedName;
import org.eclipse.core.runtime.content.IContentDescription;
import org.eclipse.core.runtime.content.IContentType;
import org.eclipse.core.runtime.content.IContentTypeManager;
import org.eclipse.jem.util.logger.proxy.Logger;
import org.eclipse.wst.validation.internal.delegates.ValidatorDelegatesRegistry;
import org.eclipse.wst.validation.internal.operations.IWorkbenchContext;
import org.eclipse.wst.validation.internal.operations.WorkbenchContext;
import org.eclipse.wst.validation.internal.plugin.ValidationHelperRegistryReader;
import org.eclipse.wst.validation.internal.plugin.ValidationPlugin;
import org.eclipse.wst.validation.internal.provisional.core.IValidator;
import org.eclipse.wst.validation.internal.provisional.core.IValidatorJob;
import org.osgi.framework.Bundle;

/**
 * This class stores information, as specified by a validator's plugin.xml tags. There is one
 * ValidatorMetaData for each Validator. No Validator should attempt to access its
 * ValidatorMetaData; it is for use by the base framework only.
 */
public class ValidatorMetaData {
	private ValidatorFilter[] _filters;
	private ValidatorNameFilter[] _projectNatureFilters;
	private String[] facetFilters;
	private IValidator _validator;
	private IWorkbenchContext _helper;
	private String _validatorDisplayName;
	private String _validatorUniqueName;
	private String[] _aggregatedValidators;
    private String[] contentTypeIds = null;
	private String[] _validatorNames;
	private String _pluginId;
	private boolean _supportsIncremental = RegistryConstants.ATT_INCREMENTAL_DEFAULT;
	private boolean _supportsFullBuild = RegistryConstants.ATT_FULLBUILD_DEFAULT;
	private Logger _logger;
	private boolean _isEnabledByDefault = RegistryConstants.ATT_ENABLED_DEFAULT;
	private MigrationMetaData _migrationMetaData;
	private int _ruleGroup = RegistryConstants.ATT_RULE_GROUP_DEFAULT;
	private boolean _async = RegistryConstants.ATT_ASYNC_DEFAULT;
	private boolean dependentValidator = RegistryConstants.DEP_VAL_VALUE_DEFAULT;
	private String[] markerIds;
	private String _helperClassName;
	private IConfigurationElement _helperClassElement;
	private IConfigurationElement _validatorClassElement;
	private boolean _cannotLoad = false;
	private boolean manualValidation = true;
	private boolean buildValidation = true;
	private Map helpers = Collections.synchronizedMap( new HashMap() );
	private Expression enablementExpression;

	ValidatorMetaData() {
		//default
	}

	/**
	 * Add to the list of class names of every validator which this validator aggregates. For
	 * example, if the EJB Validator instantiated another validator, and started its validate
	 * method, then that instantiated class' name should be in this list.
	 */
	void addAggregatedValidatorNames(String[] val) {
		_aggregatedValidators = val;
	}

	/**
	 * Add the name/type filter pair(s).
	 */
	void addFilters(ValidatorFilter[] filters) {
		_filters = filters;
	}

	/**
	 * Add the project nature filter(s).
	 */
	void addProjectNatureFilters(ValidatorNameFilter[] filters) {
		_projectNatureFilters = filters;
	}
	
	/**
	 * Add the facet  filter(s).
	 */
	protected void addFacetFilters(String[] filters) {
		facetFilters = filters;
	}
	
	protected String[] getFacetFilters() {
		return facetFilters;
	}

	public List getNameFilters() {
		List nameFilters = new ArrayList();
		if (_filters != null && _filters.length > 0) {
			for (int i = 0; i < _filters.length; i++) {
				ValidatorFilter filter = _filters[i];
				ValidatorNameFilter nameFilter = filter.get_nameFilter();
				if (nameFilter != null) {
					nameFilters.add(nameFilter.getNameFilter());
				}

			}
		}
		return nameFilters;
	}

	/**
	 * Return the list of class names of the primary validator and its aggregates.
	 */
	public String[] getValidatorNames() {
		if (_validatorNames == null) {
			int aLength = (_aggregatedValidators == null) ? 0 : _aggregatedValidators.length;
			_validatorNames = new String[aLength + 1]; // add 1 for the primary validator name
			_validatorNames[0] = getValidatorUniqueName();
			if (_aggregatedValidators != null) {
				System.arraycopy(_aggregatedValidators, 0, _validatorNames, 1, aLength);
			}
		}
		return _validatorNames;
	}

	/**
	 * Return the list of class names of every validator which this validator aggregates. For
	 * example, if the EJB Validator instantiated another validator, and started its validate
	 * method, then that instantiated class' name should be in this list.
	 */
	public String[] getAggregatedValidatorNames() {
		return _aggregatedValidators;
	}

	/**
	 * Return the name/type filter pairs.
	 */
	public ValidatorFilter[] getFilters() {
		return _filters;
	}

	/**
	 * Return true if this vmd's helper and validator have been instantiated, and also if this
	 * validator's plugin is active.
	 */
	public boolean isActive() {
		if (_helperClassElement != null) {
			return false;
		}

		if (_validatorClassElement != null) {
			return false;
		}

		Bundle bundle = Platform.getBundle(_pluginId);
		if (bundle != null)
			return bundle.getState() == Bundle.ACTIVE;

		return false;
	}

	/**
	 * This method will throw an InstantiationException if the helper cannot be instantiated, e.g.,
	 * if the helper's plugin is disabled for some reason. Before the InstantiationException is
	 * thrown, this validator will be disabled.
	 * 
	 * The IWorkbenchContext must ALWAYS have its project set before it is used; but it can't be
	 * created with the IProject. So, before using the single instance, always initialize that
	 * instance with the IProject.
	 * 
	 * If this validator supports asynchronous validation, then instead of maintaining a single the
	 * helper instance, create a new IWorkbenchContext instance every time that the helper is needed.
	 * This feature is provided because several validation Runnables may be queued to run, and if
	 * those Runnables's project is different from the current validation's project, then the
	 * current validation will suddenly start validating another project.
	 */
	//TODO just want to remember to figure out the many-temporary-objects problem if this method
	// continues to new an IValidationContext every time - Ruth
	public IWorkbenchContext getHelper(IProject project) throws InstantiationException {
		if (_helper == null) {
			_helper = ValidationRegistryReader.createHelper(_helperClassElement, _helperClassName);
			if (_helper == null) {
				_helper = new WorkbenchContext();
				//setCannotLoad();
				//throw new InstantiationException(ResourceHandler.getExternalizedMessage(ResourceConstants.VBF_EXC_DISABLEH, new String[]{_helperClassName, getValidatorUniqueName()}));
			}
			// Won't be using the element & name again, so clear them.
			//_helperClassElement = null;
			//_helperClassName = null;
		}
		if ((_helper.getProject() == null) || !(_helper.getProject().equals(project))) {
			// Initialize helper with the new project
			_helper.setProject(project);
		}
		return _helper;
	}

	/**
	 * cannotLoad is false if both the IValidator and IWorkbenchContext instance can be instantiated.
	 * This method should be called only by the validation framework, and only if an
	 * InstantiationException was thrown.
	 * 
	 * @param can
	 */
	private void setCannotLoad() {
		_cannotLoad = true;
	}

	/**
	 * Return false if both the IValidator and IWorkbenchContext instance can be instantiated.
	 * 
	 * @return boolean
	 */
	public boolean cannotLoad() {
		return _cannotLoad;
	}

	/**
	 * This method must not be called until the unique id of the validator has been initialized.
	 */
	public Logger getMsgLogger() {
		if (_logger == null) {
			_logger = ValidationPlugin.getPlugin().getMsgLogger();
			/*
			 * // Decided against having a logger for each validator because each validator // would
			 * need to contribute an extension in their plugins for it to be recognized // by the
			 * logging preference page. For now, just use the validation framework's logger. _logger =
			 * (MsgLogger)MsgLogger.getFactory().getLogger(getValidatorUniqueName());
			 * _logger.write(Level.CONFIG, getValidatorDisplayName());
			 */
		}
		return _logger;
	}

	public MigrationMetaData getMigrationMetaData() {
		return _migrationMetaData;
	}

	/**
	 * Return the IRuleGroup integer indicating which groups of rules this validator recognizes.
	 */
	public int getRuleGroup() {
		return _ruleGroup;
	}

	/**
	 * Return the filters which identify which project(s) this validator may run on.
	 */
	ValidatorNameFilter[] getProjectNatureFilters() {
		return _projectNatureFilters;
	}

	/**
	 * This method returns the validator if it can be loaded; if the validator cannot be loaded,
	 * e.g., if its plugin is disabled for some reason, then this method throws an
	 * InstantiationException. Before the CoreException is thrown, this validator is disabled.
	 * 
	 * @return IValidator
	 * @throws InstantiationException
	 */
	public IValidator getValidator() throws InstantiationException {
		if (_validator == null) {
			_validator = ValidationRegistryReader.createValidator(_validatorClassElement, getValidatorUniqueName());

			// Since the element won't be used any more, clear it.
			//_validatorClassElement = null;

			if (_validator == null) {
				setCannotLoad();
				throw new InstantiationException(ResourceHandler.getExternalizedMessage(ResourceConstants.VBF_EXC_DISABLEV, new String[]{getValidatorUniqueName()}));
			}
		}
		return _validator;
	}

	public String getValidatorDisplayName() {
		return _validatorDisplayName;
	}

	public String getValidatorUniqueName() {
		return _validatorUniqueName;
	}

	/**
	 * If the resource is applicable to the Validator which this ValidatorMetaData is associated
	 * with, return true; else return false.
	 * 
	 * A resource is applicable if it passes the name/type filters. This method is called if there
	 * is no resource delta (i.e., a full validation).
	 */
	public boolean isApplicableTo(IResource resource) {
		return isApplicableTo(resource, ValidatorActionFilter.ALL_ACTIONS);
	}

	/**
	 * If the resource is applicable to the Validator which this ValidatorMetaData is associated
	 * with, return true; else return false.
	 * 
	 * A resource is applicable if it passes the name/type filters.
	 */
	public boolean isApplicableTo(IResource resource, int resourceDelta) {
		// If no filters are specified, then every type of resource should be validated/trigger a
		// rebuild of the model cache
		if (_filters == null)
			return true;

		return isApplicableTo(resource, resourceDelta, _filters);
	}

	/**
	 * Return true if the resource passes the name/type filters for this validator.
	 */
	boolean isApplicableTo(IResource resource, int resourceDelta,
			ValidatorFilter[] filters) {
		// Are any of the filters satisfied? (i.e., OR them, not AND them.)
		if (checkIfValidSourceFile(resource)) {
			for (int i = 0; i < filters.length; i++) {
				ValidatorFilter filter = filters[i];
				if (filter.isApplicableType(resource)
						&& filter.isApplicableName(resource)
						&& filter.isApplicableAction(resourceDelta)) {
					return true;
				}

			}
		}
		if (getContentTypeIds() != null) {
			IContentDescription description = null;
			try {
				if (resource.getType() == IResource.FILE)
					description = ((IFile) resource).getContentDescription();
			} catch (CoreException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			if (description == null)
				return false;
			if (isApplicableContentType(description))
				return true;
		}
		return false;
	}

	private boolean checkIfValidSourceFile(IResource file) {
		if (file.getType() == IResource.FILE) {
			IProjectValidationHelper helper = ValidationHelperRegistryReader.getInstance().getValidationHelper();
			IProject project = file.getProject();
			if (helper == null || project == null)
				return true;
			IContainer[] outputContainers = helper.getOutputContainers(project);
			IContainer[] sourceContainers = helper.getSourceContainers(project);
			for (int i=0; i<outputContainers.length; i++) {
				String outputPath = outputContainers[i].getProjectRelativePath().makeAbsolute().toString();
                String filePath = file.getProjectRelativePath().makeAbsolute().toString();
				if (filePath.startsWith(outputPath)) {
					//The file is in an output container.
					//If it is a source container return true and false otherwise.
					for (int j=0;j<sourceContainers.length; j++) {
	                    if(outputContainers[i].equals(sourceContainers[j])){
	                    	return true;
	                    }
						return false;
					}
				}
			}
		}
		return true;
	}
		
		
	/**
	 * If this validator recognizes the project nature, whether included or excluded, return the
	 * name filter which describes the nature. Otherwise return null.
	 */
	ValidatorNameFilter findProjectNature(String projId) {
		if (projId == null) {
			return null;
		}

		if (_projectNatureFilters == null) {
			// If no tag is specified, this validator is configured on all IProjects
			return null;
		}

		for (int i = 0; i < _projectNatureFilters.length; i++) {
			ValidatorNameFilter filter = _projectNatureFilters[i];
			// In this case, we're not checking if the project is an instance of the filter class,
			// but if it has the Nature specified in the filter class.
			String projectNatureID = filter.getNameFilter();
			if (projId.equals(projectNatureID)) {
				return filter;
			}
		}
		return null;
	}

	/**
	 * Convenience method. Rather than store the is-this-vmd-configured-on-this-IProject algorithm
	 * in two places, refer back to the reader's cache.
	 */
	public boolean isConfiguredOnProject(IProject project) {
		return ValidationRegistryReader.getReader().isConfiguredOnProject(this, project);
	}

	public boolean isEnabledByDefault() {
		return _isEnabledByDefault;
	}

	public boolean isIncremental() {
		return _supportsIncremental;
	}

	public boolean isFullBuild() {
		return _supportsFullBuild;
	}

	/**
	 * Return true if the validator is thread-safe and can be run asynchronously.
	 */
	public boolean isAsync() {
		return _async;
	}

	void setHelperClass(IConfigurationElement element, String helperClassName) {
		_helperClassElement = element;
		_helperClassName = helperClassName;
	}

	void setEnabledByDefault(boolean enabledByDefault) {
		_isEnabledByDefault = enabledByDefault;
	}

	void setIncremental(boolean isIncremental) {
		_supportsIncremental = isIncremental;
	}

	void setFullBuild(boolean fullBuild) {
		_supportsFullBuild = fullBuild;
	}

	void setAsync(boolean isAsync) {
		_async = isAsync;
	}

	void setMigrationMetaData(MigrationMetaData mmd) {
		_migrationMetaData = mmd;
	}

	void setRuleGroup(int ruleGroup) {
		_ruleGroup = ruleGroup;
	}

	void setValidatorClass(IConfigurationElement element) {
		_validatorClassElement = element;
		// validator class name == validatorUniqueName
	}

	void setValidatorDisplayName(String validatorName) {
		_validatorDisplayName = validatorName;
	}

	void setValidatorUniqueName(String validatorUniqueName) {
		_validatorUniqueName = validatorUniqueName;
	}

	void setPluginId(String validatorPluginId) {
		_pluginId = validatorPluginId;
	}

	public String toString() {
		return getValidatorUniqueName();
	}

	public class MigrationMetaData {
		private Set _ids = null;

		public MigrationMetaData() {
			//default
		}

		public void addId(String oldId, String newId) {
			if (oldId == null) {
				// log
				return;
			}

			if (newId == null) {
				// log
				return;
			}

			String[] ids = new String[]{oldId, newId};
			getIds().add(ids);
		}

		public Set getIds() {
			if (_ids == null) {
				_ids = new HashSet();
			}
			return _ids;
		}
	}

	/**
	 * @param b
	 */
	public void addDependentValidator(boolean b) {
		dependentValidator = b;
	}

	/**
	 * @param b
	 */
	public boolean isDependentValidator() {
		return dependentValidator;
	}

	/**
	 * @return Returns the markerId.
	 */
	public String[] getMarkerIds() {
		return markerIds;
	}

	/**
	 * @param markerId
	 *            The markerId to set.
	 */
	public void setMarkerIds(String[] markerId) {
		this.markerIds = markerId;
	}

	public boolean isBuildValidation() {
		return buildValidation;
	}

	public void setBuildValidation(boolean buildValidation) {
		this.buildValidation = buildValidation;
	}

	public boolean isManualValidation() {
		return manualValidation;
	}

	public void setManualValidation(boolean manualValidation) {
		this.manualValidation = manualValidation;
	}
  
	/**
   * Determines if the validator described by this metadata object is a delegating validator. 
   * @return true if the validator described by this metadata object is a delegating validator, false otherwise.
	 */
  public boolean isDelegating() {
    String targetID = getValidatorUniqueName();
    return ValidatorDelegatesRegistry.getInstance().hasDelegates(targetID);
  }
  

	public IValidator createValidator() throws InstantiationException {
		return  ValidationRegistryReader.createValidator(_validatorClassElement, getValidatorUniqueName());
	}
	
	public IWorkbenchContext createHelper(IProject project) throws InstantiationException {
		IWorkbenchContext helper = ValidationRegistryReader.createHelper(_helperClassElement, _helperClassName);
		if (helper == null) {
			helper = new WorkbenchContext();
		}
		helper.setProject(project);
		return helper;
	}	  
	
   public void addHelper( IValidatorJob validator, IWorkbenchContext helper ){
	   helpers.put( validator, helper );
   }
   
   public void removeHelper( IValidatorJob validator ){
	   helpers.remove( validator );
   }
   
   private IWorkbenchContext getHelper( IValidatorJob validator ){
	   return (IWorkbenchContext)helpers.get( validator );
   }   
   
   public IWorkbenchContext getHelper( IProject project, IValidator validator ){
	   
	   if( validator instanceof IValidatorJob ){
		   IWorkbenchContext helper = getHelper( (IValidatorJob)validator );
		   if( helper == null ){
			   try{
				helper =  getHelper( project );
				return helper;
			   }catch (InstantiationException e) {
					e.printStackTrace();
				}			   
		   }
	   	return helper;
	   }
	   else{
		   try {
			IWorkbenchContext helper =  getHelper( project );
			return helper;
			} catch (InstantiationException e) {
				e.printStackTrace();
			}
	   }
	   
	   return null;
   }   
   
   public Expression getEnablementExpresion() {
		return enablementExpression;
	}

   public void setEnablementElement(Expression enablementElement) {
	 enablementExpression = enablementElement;
	}

public String[] getContentTypeIds() {
	return contentTypeIds;
}

public void setContentTypeIds(String[] contentTypeIds) {
	this.contentTypeIds = contentTypeIds;
}

 
private boolean isApplicableContentType(IContentDescription desc){
	
	IContentType ct = desc.getContentType();
	String[] applicableContentTypes = getContentTypeIds();
	if (applicableContentTypes != null) {
		for (int i = 0; i < applicableContentTypes.length; i ++){
			if(applicableContentTypes[i].equals(ct.getId()))
				return true;
		}
	}
	return false;
}
   
}