/*******************************************************************************
 * Copyright (c) 2006 Oracle Corporation.
 * 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:
 *    Gerry Kessler/Oracle - initial API and implementation
 *    
 ********************************************************************************/
package org.eclipse.jst.jsf.validation.internal;

import java.io.IOException;
import java.util.Iterator;
import java.util.List;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Platform;
import org.eclipse.emf.common.util.Diagnostic;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jst.jsf.common.internal.types.CompositeType;
import org.eclipse.jst.jsf.common.internal.types.TypeComparator;
import org.eclipse.jst.jsf.context.resolver.structureddocument.internal.provisional.IDOMContextResolver;
import org.eclipse.jst.jsf.context.resolver.structureddocument.internal.provisional.IStructuredDocumentContextResolverFactory;
import org.eclipse.jst.jsf.context.resolver.structureddocument.internal.provisional.ITaglibContextResolver;
import org.eclipse.jst.jsf.context.structureddocument.internal.provisional.IStructuredDocumentContext;
import org.eclipse.jst.jsf.context.structureddocument.internal.provisional.IStructuredDocumentContextFactory;
import org.eclipse.jst.jsf.core.internal.JSFCorePlugin;
import org.eclipse.jst.jsf.metadataprocessors.internal.provisional.MetaDataEnabledProcessingFactory;
import org.eclipse.jst.jsf.metadataprocessors.internal.provisional.features.ELIsNotValidException;
import org.eclipse.jst.jsf.metadataprocessors.internal.provisional.features.IValidELValues;
import org.eclipse.jst.jsf.metadataprocessors.internal.provisional.features.IValidValues;
import org.eclipse.jst.jsf.metadataprocessors.internal.provisional.features.IValidationMessage;
import org.eclipse.jst.jsf.validation.internal.el.ELExpressionValidator;
import org.eclipse.jst.jsf.validation.internal.el.diagnostics.DiagnosticFactory;
import org.eclipse.jst.jsf.validation.internal.el.diagnostics.ValidationMessageFactory;
import org.eclipse.jst.jsp.core.internal.domdocument.DOMModelForJSP;
import org.eclipse.jst.jsp.core.internal.regions.DOMJSPRegionContexts;
import org.eclipse.jst.jsp.core.internal.validation.JSPValidator;
import org.eclipse.wst.sse.core.StructuredModelManager;
import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel;
import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocument;
import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocumentRegion;
import org.eclipse.wst.sse.core.internal.provisional.text.ITextRegion;
import org.eclipse.wst.sse.core.internal.provisional.text.ITextRegionCollection;
import org.eclipse.wst.sse.core.internal.provisional.text.ITextRegionList;
import org.eclipse.wst.sse.ui.internal.reconcile.validator.ISourceValidator;
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;
import org.eclipse.wst.xml.core.internal.regions.DOMRegionContext;

/**
 * A JSP page validator that makes use of the JSF metadata processing framework so that JSP page
 * semantics can be validated.
 * 
 * This implementation currently only validates attribute values. 
 * @author Gerry Kessler - Oracle
 */
public class JSPSemanticsValidator extends JSPValidator implements ISourceValidator{
// TODO: should the source validator be a separate class in jsp.ui?
    // problem with simple split off is that preference must also be split off
	static final boolean DEBUG;
	static {
		String value = Platform.getDebugOption("org.eclipse.jst.jsf.validation.internal.el/debug/jspsemanticsvalidator"); //$NON-NLS-1$
		DEBUG = value != null && value.equalsIgnoreCase("true"); //$NON-NLS-1$
	}
	private IDocument fDocument;

