/*******************************************************************************
 * 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.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.Platform;
import org.eclipse.jem.util.logger.proxy.Logger;
import org.eclipse.wst.validation.internal.operations.IWorkbenchContext;
import org.eclipse.wst.validation.internal.plugin.ValidationPlugin;
import org.eclipse.wst.validation.internal.provisional.core.IValidator;
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 = null;
	private ValidatorNameFilter[] _projectNatureFilters = null;
	private IValidator _validator = null;
	private IWorkbenchContext _helper = null;
	private String _validatorDisplayName = null;
	private String _validatorUniqueName = null;
	private String[] _aggregatedValidators = null;
	private String[] _validatorNames = null;
	private String _pluginId = null;
	private boolean _supportsIncremental = RegistryConstants.ATT_INCREMENTAL_DEFAULT;
	private boolean _supportsFullBuild = RegistryConstants.ATT_FULLBUILD_DEFAULT;
	private Logger _logger = null;
	private boolean _isEnabledByDefault = RegistryConstants.ATT_ENABLED_DEFAULT;
	private MigrationMetaData _migrationMetaData = null;
	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 markerId = null;
	private String _helperClassName = null;
	private IConfigurationElement _helperClassElement = null;
	private IConfigurationElement _validatorClassElement = null;
	private boolean _cannotLoad = false;

	/* package */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.
	 */
	/* package */void addAggregatedValidatorNames(String[] val) {
		_aggregatedValidators = val;
	}

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

	/**
	 * Add the project nature filter(s).
	 */
	/* package */void addProjectNatureFilters(ValidatorNameFilter[] filters) {
		_projectNatureFilters = filters;
	}

	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 (isAsync()) {
			IWorkbenchContext helper = ValidationRegistryReader.createHelper(_helperClassElement, _helperClassName);
			if (helper == null) {
				setCannotLoad();
				throw new InstantiationException(ResourceHandler.getExternalizedMessage(ResourceConstants.VBF_EXC_DISABLEH, new String[]{_helperClassName, getValidatorUniqueName()}));
			}
			helper.setProject(project);
			return helper;
		}
		if (_helper == null) {
			_helper = ValidationRegistryReader.createHelper(_helperClassElement, _helperClassName);
			if (_helper == null) {
				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.
	 */
	/* package */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.
	 */
	/* package */boolean isApplicableTo(IResource resource, int resourceDelta, ValidatorFilter[] filters) {
		// Are any of the filters satisfied? (i.e., OR them, not AND them.)
		for (int i = 0; i < filters.length; i++) {
			ValidatorFilter filter = filters[i];
			if (filter.isApplicableType(resource) && filter.isApplicableName(resource) && filter.isApplicableAction(resourceDelta)) {
				return true;
			}
		}
		return false;
	}

	/**
	 * 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;
	}

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

	/* package */void setEnabledByDefault(boolean enabledByDefault) {
		_isEnabledByDefault = enabledByDefault;
	}

	/* package */void setIncremental(boolean isIncremental) {
		_supportsIncremental = isIncremental;
	}

	/* package */void setFullBuild(boolean fullBuild) {
		_supportsFullBuild = fullBuild;
	}

	/* package */void setAsync(boolean isAsync) {
		_async = isAsync;
	}

	/* package */void setMigrationMetaData(MigrationMetaData mmd) {
		_migrationMetaData = mmd;
	}

	/* package */void setRuleGroup(int ruleGroup) {
		_ruleGroup = ruleGroup;
	}

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

	/* package */void setValidatorDisplayName(String validatorName) {
		_validatorDisplayName = validatorName;
	}

	/* package */void setValidatorUniqueName(String validatorUniqueName) {
		_validatorUniqueName = validatorUniqueName;
	}

	/* package */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 getMarkerId() {
		return markerId;
	}

	/**
	 * @param markerId
	 *            The markerId to set.
	 */
	public void setMarkerId(String markerId) {
		this.markerId = markerId;
	}
}