/*******************************************************************************
 * Copyright (c) 2001, 2005 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.jst.j2ee.model.internal.validation;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.logging.Level;

import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.jobs.ISchedulingRule;
import org.eclipse.jem.java.JavaClass;
import org.eclipse.jem.util.logger.LogEntry;
import org.eclipse.jem.util.logger.proxy.Logger;
import org.eclipse.jst.j2ee.ejb.EJBJar;
import org.eclipse.jst.j2ee.ejb.EnterpriseBean;
import org.eclipse.jst.j2ee.ejb.Entity;
import org.eclipse.jst.j2ee.internal.J2EEConstants;
import org.eclipse.wst.validation.internal.core.ValidationException;
import org.eclipse.wst.validation.internal.provisional.core.IMessage;
import org.eclipse.wst.validation.internal.provisional.core.IReporter;
import org.eclipse.wst.validation.internal.provisional.core.IValidationContext;

/**
 * @version 	1.0
 * @author
 */
public class EJBValidator extends AbstractEJBValidator {
	private static EJBValidator _inst = null;
	private static TargetObjectPool _targetObjectPoolSingleton = null;
	private LogEntry logEntry = null;
	
	
	public EJBValidator() {
		_inst = this;
	}
	
	public static EJBValidator getValidator() {
		return _inst;
	}
	
	private LogEntry getLogEntry(){
	    if(logEntry == null)
	        logEntry = new LogEntry(IEJBValidatorConstants.BUNDLE_NAME);
	    return logEntry;
	}
	
	public String getBaseName() {
		return "ejbvalidator"; //$NON-NLS-1$
	}

	public void commonValidate(IValidationContext helper, IReporter reporter) throws ValidationException {
		long start = System.currentTimeMillis();
		Logger logger = Logger.getLogger(IEJBValidatorConstants.J2EE_CORE_PLUGIN);
		if (logger != null && logger.isLoggingLevel(Level.FINER)) {
			long end = System.currentTimeMillis();
			LogEntry entry = getLogEntry();
			entry.setSourceID("EJBValidator::validate"); //$NON-NLS-1$
			entry.setText("validate took " + (end - start) + " milliseconds."); //$NON-NLS-1$  //$NON-NLS-2$
			logger.write(Level.FINER, entry);
		}
		try {
			EJBValidationContext vc = new EJBValidationContext(this, helper, reporter);
			setValidationContext(vc);
			if (isFullValidate(vc)) {
				fullValidate(vc);
			} else {
				incrementalValidate(vc);
			}
			if (logger != null && logger.isLoggingLevel(Level.FINER)) {
				long end = System.currentTimeMillis();
				LogEntry entry = getLogEntry();
				entry.setSourceID("EJBValidator::validate"); //$NON-NLS-1$
				entry.setText("validate took " + (end - start) + " milliseconds."); //$NON-NLS-1$  //$NON-NLS-2$
				logger.write(Level.FINER, entry);
			}
		} finally {
			if (ValidationRuleUtility.helperMap != null) {
				ValidationRuleUtility.helperMap.clear();
				ValidationRuleUtility.helperMap = null;
			}
		}
	}	
	
	
	public void validate(IValidationContext helper, IReporter reporter) throws ValidationException {
		commonValidate(helper, reporter);
	}
	/*
	 * @see IValidator#validate(IValidationContext, IReporter, IFileDelta[])
	 */
	public IStatus validateInJob(IValidationContext helper, IReporter reporter) throws ValidationException {
		commonValidate(helper, reporter);
		return status;
	}
	
	public boolean isFullValidate(IEJBValidationContext vc) {
		String[] fileURIs = vc.getURIs();
		if(fileURIs == null) {
			return true;
		}
		if(fileURIs.length == 0) {
			return true;
		}
		
		for(int i=0; i<fileURIs.length; i++) {
			String uri = fileURIs[i];
			if(uri.endsWith(J2EEConstants.EJBJAR_DD_SHORT_NAME)) {
				return true;
			}
		}
		
		return false;
	}
	
	public void runDependents(IEJBValidationContext vc, IValidationRule rule, Object targetParent, Object target) throws ValidationException {
		// If a class is being run only because it depends on a rule which has changed,
		// i.e., it's a dependent, then we don't want to run its dependents because the
		// class itself hasn't changed.
		Set dependents = rule.getDependents();
		if(dependents == null) {
			return;
		}
		
		Iterator iterator = dependents.iterator();
		while(iterator.hasNext()) {
			try {
				IValidationRule dRule = (IValidationRule)iterator.next();
				Object dRuleTarget = dRule.getTarget(targetParent, target);
				if(dRuleTarget != null) {
					run(dRule, targetParent, dRuleTarget); // false=not full validation
				}
			}
			catch(ValidationCancelledException e) {
				throw e;
			}
			catch(ValidationException e) {
				throw e;
			}
			catch(Throwable exc) {
				addInternalErrorMessage(getValidationContext(), exc);
			}
			finally {
				EJBValidationRuleFactory.getFactory().release(rule);
			}
		}
	}
	