	/* (non-Javadoc)
	 * @see org.eclipse.jst.jsp.core.internal.validation.JSPValidator#validateFile(org.eclipse.core.resources.IFile, org.eclipse.wst.validation.internal.provisional.core.IReporter)
	 */
	protected void validateFile(IFile file, IReporter reporter) {	
		IStructuredModel model = null;		
		if (DEBUG)
			System.out.println("executing JSPSemanticsValidator.validateFile");
		try {
			model = StructuredModelManager.getModelManager().getModelForRead(file);
			DOMModelForJSP jspModel = (DOMModelForJSP) model;
			IStructuredDocument structuredDoc = jspModel.getStructuredDocument();
			IStructuredDocumentRegion curNode = structuredDoc.getFirstStructuredDocumentRegion();
			while (null != curNode && !reporter.isCancelled()) {
				if (curNode.getFirstRegion().getType() == DOMRegionContext.XML_TAG_OPEN ) 
                {
					validateTag(curNode, reporter, file, false);
				}				
				curNode = curNode.getNext();
			}
		}
        catch (CoreException e)
        {
            JSFCorePlugin.log("Error validating JSF", e);
        }
		catch (IOException e) 
        {
            JSFCorePlugin.log("Error validating JSF", e);
		}
		finally 
        {
			if (null != model)
				model.releaseFromRead();
		}
	}

	/* (non-Javadoc)
	 * @see org.eclipse.wst.sse.ui.internal.reconcile.validator.ISourceValidator#validate(org.eclipse.jface.text.IRegion, org.eclipse.wst.validation.internal.provisional.core.IValidationContext, org.eclipse.wst.validation.internal.provisional.core.IReporter)
	 */
	public void validate(IRegion dirtyRegion, IValidationContext helper, IReporter reporter) {
		if (DEBUG)
			System.out.println("exec JSPSemanticsValidator.validateRegion");

		if (fDocument instanceof IStructuredDocument) {
			IStructuredDocument sDoc = (IStructuredDocument) fDocument;
			IStructuredDocumentRegion[] regions = sDoc.getStructuredDocumentRegions(dirtyRegion.getOffset(), dirtyRegion.getLength());
			if (regions != null){
					validateTag(regions[0], reporter, getFile(helper), true);
			}
		}		
	}
	
	private IFile getFile(IValidationContext helper) {
		String[] uris = helper.getURIs();
		IWorkspaceRoot wsRoot = ResourcesPlugin.getWorkspace().getRoot();
		if (uris.length > 0) 
			return wsRoot.getFile(new Path(uris[0]));

		return null;
	}


