/*******************************************************************************
 * Copyright (c) 2006 Oracle Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *     Oracle Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.bpel.validator.model;

/**
 * Java JDK dependency 
 */
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.xml.namespace.QName;

/**
 * BPEL Validation model dependency 
 */

import org.eclipse.bpel.validator.model.Rules.Rule;

/**
 * The base Validator class.
 * 
 * A validator basically encapsulates an INode and runs some special methods (called rules)
 * to check the INode element. The output is a set of IProblem (s).
 * 
 * <p>
 * 
 * Rules are special methods that are discovered by reflection in two ways:
 * <ol>
 *  <li> They either have form "rule_<name>_<index>", or
 *  <li> The have the ARule annotation on them.
 * </ol>
 * 
 * <p>
 * 
 * Order of execution of the rules on a given validator is user defined - 
 * that's what the "index" means above. A rule may also be turned off by
 * the validator code during execution, so that logically exclusive conditions
 * can be simply "turned" off by rules.
 * <p>
 * If the ARule annotation is used then the order() method returns the order of execution.
 * Rules are simply discovered for every validator (only once), then sorted, and then run
 * during invocations.
 * 
 * <p>
 * 
 * Beyond that, there are just 2 other items that govern how rules are executed. 
 * <ol>
 *  <li> The rule tag (simple string), and
 *  <li> the arguments (if any) to the rule method.
 * </ol>
 * <p>
 * Rule tags are just strings which help organize the rules in some way and force their execution
 * at specific times. There are two tags reserved for the system, one is "pass1", the other is "pass2". 
 * User that write validators can invoke other rule sets by calling {@see runRules() }
 * and passing the appropriate tag and arguments. Return values from rule methods are never used.
 * 
 * <p>
 * Validators can be chained, so that you have the following scenario:
 * <pre>
 *   1 <-> 2 <-> 3 <-> 4 ... N
 * </pre>
 * For every INode there is the first validator that is always created. Other validators for the same 
 * INode can be created by simply calling the factory and then attaching the returned validator to the chain.
 * This allows for separation of concerns. For example, "query" nodes may validate in the BPEL and WSDL contexts, and
 * also validate in the Query language context (the same physical node).
 * 
 * <p>
 * 
 * Validators can keep certain state between passes, in the data hash map which is available to
 * the super-classes. This data is erased every time a "pass1" tag is triggered on the validator but
 * remains on for the duration of the object's lifetime.
 * 
 * <p>
 * This simple hash map mechanism is the way that various validators pass data to each other. This is primitive
 * but allows for very loose coupling between the code. When a validator asks for getData() the query goes
 * to its state data and if not found travels in the validator chain in the opposite direction to 
 * execution (always to previous).
 * 
 * <p> 
 * And finally a note about INode. INode represents the generic tree node that some source material
 * is sitting behind. This could be BPEL of course, but it could be any other thing as well. There are
 * adapters which adapt DOM nodes to INodes and EMF nodes to INodes (though there is fewer of those). 
 *
 * @author Michal Chmielewski (michal.chmielewski@oracle.com)
 * @date Sep 14, 2006
 *
 */

@SuppressWarnings({"unchecked","nls","boxing"})

public class Validator implements IConstants {
	
	Logger mLogger = Logger.getLogger( getClass().getName() );
	
	/** The runner which will run our rules */
	RuleRunner fRuleRunner;
	
	/** Problems produced by these rules */	
	private List<IProblem> fProblems = new ArrayList<IProblem>(4);
	
	/** An empty problem array */
	final static IProblem EMPTY_ARRAY[] = {};
	
	/** The node that we are validating */
	protected INode mNode ;
	
	/** Answer interesting things about the model */
	protected IModelQuery mModelQuery;
		
	/** a list of state information that any validator can keep */
	private Map<Object,Object> mData = new HashMap<Object,Object>(5);	
	
	/** The selector that can be used to query the INode facade */
	static protected Selector mSelector = new Selector();
		
	/** Pass 1 tag for rules */
	static public final String PASS1 = "pass1";
	
	/** PAss 2 tag for rules */
	static public final String PASS2 = "pass2";
	