	protected String internalErrorMessage() {
		return IEJBValidatorMessageConstants.CHKJ2900;
	}
	
	
	
	protected void logMissingRule(IEJBValidationContext vc, Object ruleId) {
		Logger logger = vc.getMsgLogger();
		if (logger != null && logger.isLoggingLevel(Level.SEVERE)) {
			logger.write(Level.SEVERE, ruleId + " = null"); //$NON-NLS-1$
		}
		addInternalErrorMessage(vc);
	}
	
	protected void preRemoveOldMessages(IEJBValidationContext vc, Map targets) throws ValidationException {
		List validatedClasses = new ArrayList();
		
		try {	
			String[] uris = vc.getURIs();
			for(int i=0; i<uris.length; i++) {
				String uriInst = uris[i];
				if((uriInst == null) || (uriInst.length() == 0)) {
					continue;
				}
				
				Object id = EJBValidationRuleFactory.getFactory().getRuleId(vc, uriInst);
				if(id == null) {
					Object[] clazzAndBean = (Object[])vc.loadModel(uriInst, null); // Don't need a second parameter, but can't cast a RefObject to an Object[], so use the second load method.
					if(clazzAndBean == null) {
						// Log, add "Cannot validate" to task list, and return.
						logMissingRule(vc, id);
						continue;
					}
	
					// In the clazzAndBean object array, the first entry is the JavaClass,
					// and the rest of the entries are the EnterpriseBean instances which 
					// use the JavaClass.
					JavaClass clazz = (JavaClass)clazzAndBean[0];
					List beans = (List)clazzAndBean[1];

					// The validatedClass set keeps track of JavaClasses 
					// that have changed, and this set is used to determine 
					// whose children need to be found and validated. 
					// Validation is performed after all of the changed files 
					// are validated so that all of the children of all of
					// the changed files can be searched for at once. Searching
					// once on a group produces performance savings because
					// the type hierarchy method takes a non-trivial amount
					// of time when there's a large group of deltas.
					validatedClasses.add(clazz);

					if((beans == null) || (beans.size() == 0)) {
						// The JavaClass itself is not part of an enterprise bean, but one of its children may be.
					}
					else {
						Iterator iterator = beans.iterator();
						while(iterator.hasNext()) {
							EnterpriseBean bean = (EnterpriseBean)iterator.next();
							id = EJBValidationRuleFactory.getFactory().getRuleId(vc, clazz, bean);
		
							IValidationRule clazzRule = EJBValidationRuleFactory.getFactory().getRule(vc, id);
							if(clazzRule == null) {
								// This has already been logged by the AbstractEJBValidationRuleFactory (if it's
								// an error - this is expected if the key is a primitive primary key).
								continue;
							}
		
							setValidated(clazzRule.getId(), bean, clazz);
						}
					}
					
				}
				else {
					EJBJar ejbJar = (EJBJar)vc.loadModel(EJBValidatorModelEnum.EJB_MODEL);
					if(ejbJar == null) {
						// Log, add "Cannot validate" to task list, and return.
						continue;
					}
					
					IValidationRule ejbExtRule = EJBValidationRuleFactory.getFactory().getRule(vc, id);
					if(ejbExtRule == null) {
						// This has already been logged by the AbstractEJBValidationRuleFactory, so just
						// need to add "Cannot validate" to the task list.
						continue;
					}
					
					setValidated(ejbExtRule.getId(), null, ejbJar);
				}
			} // end for
			
			// Always validate ejb-jar.xml, because a change to one of the files it references
			// may mean that it needs to be revalidated.	
			EJBJar ejbJar = (EJBJar)vc.loadModel(EJBValidatorModelEnum.EJB_MODEL);
			if(ejbJar != null) {
				Object id = EJBValidationRuleFactory.getFactory().getRuleId(vc, J2EEConstants.EJBJAR_DD_SHORT_NAME);
				if(id == null) {
					// Log, add "Cannot validate" to task list, and return.
					logMissingRule(vc, id);
				}
				else {
					IValidationRule ejbJarRule = EJBValidationRuleFactory.getFactory().getRule(vc, id);
					if(ejbJarRule == null) {
						logMissingRule(vc, id);
					}
					setValidated(ejbJarRule.getId(), null, ejbJar);
				}
			}
			
			if(validatedClasses.size() > 0) {
				// Check the children of the changed classes.
				// This check must be done before the dependents, because
				// the dependents of the children classes must be checked
				// as well.

				// Class never validated before, so check its children
				for (int vC = 0; vC<validatedClasses.size(); vC++) {
					List beans = (List)vc.loadModel(EJBValidatorModelEnum.EJB, new Object[]{validatedClasses.get(vC)});
					if((beans == null) || (beans.size() == 0)) {
						// The class is not a member of an enterprise bean.
						continue;
					}
					Set rootValidatedClass = new HashSet();
					rootValidatedClass.add(validatedClasses.get(vC));
					JavaClass[] children = (JavaClass[])vc.loadModel(EJBValidatorModelEnum.CHILDREN, new Object[]{vc.getReporter(), rootValidatedClass});
					if((children != null) && (children.length > 0)) {
						Iterator bciterator = null;
						Object id = null;
						for(int c=0; c<children.length; c++) {
							JavaClass child = children[c];
							beans = (List)vc.loadModel(EJBValidatorModelEnum.EJB, new Object[]{child});
							// The child is not a member of an enterprise bean.
							if((beans == null) || (beans.size() == 0))
								continue;
							bciterator = beans.iterator();
							while(bciterator.hasNext()) {
								EnterpriseBean bean = (EnterpriseBean)bciterator.next();
								id = EJBValidationRuleFactory.getFactory().getRuleId(vc, child, bean);
								IValidationRule clazzRule = EJBValidationRuleFactory.getFactory().getRule(vc, id);
								// This has already been logged by the AbstractEJBValidationRuleFactory, so just need to add "Cannot validate" to the task list.
								if(clazzRule == null)
									continue;
								setValidated(clazzRule.getId(), bean, child);
							}
						}
					}
				}
				validatedClasses.clear(); // Don't need this cache any more; free the memory.
			}
			
			// Now, validate the dependents.
			targets.putAll(_validated);
			Iterator iterator = targets.keySet().iterator();
			while(iterator.hasNext()) {
				Object id = iterator.next();
				IValidationRule rule = EJBValidationRuleFactory.getFactory().getRule(vc, id);
				if(rule == null) {
					continue;
				}
				
				Set contexts = (Set)targets.get(id);
				if(contexts == null) {
					continue;
				}
				
				Iterator cIterator = contexts.iterator();
				while(cIterator.hasNext()) {
					TargetObject to = (TargetObject)cIterator.next();
					Object targetParent = to.getTargetParent();
					Object target = to.getTarget();
					Set dependents = rule.getDependents();
					if(dependents == null) {
						continue;
					}
					
					Iterator dIterator = dependents.iterator();
					while(dIterator.hasNext()) {
						try {
							IValidationRule dRule = (IValidationRule)dIterator.next();
							Object dRuleTarget = dRule.getTarget(targetParent, target);
							if(dRuleTarget != null) {
								setValidated(dRule.getId(), targetParent, dRuleTarget);
							}
						}
						catch(ValidationCancelledException e) {
							throw e;
						}
						catch(Throwable exc) {
							addInternalErrorMessage(getValidationContext(), exc);
						}
						finally {
							EJBValidationRuleFactory.getFactory().release(rule);
						}
					}
				}
			}
		}
		finally {
			// No matter what, clear the temporary caches.
			targets.clear();
			validatedClasses.clear();
			
			// Now put the "validated" results in "done", because they weren't
			// really validated; it was just a tracking mechanism.
			targets.putAll(_validated);
			_validated.clear(); // Clear the "validated" cache because the targets weren't really validated; they were just tracked.
		}
	}
	