	/**
	 * Validates a JSP tag.
	 * 
	 * Currently only attribute values with supplied annotation meta-data is being validated.
	 * Also, only JSF EL is being validated and not JSP EL.
	 * 
	 * This method may be extended in the future to validate tag semantics an other cross attribute
	 * validations.
     * 
	 * @param container 
	 * @param reporter 
	 * @param file 
	 * @param isIncremental -- true if this validation is "as you type"
	 *  
	 */
	private void validateTag(ITextRegionCollection container, IReporter reporter, IFile file, boolean isIncremental) {
		ITextRegionCollection containerRegion = container;
		Iterator regions = containerRegion.getRegions().iterator();
		ITextRegion region = null;
		String uri = null;
		String tagName = null;
		String attrName = null;		
		while (regions.hasNext() && !reporter.isCancelled()) {
			region = (ITextRegion) regions.next();
			String type = region.getType();
			IDOMContextResolver resolver = null;
			ITaglibContextResolver tagLibResolver = null; 
			if (type != null  && (type == DOMRegionContext.XML_TAG_NAME || type == DOMRegionContext.XML_TAG_ATTRIBUTE_NAME || type == DOMRegionContext.XML_TAG_ATTRIBUTE_VALUE)){											
				IStructuredDocumentContext context = IStructuredDocumentContextFactory.INSTANCE.getContext(((IStructuredDocumentRegion)containerRegion).getParentDocument(), containerRegion.getStartOffset() + region.getStart());
				resolver = IStructuredDocumentContextResolverFactory.INSTANCE.getDOMContextResolver(context);
				if	(type == DOMRegionContext.XML_TAG_NAME) {					
					tagLibResolver = IStructuredDocumentContextResolverFactory.INSTANCE.getTaglibContextResolver(context);
					tagName = resolver.getNode().getLocalName();
					uri = tagLibResolver.getTagURIForNodeName(resolver.getNode());
					if (DEBUG)
						System.out.println(addDebugSpacer(1)+"tagName= "+ (tagName!= null ? tagName : "null") +": uri= "+(uri != null ? uri : "null") );
				} 
				else if (type == DOMRegionContext.XML_TAG_ATTRIBUTE_NAME){
					attrName = resolver.getNode().getNodeName();
					if (DEBUG)
						System.out.println(addDebugSpacer(2)+"attrName= "+(attrName != null ? attrName : "null" ));
					if (uri != null && tagName != null)
                    {
						// TODO: validateAttribute(context, region, uri, resolver.getNode(), file);
                    }
				}
				else if (type == DOMRegionContext.XML_TAG_ATTRIBUTE_VALUE){
                    final String attributeVal = 
                        resolver.getNode().getNodeValue();    

                    // if there's  elText then validate it
                    // TODO: this approach will fail with mixed expressions
                    if (!checkIfELAndValidate(region, 
                                              context,
                                              uri,
                                              tagName,
                                              attrName,
                                              attributeVal,
                                              isIncremental,
                                              reporter,
                                              file)
                                              )
                    {
                        // else validate as static attribute value 
                        if (DEBUG)
                            System.out.println(addDebugSpacer(3)+"attrVal= "+(attributeVal != null ? attributeVal : "null") );

                        if (uri != null && tagName != null && attrName != null)
                            validateAttributeValue(context, uri, tagName, attrName, attributeVal, reporter, file);
                    }
				}
			}
		}
	}

    /**
     * Checks the region to see if it contains an EL attribute value.  If it
     * does, validates it
     * @return true if validated EL, false otherwise
     */
    private boolean checkIfELAndValidate(ITextRegion region, 
                                         IStructuredDocumentContext context,
                                         String uri,
                                         String tagName,
                                         String attrName,
                                         String attrValue,
                                         boolean isIncremental,
                                         IReporter reporter,
                                         IFile  file)
    {
        if (region instanceof ITextRegionCollection) {
            ITextRegionCollection parentRegion = ((ITextRegionCollection) region);
            if (parentRegion.getType() == DOMRegionContext.XML_TAG_ATTRIBUTE_VALUE)
            {
                // look for attribute pattern "#{}"
                // TODO: need to generalize this for RValue concatenation
                final ITextRegionList  regionList = parentRegion.getRegions();
                if (regionList.size() >= 4)
                {
                    ITextRegion  openQuote = regionList.get(0);
                    ITextRegion  openVBLQuote = regionList.get(1);

                    if (    (openQuote.getType() == DOMJSPRegionContexts.XML_TAG_ATTRIBUTE_VALUE_DQUOTE
                                || openQuote.getType() == DOMJSPRegionContexts.XML_TAG_ATTRIBUTE_VALUE_SQUOTE)
                                && (openVBLQuote.getType() == DOMJSPRegionContexts.JSP_VBL_OPEN))
                    {
                        // we appear to be inside "#{", so next should be a VBL_CONTENT if there's anything
                        // here to validate
                        final ITextRegion content = regionList.get(2);
                        if (content.getType() == DOMJSPRegionContexts.JSP_VBL_CONTENT)
                        {
                            final int contentStart = 
                                parentRegion.getStartOffset(content);
                            final IStructuredDocumentContext elContext =
                                IStructuredDocumentContextFactory.INSTANCE.
                                    getContext(context.getStructuredDocument(), 
                                            contentStart);

                            final String elText = parentRegion.getText(content);
                            
                            if (DEBUG)
                                System.out.println(addDebugSpacer(3)+"EL attrVal= "+elText);

                            // EL validation is user configurable because
                            // it can be computationally costly.
                            if (checkShouldValidateEL(isIncremental))
                            {
                                List elVals = MetaDataEnabledProcessingFactory.getInstance().getAttributeValueRuntimeTypeFeatureProcessors(IValidELValues.class, elContext, uri, tagName, attrName);
                                validateELExpression(context, 
                                                     elContext, 
                                                     elVals, 
                                                     attrValue,
                                                     elText, 
                                                     reporter, 
                                                     file);
                            }
                        }
                        else if (content.getType() == DOMJSPRegionContexts.JSP_VBL_CLOSE)
                        {
                            final int offset = parentRegion.getStartOffset(openVBLQuote)+1;
                            final int length = 2;
                            
                            // detected empty EL expression
                            reporter.addMessage(this, 
                              ValidationMessageFactory.createFromDiagnostic(
                                   DiagnosticFactory.create_EMPTY_EL_EXPRESSION(),
                                       offset, length, file));
                        }
                        
                        boolean foundClosingQuote = false;
                        for (int i = 2; !foundClosingQuote && i < regionList.size(); i++)
                        {
                            ITextRegion  searchRegion = regionList.get(i);
                            if (searchRegion.getType() == DOMJSPRegionContexts.JSP_VBL_CLOSE)
                            {
                                foundClosingQuote = true;
                            }
                        }
                          
                        if (!foundClosingQuote)
                        {
                            int offset = context.getDocumentPosition()+1;
                            int length = parentRegion.getText().length();

                            reporter.addMessage(this, 
                              ValidationMessageFactory.
                                  createFromDiagnostic(
                                          DiagnosticFactory.create_MISSING_CLOSING_EXPR_BRACKET(), 
                                              offset, length, file));
                        }
                        
                        return true;
                    }
                }
            }
        }
        return false;
    }
            