	/** Support chains of validators for the same element */
	private Validator fNext = null;	
	private Validator fPrev = null;
	
	/** A set denoting the list of Static Analysis checks actually done */
	private Set<ARule> mSAChecks = null;

	
	
	
	/**
	 * Create an instance of the validator.
	 * Discover and setup the rules that we will be running. Primarily this 
	 * includes roaming through the methods and ordering them in the correct
	 * order.
	 */
	
	protected Validator () {
		fRuleRunner = new RuleRunner ( this );
	}
	

	/**
	 * @param node  
	 */
	
	public void setNode (INode node) {
		mNode = node;
	}

	/**
	 * Set the model query.
	 * @param query
	 */
	
	public void setModelQuery (IModelQuery query) {
		mModelQuery = query;
	}
	
	
	/**
	 * Use this set to determine coverage of the validators. 
	 * 
	 * @param ruleSet
	 */
	
	public void setSAChecks ( Set<ARule> ruleSet ) {
		mSAChecks = ruleSet;
	}
	
	
	/**
	 * Add a validator to the chain. It is always added to the end of the validator chain.
	 * The validators form a chain starting at the very first one like so
	 * <pre>
	 *   1 <-> 2 <-> 3 <-> 4 <-> 5 ... N
	 * </pre> 
	 * 
	 * When the main dispatcher code runs the validator for the given node, it starts running it at 1 
	 * and continues to N.
	 * <p>
	 * A validator can be attached in 2 ways
	 * <ul>
	 * <li>During the initial factory create calls where all validators for the node
	 * are created and the initial chain is built, and
	 * <li>During execution of a rule.
	 * </ul>
	 * For that reason it is important to realize that the validator mNode, mModelQuery
	 * references may not be yet set. 
	 * 
	 * @param next
	 */
	
	protected void attach ( Validator next ) {
		// no duplicates in chain
		if (this == next) {
			return ;
		}
		
		if (fNext == null) {
			fNext = next;
			
			next.fNext = null;
			next.fPrev = this;
					
		} else {
			fNext.attach ( next );
		}		
	}
			
	
	/**
	 * Validate the node using the rules provided in this validator.
	 * 
	 * @param tag the rules marked with the tag will be run
	 * model   
	 */
		
	final public void validate ( String tag ) {
				
		try {
			if (tag.equals(PASS1)) {
				start();
			}			
			fRuleRunner.runRules ( tag );			
			if (tag.equals(PASS2)) {				
				end();
			}
		} catch (Throwable t) {			
			mLogger.logp(Level.SEVERE, getClass().getName(), 
					"validate", 
					"Problem executing this validator.",
					t);
		}
		
		if (fNext != null) {
			fNext.validate(tag);
		}
		
	}
	
	
	/**
	 * Return the problems found as a result of validation
	 * in the last validation pass. 
	 * 
	 * @return the list of problems found
	 */
	
	@SuppressWarnings("unchecked")
	final public IProblem[] getProblems () {
		
		// Next is empty, just return what we have.
		if (fProblems.size() == 0) {
			return EMPTY_ARRAY;
		}
		return fProblems.toArray( EMPTY_ARRAY );
	}
	
	
	/**
	 * 
	 * Return true if this node validator has captured any problems regarding
	 * the node in question.
	 * 
	 * Chained validators are also consulted.
	 *  
	 * @return true if there are problems, false if there are no problems reported.
	 * 
	 */
	
	public boolean hasProblems () {
		return fProblems.isEmpty() == false;
	}
	
	
	/** 
	 * 
	 * @param node
	 * @return true if there are problems, false otherwise.
	 */
	
	public boolean hasProblems ( INode node ) {
		if (isDefined(node)) {
			Validator validator = node.nodeValidator();
			if (validator != null) {
				return validator.hasProblems();
			}
			return false;
		}
		
		return true;		
	}
		
	
	
	/**
	 * Disable all rules.
	 */
	
	protected void disableRules ( ) {
		disableRules(0,65536);
	}
	
	/**
	 * @param startIdx
	 * @param endIdx
	 */
	
	protected void disableRules (int startIdx, int endIdx ) {
		fRuleRunner.addFilter ( new Rules.IndexFilter ( startIdx,endIdx)  );		
	}
	
	
	/**
	 * Start the validation pass. This is run before all the rules are run.
	 * 
	 */
	