	protected String removeOldMessagesString() {
		return EJBValidatorModelEnum.REMOVE_OLD_MESSAGES;
	}
	
	public void fullValidate(IEJBValidationContext vc) throws ValidationException {
		removeOldMessages(vc,null); // null == no IFileDelta, null = don't track targets
		

		EJBJar ejbJar = (EJBJar)vc.loadModel(EJBValidatorModelEnum.EJB_MODEL);
		if(ejbJar == null) {
			// Log, add "Cannot validate" to task list, and return.
			// EJBProjectResources will already have logged the problem.
			
			IMessage mssg = vc.getMessage();
			mssg.setId(IEJBValidatorMessageConstants.CHKJ2905);
			vc.addMessage(mssg);
			return;
		}
		
		Object id = EJBValidationRuleFactory.getFactory().getRuleId(vc, J2EEConstants.EJBJAR_DD_SHORT_NAME);
		if(id == null) {
			// Log, add "Cannot validate" to task list, and return.
			logMissingRule(vc, J2EEConstants.EJBJAR_DD_SHORT_NAME);
			return;
		}
		IValidationRule ejbJarRule = EJBValidationRuleFactory.getFactory().getRule(vc, id);
		if(ejbJarRule == null) {
			logMissingRule(vc, id);
			return;
		}
		run(ejbJarRule, null, ejbJar); // true= full validation

		List beans = ejbJar.getEnterpriseBeans();
		Iterator iterator = beans.iterator();
		id = null;

		while(iterator.hasNext()) {
			EnterpriseBean bean = (EnterpriseBean)iterator.next();
			JavaClass[] classes = getJavaClass(bean);
			for(int i=0; i<classes.length; i++) {
				JavaClass clazz = classes[i];
				id = EJBValidationRuleFactory.getFactory().getRuleId(vc, clazz, bean);
		
				IValidationRule clazzRule = EJBValidationRuleFactory.getFactory().getRule(vc, id);
				if(clazzRule == null) {
					// This has already been logged by the AbstractEJBValidationRuleFactory (if it's
					// an error - this is expected if the key is a primitive primary key).
					continue;
				}
		
				run(clazzRule, bean, clazz); // true = full validation
			}
		}
	}
	