	private void validateELExpression(IStructuredDocumentContext context,
                                     IStructuredDocumentContext elContext, 
                                     List elVals, 
                                     String attributeVal,
                                     String elText, 
                                     IReporter reporter, 
                                     IFile file) 
    {
        //Call EL validator which will perform at least the syntactical validation
        final ELExpressionValidator elValidator = 
            new ELExpressionValidator(elContext, elText,file);
        elValidator.validateXMLNode();
        elValidator.reportFindings(this, reporter);
        
		CompositeType exprType = elValidator.getExpressionType();
		if (exprType != null)
        {
			for (Iterator it=elVals.iterator();it.hasNext();){
				IValidELValues elval = (IValidELValues)it.next();
				CompositeType expectedType;
				IMessage message = null;
				try {
					expectedType = elval.getExpectedRuntimeType();
                    
                    if (expectedType != null)
                    {
    					Diagnostic status = TypeComparator.calculateTypeCompatibility
                            (expectedType, exprType);
    					if (status.getSeverity() != Diagnostic.OK){
    						message = createValidationMessage(context, attributeVal, getSeverity(status.getSeverity()), status.getMessage(), file);						
    					}
                    }
				} catch (ELIsNotValidException e) {
					message = createValidationMessage(context, attributeVal, IMessage.NORMAL_SEVERITY, e.getMessage(), file);						
				}
				if (message != null) {
					reporter.addMessage(this, message);
				}
			}
        }
	}

//    private void validateAttribute(IStructuredDocumentContext context, ITextRegion region, String uri, Node attr, IFile file) {
		//Not doing anything until the resolver can help me
		
		//validate that attribute can be part of the tag
//		ITaglibContextResolver tagLibResolver = IStructuredDocumentContextResolverFactory.INSTANCE.getTaglibContextResolver(context);
//		if (tagLibResolver.getTagURIForNodeName(attr) == null){
//			System.out.println("not ok: "+attr.getNodeName());
//		}
//		else
//			System.out.println("ok");
		
//	}