	protected void start () {				
		
		/** reset any disabled rules */		
		fRuleRunner.start();
		
		/**
		 * If we are the first validator in the chain
		 * Then we reset any problems list and clear any data that we 
		 * have.
		 */
		if (fPrev == null) {
			
			fProblems.clear();
			mData.clear();
			
		} else {
			
			/** 
			 * We point ourselves at the first validator in the chain. 
			 *  
			 */
			Validator first = getFirst();
			
			/** 
			 * These are in fact shared between the validators
			 * in the chain.
			 */
			
			fProblems = first.fProblems;
			mData = first.mData;
			mNode = first.mNode;
			mModelQuery = first.mModelQuery;
			mSAChecks = first.mSAChecks;
			
		}		
	}
	
	

	/**
	 *  The validation pass has ended for this object
	 */
	
	protected void end ( ) {
		
	}

	
	/**
	 * Runs the rules matching the tag and and the arguments given.
	 * 
	 * @param tag
	 * @param args
	 */
	
	protected void runRules ( String tag, Object ... args ) {
		fRuleRunner.runRules (tag,args);		
	}
	
	
	/**
	 * Add problems derived from contained validators into the
	 * problems we are reporting.
	 * 
	 * @param problems
	 */
		
	protected void addProblems ( IProblem[] problems ) {
		for(IProblem p : problems) {
			fProblems.add(p);
		}
	}
	
	
	@ARule(
			author = "michal.chmielewski@oracle.com",
			desc = "Internal error: no validator.",		
			date = "10/2/2006",
			sa = -1,
			warnings="BPELC__INTERNAL"
		)	
	protected void internalProblem ( Rule rule, Throwable t ) {
		
		IProblem problem = createWarning();		
		
		while ( t.getCause() != null ) {
			t = t.getCause();
		}
						
		problem.fill("BPELC__INTERNAL",
				toString(mNode.nodeName()),
				rule.getFullName(),
				rule.getIndex(),
				rule.getTag(),
				t);
		
		problem.setAttribute(IProblem.EXCEPTION, t);
	}		
	
	/**
	 * Mark that an SA check has been performed. 
	 * This is done automatically when create*() methods are called to
	 * create an error/warning/info  but you can call this method directly 
	 * too.
	 * 
	 * The is purely for testing reasons to make sure that cases 
	 * are correctly run. This method may be a noop if the validator does not
	 * have the property "internal.sa.checks" set to the right value.
	 * 
	 * @param arule the annotation to record as having been executed
	 */
	
	protected void markSAExecution (ARule arule) {
		if (mSAChecks == null) {
			return ;
		}
		if (arule == null) {
			arule = fRuleRunner.getExecutingRule().method.getAnnotation( ARule.class );
		}
		if (arule != null) {
			mSAChecks.add(arule);	
		}		
	}
	
	/**
	 * Adopt this problem as one of ours. In this case, we simply fill in the location information
	 * in the problem and add it to a list of problems that we keep.
	 * 
	 * @param problem
	 * @param node 
	 */
	
	public void adopt ( IProblem problem , INode node ) {

		// remember it 
		fProblems.add (problem);
		
		problem.setAttribute(IProblem.NODE, node );
		
		problem.setAttribute(IProblem.LINE_NUMBER, 
				mModelQuery.lookup(node, IModelQueryLookups.LOOKUP_NUMBER_LINE_NO,-1));
		
		problem.setAttribute(IProblem.COLUMN_NUMBER, 
				mModelQuery.lookup(node, IModelQueryLookups.LOOKUP_NUMBER_COLUMN_NO,-1));
		
		problem.setAttribute(IProblem.CHAR_END,    
				mModelQuery.lookup(node, IModelQueryLookups.LOOKUP_NUMBER_CHAR_END,-1));
		
		problem.setAttribute(IProblem.CHAR_START,  
				mModelQuery.lookup(node, IModelQueryLookups.LOOKUP_NUMBER_CHAR_START,-1));
				
		problem.setAttribute(IProblem.LOCATION,    
				mModelQuery.lookup(node, IModelQueryLookups.LOOKUP_TEXT_LOCATION,null,null));
		
		problem.setAttribute(IProblem.ADDRESS_MODEL,        
				mModelQuery.lookup(node, IModelQueryLookups.LOOKUP_TEXT_HREF,null,null));		
		
		problem.setAttribute(IProblem.ADDRESS_XPATH,        
				mModelQuery.lookup(node, IModelQueryLookups.LOOKUP_TEXT_HREF_XPATH,null,null));		
									
	}
	
	
	/**
	 * Create a problem based on the context node passed.
	 * 
	 * @param node the context node from which the problem will be 
	 * created.
	 * @return the IProblem marker for the node indicated. 
	 */
	