	protected JavaClass[] getJavaClass(EnterpriseBean bean) {
		int count = 0;
		JavaClass[] classes = new JavaClass[6];
		
		JavaClass ejbClass = bean.getEjbClass();
		if((ejbClass != null) && (ejbClass.isExistingType())) {
			classes[count++] = ejbClass;
		}
		
		JavaClass remoteClass = bean.getRemoteInterface();
		if((remoteClass != null) && (remoteClass.isExistingType())) {
			classes[count++] = remoteClass;
		}
		
		JavaClass localClass = bean.getLocalInterface();
		if((localClass != null) && (localClass.isExistingType())) {
			classes[count++] = localClass;
		}
		
		JavaClass homeClass = bean.getHomeInterface();
		if((homeClass != null) && (homeClass.isExistingType())) {
			classes[count++] = homeClass;
		}
		
		JavaClass localHomeClass = bean.getLocalHomeInterface();
		if((localHomeClass != null) && (localHomeClass.isExistingType())) {
			classes[count++] = localHomeClass;
		}
		
		if(bean instanceof Entity) {
			JavaClass key = ((Entity)bean).getPrimaryKey();
			if((key != null) && (key.isExistingType())) {
				classes[count++] = key;
			}
		}

		if(count == 6) {
			return classes;
		}
		
		JavaClass[] result = new JavaClass[count];
		System.arraycopy(classes, 0, result, 0, count);
		return result;		
	}
	
	public void incrementalValidate(IEJBValidationContext vc) throws ValidationException {
		Map targets = new HashMap();
		try {
			removeOldMessages(vc,targets);
			
			Iterator iterator = targets.keySet().iterator();
			while(iterator.hasNext()) {
				Object id = iterator.next();
				IValidationRule rule = EJBValidationRuleFactory.getFactory().getRule(vc, id);
				if(rule == null) {
					continue;
				}
				
				Set contexts = (Set)targets.get(id);
				if(contexts == null) {
					continue;
				}
				
				Iterator cIterator = contexts.iterator();
				while(cIterator.hasNext()) {
					TargetObject to = (TargetObject)cIterator.next();
					run(rule, to.getTargetParent(), to.getTarget());
				}
			}
		}
		finally {
			targets.clear();
			targets = null;
		}
	}
	
	protected TargetObjectPool getTargetObjectPool() {
		if(_targetObjectPoolSingleton == null) {
			_targetObjectPoolSingleton = new TargetObjectPool(100);
		}
		return _targetObjectPoolSingleton;
	}

    /* (non-Javadoc)
     * @see org.eclipse.jst.j2ee.internal.model.validation.AbstractEJBValidator#releaseRules(org.eclipse.jst.j2ee.internal.model.validation.ejb.IValidationRule)
     */
    protected void releaseRules(IValidationRule rule) {
        EJBValidationRuleFactory.getFactory().release(rule);
        
    }

	public ISchedulingRule getSchedulingRule(IValidationContext helper) {
		// TODO Auto-generated method stub
		return null;
	}
	
}