	/**
	 * Validates an attribute value in context using the JSF metadata processing framework
	 * 
	 * @param context
	 * @param region
	 * @param uri
	 * @param tagName
	 * @param attrName
	 * @param attributeVal
	 * @param reporter
	 * @param file
	 */
	private void validateAttributeValue(IStructuredDocumentContext context, String uri, String tagName, String attrName, String attributeVal, IReporter reporter, IFile file) {						
		List vv = MetaDataEnabledProcessingFactory.getInstance().getAttributeValueRuntimeTypeFeatureProcessors(IValidValues.class, context, uri, tagName, attrName);
		if (!vv.isEmpty()){
			for (Iterator it = vv.iterator();it.hasNext();){
				IValidValues v = (IValidValues)it.next();
				if (!v.isValidValue(attributeVal.trim())){	
					if (DEBUG)
						System.out.println(addDebugSpacer(4)+"NOT VALID ");
					
					for (Iterator msgs = v.getValidationMessages().iterator();msgs.hasNext();){
						IValidationMessage msg = (IValidationMessage)msgs.next();
						IMessage message = createValidationMessage(context, attributeVal, getSeverity(msg.getSeverity()), msg.getMessage(), file);						
						if (message != null) {
							reporter.addMessage(this, message);
						}
					}
				}
				else
					if (DEBUG)
						System.out.println(addDebugSpacer(5) + "VALID ");
			}			
		}
		else if (DEBUG)
			System.out.println(addDebugSpacer(4)+"NO META DATA ");
	}
	
	private IMessage createValidationMessage(IStructuredDocumentContext context, String attributeValue, int severity, String msg, IFile file){
		IMessage message = new LocalizedMessage(severity, msg, file);						
		if (message != null) {
			final int start = context.getDocumentPosition() + 1;
			final int length = attributeValue.length();
			
			int lineNo = 0;
			try {
				lineNo = context.getStructuredDocument().getLineOfOffset(start);
			} catch (BadLocationException e) {
                //  TODO: C.B why need line number? Length and offset should be
			    //  sufficient
			}
			
			message.setLineNo(lineNo);
			message.setOffset(start);
			message.setLength(length);
		}
		return message;
	}
	/**
	 * Maps IStatus codes to IMessage severity
	 * @param IStatus codesseverity
	 * @return IMessage severity
	 */
	private int getSeverity(int severity) {

		switch (severity){
			case IStatus.ERROR:
				return IMessage.HIGH_SEVERITY;
			case IStatus.WARNING:
				return IMessage.NORMAL_SEVERITY;
			case IStatus.INFO:
				return IMessage.LOW_SEVERITY;
		}
		return IMessage.NORMAL_SEVERITY;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.wst.sse.ui.internal.reconcile.validator.ISourceValidator#connect(org.eclipse.jface.text.IDocument)
	 */
	public void connect(IDocument document) {
		fDocument = document;		
	}

	/* (non-Javadoc)
	 * @see org.eclipse.wst.sse.ui.internal.reconcile.validator.ISourceValidator#disconnect(org.eclipse.jface.text.IDocument)
	 */
	public void disconnect(IDocument document) {
        // do nothing; no disconnect logic
	}
	
	private String addDebugSpacer(int count){
		String TAB = "\t";
		StringBuffer ret = new StringBuffer("");
		for(int i=0;i<=count;i++){
			ret.append(TAB);
		}
		return ret.toString();
	}

    /**
     * @param isIncremental -- true if this is "as-you-type" validation, false
     * if this is "Build" or "Run Validation" validation
     * @return true if user preferences say we should do EL validation,
     * false otherwise
     */
    private boolean checkShouldValidateEL(boolean isIncremental)
    {
        final ValidationPreferences  prefs = new ValidationPreferences();
        prefs.load();
        if (isIncremental)
        {
            return prefs.getElPrefs().isEnableIncrementalValidation();
        }

        return prefs.getElPrefs().isEnableBuildValidation();
    }
}