	protected IProblem createProblem ( INode node ) {
		
		IProblem problem = new Problem ( this );			
		adopt (problem, node);				
		
		Rule r = fRuleRunner.getExecutingRule();
		
		if (r != null) {
			
			problem.setAttribute(IProblem.RULE, r.getFullName() );
			
			ARule a = r.method.getAnnotation( ARule.class );
			
			if (a != null) {
				
				markSAExecution(a);
				
				problem.setAttribute( IProblem.SA_CODE, a.sa() );
				problem.setAttribute( IProblem.RULE_DESC, a.desc() );
			}
		}
		
		return problem;
	}
	
	
	/**
	 * Create an error problem on the current node
	 * 
	 * @return the problem created
	 */
	protected IProblem createError ( ) {
		return createError ( mNode );
	}
	
	
	/**
	 * Create an error problem. This does the same as this as
	 * createProblem plus it sets the problem object to severity error.
	 * 
	 * @param node
	 * @return the problem to be recorded.
	 */
	
	protected IProblem createError ( INode node ) {
		IProblem problem = createProblem (node);
		problem.setAttribute(IProblem.SEVERITY, IProblem.SEVERITY_ERROR);
		return problem;
	}

	
	/**
	 * Create a warning problem on the current node
	 * 
	 * @return the problem created
	 */
	
	protected IProblem createWarning( ) {
		return createWarning ( mNode );
	}
	
	/**
	 * Create a warning problem. This does the same as this as
	 * createProblem plus it sets the problem object to severity warning.
	 * 
	 * @param node
	 * @return the problem to be recorded.
	 */
	protected IProblem createWarning ( INode node ) {
		IProblem problem = createProblem (node);
		problem.setAttribute(IProblem.SEVERITY, IProblem.SEVERITY_WARNING);
		return problem;		
	}
	
	
	/**
	 * Create an information problem. This does the same as this as
	 * createProblem plus it sets the problem object to severity information.
	 * 
	 * @param node
	 * @return the problem to be recorded.
	 */
	
	protected IProblem createInfo ( INode node ) {
		IProblem problem = createProblem (node);
		problem.setAttribute(IProblem.SEVERITY, IProblem.SEVERITY_INFO);
		return problem;
		
	}
	
	
	
	/**
	 * Create an information problem on the current node
	 * 
	 * @return the problem created
	 */
	protected IProblem createInfo ( ) {
		return createInfo ( mNode );
	}	
	
	
	/**
	 * Is the node defined ? The check is to see if the node is empty and is resolved. 
	 * If so, then we return true. Otherwise we return false.
	 * 
	 * @param node
	 * @return true if defined, false otherwise
	 */
	
	protected boolean isDefined ( INode node ) {
		return node != null && node.isResolved();
	}
	
	/**
	 * Is the node undefined ? The check is to see if the node is empty or it is unresolved.
	 * If that's the case, we return true, otherwise we return false.
	 * 
	 * @param node
	 * @return true of undefined, false if defined.
	 */
	
	protected boolean isUndefined ( INode node ) {
		return node == null || node.isResolved() == false;
	}
	
	
	/**
	 * 
	 * @param <T>
	 * @param key
	 * @return the value
	 */
	
	public <T extends Object> T getValue ( Object key ) {
		return (T) getValue( key , null );
	}

	
	/**
	 * @param <T>
	 * @param key
	 * @param def
	 * @return the value
	 */
	
	public <T extends Object> T getValue ( Object key, T def ) {
		if (mData.containsKey(key)) {
			Object obj = mData.get(key);			
			if (obj instanceof IValue) {
				return (T) ((IValue)obj).get();
			}
			return (T) obj;				
		}		
		return def;
	}
	
	
	/**
	 * Return the data stored under the key keyName for the node node
	 * on its connected validator.
	 * 
	 * @param <T>  
	 * @param node the reference node
	 * @param key the key name
	 * @param def the default value
	 * @return the object stored or the default value passed
	 */
	
	public <T extends Object> T getValue ( INode node, Object key, T def ) {		
		Validator validator = validatorForNode(node);
		if (validator != null) {
			return validator.getValue(key,def);
		}
		return def;		
	}


	/**
	 * @param <T>  the type of the object
	 * @param keyName the key name to use
	 * @param value the value to set
	 * @return the previous value under the key
	 */
	
	public <T extends Object> T  setValue ( Object keyName, T value) {
		return (T) mData.put(keyName, value);
	}
	
	/**
	 * @param <T> the object 
	 * @param node the node on which this value ought to be set
	 * @param keyName the key name to use
	 * @param value the value to set
	 * @return the previous value held under that key or null
	 */
	
	public <T extends Object> T setValue ( INode node, Object keyName, T value) {
		
		Validator validator = validatorForNode(node);
		if (validator != null) {
			return validator.setValue(keyName,value);
		}
		return null;
	}
	
	
	/**
	 * Return true if the value key is present on us
	 * @param key
	 * @return true if present, false if not
	 */
	
	public boolean containsValueKey ( String key ) {
		return mData.containsKey(key);
	}
	
	/**
	 * Return true if the value key is contained on the node node.
	 * @param node the node
	 * @param key the key
	 * @return true if value key is present, false otherwise.
	 */
	
	public boolean containsValueKey ( INode node, String key ) {
		Validator validator = validatorForNode (node);
		return validator != null ? validator.containsValueKey(key) : false;
	}

	
	
	Validator validatorForNode ( INode node ) {
		if (isDefined(node)) {
			return node.nodeValidator();
		}
		return null;
	}
	
	
	/** 
	 * @return  Return the first validator in the chain.
	 */
	
	private Validator getFirst() {
		Validator first = this;
		while (first.fPrev != null) {
			first = first.fPrev;
		}
		return first;
	}
	
	protected String toString (QName qname) {
		
		/** No namespace, just return the local part, sans the {} */
		if (isEmptyOrWhitespace(qname.getNamespaceURI())) {
			return qname.getLocalPart();
		}
		
		/** Lookup the prefix in the model query for the context node */
		StringBuilder sb = new StringBuilder(32);
		String prefix = qname.getPrefix();
		
		if (isEmptyOrWhitespace(prefix)) {
			prefix = mModelQuery.lookup(mNode, IModelQueryLookups.LOOKUP_TEXT_NS2PREFIX, qname.getNamespaceURI(), null );					
		}
		/** No prefix, then exit with the default QName */
		if (prefix == null) {
			return qname.toString();
		}
		return sb.append(prefix).append(":").append(qname.getLocalPart()).toString();		
	}
	
	

	/**
     * Returns true if the string is either null or contains just whitespace.
	 * @param value 
	 * @return true if empty or whitespace, false otherwise.
     */
	
	
    static public boolean isEmptyOrWhitespace( String value )
    {
        if( value == null || value.length() == 0) {
            return true;
        } 
        
        for( int i = 0, j = value.length(); i < j; i++ )
        {
            if( ! Character.isWhitespace( value.charAt(i) ) ) {
                return false;
            }
        }
        return true;
    }
    
    
    
    /**
     * Test to see if a string is empty or has a value that is empty.
     * 
     * @param value
     * @return true if empty or null, false otherwise.
     */
    
    
    static public boolean isEmpty ( String value ) {
    	return value == null || value.length() == 0;
    }

    /** Test to see if a string is non empty 
     *
     * @param value the value to test
     * @return true if non empty, false if empty 
     */
    
    
    static public boolean isNonEmpty ( String value ) {
    	return value != null  && value.length () > 0;
    }

}
