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

import java.util.Iterator;
import java.util.List;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.runtime.ISafeRunnable;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.SafeRunner;
import org.eclipse.emf.common.util.BasicDiagnostic;
import org.eclipse.emf.common.util.Diagnostic;
import org.eclipse.jst.jsf.common.dom.AttrDOMAdapter;
import org.eclipse.jst.jsf.common.dom.AttributeIdentifier;
import org.eclipse.jst.jsf.common.dom.DOMAdapter;
import org.eclipse.jst.jsf.common.internal.types.CompositeType;
import org.eclipse.jst.jsf.common.internal.types.TypeComparator;
import org.eclipse.jst.jsf.common.internal.types.TypeComparatorDiagnosticFactory;
import org.eclipse.jst.jsf.context.structureddocument.IStructuredDocumentContext;
import org.eclipse.jst.jsf.context.structureddocument.IStructuredDocumentContextFactory;
import org.eclipse.jst.jsf.core.internal.JSFCorePlugin;
import org.eclipse.jst.jsf.core.internal.region.Region2AttrAdapter;
import org.eclipse.jst.jsf.designtime.DTAppManagerUtil;
import org.eclipse.jst.jsf.designtime.internal.view.XMLViewDefnAdapter;
import org.eclipse.jst.jsf.designtime.internal.view.IDTViewHandler.ViewHandlerException;
import org.eclipse.jst.jsf.designtime.internal.view.XMLViewDefnAdapter.DTELExpression;
import org.eclipse.jst.jsf.metadataprocessors.MetaDataEnabledProcessingFactory;
import org.eclipse.jst.jsf.metadataprocessors.features.ELIsNotValidException;
import org.eclipse.jst.jsf.metadataprocessors.features.IValidELValues;
import org.eclipse.jst.jsf.metadataprocessors.features.IValidValues;
import org.eclipse.jst.jsf.metadataprocessors.features.IValidationMessage;
import org.eclipse.jst.jsf.validation.internal.AbstractXMLViewValidationStrategy;
import org.eclipse.jst.jsf.validation.internal.JSFValidationContext;
import org.eclipse.jst.jsf.validation.internal.el.ELExpressionValidator;
import org.eclipse.jst.jsp.core.internal.regions.DOMJSPRegionContexts;
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.xml.core.internal.regions.DOMRegionContext;

/**
 * An XML view validation strategy that validates
 * 
 * @author cbateman
 * 
 */
public class AttributeValidatingStrategy extends
        AbstractXMLViewValidationStrategy
{
    static final boolean               DEBUG;
    static
    {
        final 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$
    }

    /**
     * identifier
     */
    public final static String         ID           = "org.eclipse.jst.jsf.validation.strategy.AttributeValidatingStrategy";
    private final static String        DISPLAY_NAME = "Attribute Validator";

    private final JSFValidationContext _validationContext;
    private final TypeComparator       _typeComparator;
    /**
     * Default constructor
     * 
     * @param validationContext
     */
    public AttributeValidatingStrategy(
            final JSFValidationContext validationContext)
    {
        super(ID, DISPLAY_NAME);

        _validationContext = validationContext;
        _typeComparator = new TypeComparator(new TypeComparatorDiagnosticFactory(validationContext.getPrefs().getTypeComparatorPrefs()));
    }

    @Override
    public boolean isInteresting(final DOMAdapter domAdapter)
    {
        return (domAdapter instanceof AttrDOMAdapter);
    }

    @Override
    public void validate(final DOMAdapter domAdapter)
    {
        if (domAdapter instanceof AttrDOMAdapter)
        {
            final Region2AttrAdapter attrAdapter = (Region2AttrAdapter) domAdapter;
            //check that this is attribute value region - 221722
            if (attrAdapter.getAttributeValueRegion() != null) { 
	            final IStructuredDocumentContext context = IStructuredDocumentContextFactory.INSTANCE
	                    .getContext(attrAdapter.getDocumentContext()
	                            .getStructuredDocument(), attrAdapter
	                            .getOwningElement().getDocumentContext()
	                            .getDocumentPosition()
	                            + attrAdapter.getAttributeValueRegion().getStart());
            
	            validateAttributeValue(context, attrAdapter);
            }
        }
    }

    /**
     * Validates the attribute value. Reports any problems to the reporter in
     * the JSFValidationContext.
     * 
     * @param context
     * @param attrAdapter
     */
    private void validateAttributeValue(
            final IStructuredDocumentContext context,
            final Region2AttrAdapter attrAdapter)
    {
        // so of the code in run calls out into extension code or code
        // dependent on external data (meta-data)
        SafeRunner.run(new ISafeRunnable()
        {
            public void handleException(Throwable exception)
            {
                JSFCorePlugin.log(String.format(
                        "Error validating attribute: %s on element %s",
                        attrAdapter.getNodeName(), attrAdapter
                                .getOwningElement().getNodeName()), exception);
            }

            public void run() throws Exception
            {
                // if there's elText then validate it
                // TODO: this approach will fail with mixed expressions
                if (!checkIfELAndValidate(attrAdapter, context))
                {
                    validateNonELAttributeValue(context, attrAdapter);
                }
            }
        });
    }

    private boolean checkIfELAndValidate(final Region2AttrAdapter attrAdapter,
            final IStructuredDocumentContext context)
    {
        int offsetOfFirstEL = -1;
        final String attrValue = attrAdapter.getValue();

        // TODO: should find and validate all
        offsetOfFirstEL = attrValue.indexOf('#');

        if (offsetOfFirstEL != -1 && offsetOfFirstEL < attrValue.length() - 1
                && attrValue.charAt(offsetOfFirstEL + 1) == '{')
        {
            offsetOfFirstEL += 2;
        }
        else
        {
            offsetOfFirstEL = -1;
        }

        final XMLViewDefnAdapter adapter = DTAppManagerUtil
                .getXMLViewDefnAdapter(context);

        boolean isEL = false;
        if (adapter != null && offsetOfFirstEL != -1)
        {
            try
            {
                // use the attribute's context plus the offset into the
                // whole attribute value to find where we think the el
                // expression starts. Add one since the attribute value
                // string returned by attrAdapter will have the value quotes
                // removed, but the region offsets include the quotes.
                IStructuredDocumentContext elContext = IStructuredDocumentContextFactory.INSTANCE
                        .getContext(context.getStructuredDocument(), context
                                .getDocumentPosition()
                                + offsetOfFirstEL + 1);
                final DTELExpression elExpression = adapter
                        .getELExpression(elContext);
                if (elExpression != null)
                {
                    final String elText = elExpression.getText();

                    if (DEBUG)
                    {
                        System.out.println(addDebugSpacer(3) + "EL attrVal= "
                                + elText);
                    }

                    elContext = elExpression.getDocumentContext();
                    // EL validation is user configurable because
                    // it can be computationally costly.
                    if (_validationContext.shouldValidateEL())
                    {
                        // also, skip the validation if the expression is empty
                        // or only whitespace, since the parser doesn't handle it
                        // anyway.
                        if ("".equals(elText.trim()))
                        {
                            final int offset = elContext.getDocumentPosition()-1;
                            final int length = elText.length()+2;
                            final Diagnostic diagnostic = _validationContext
                                    .getDiagnosticFactory()
                                    .create_EMPTY_EL_EXPRESSION();
                            // detected empty EL expression
                            if (_validationContext.shouldValidateEL())
                            {
                                _validationContext.getReporter().report(
                                        diagnostic, offset, length);
                            }
                        }
                        else
                        {
                            final List elVals = MetaDataEnabledProcessingFactory
                                    .getInstance()
                                    .getAttributeValueRuntimeTypeFeatureProcessors(
                                            IValidELValues.class, elContext,
                                            attrAdapter.getAttributeIdentifier());
                            final String safeELText = elText.replaceAll("[\n\r\t]", " ");
                            validateELExpression(context, elContext, elVals,
                                    attrAdapter.getValue(), safeELText);
                            isEL = true;
                        }
                    }
                }
            }
            catch (final ViewHandlerException e)
            {
                // fall through to return false
            }
        }

        // is el if we've already detected it or if the step 2 method
        // finds it. Run the method first to avoid short-circuiting
        final boolean isEL2 = checkIfELAndValidate2(attrAdapter, context);

        return isEL || isEL2;
    }

    /**
     * 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 checkIfELAndValidate2(final Region2AttrAdapter attrAdapter,
            final IStructuredDocumentContext sDocContext)
    {
        final ITextRegion attrValueRegion = attrAdapter
                .getAttributeValueRegion();
        if (attrValueRegion instanceof ITextRegionCollection)
        {
            final ITextRegionCollection parentRegion = ((ITextRegionCollection) attrValueRegion);
            if (parentRegion.getType() == DOMRegionContext.XML_TAG_ATTRIBUTE_VALUE)
            {
                ITextRegionList regionList = parentRegion.getRegions();

                if (regionList.size() >= 3)
                {
                    final ITextRegion openQuote = regionList.get(0);
                    final ITextRegion vblOpen = regionList.get(1);

                    if ((openQuote.getType() == DOMJSPRegionContexts.XML_TAG_ATTRIBUTE_VALUE_DQUOTE || openQuote
                            .getType() == DOMJSPRegionContexts.JSP_VBL_DQUOTE)
                            && vblOpen.getType() == DOMJSPRegionContexts.JSP_VBL_OPEN)
                    {
                        boolean foundClosingQuote = false;
                        for (int i = 2; !foundClosingQuote
                                && i < regionList.size(); i++)
                        {
                            final ITextRegion searchRegion = regionList.get(i);
                            if (searchRegion.getType() == DOMJSPRegionContexts.JSP_VBL_CLOSE)
                            {
                                foundClosingQuote = true;
                            }
                        }

                        if (!foundClosingQuote
                                && _validationContext.shouldValidateEL())
                        {
                            final int offset = sDocContext
                                    .getDocumentPosition() + 1;
                            final int length = parentRegion.getText().length();
                            final Diagnostic diagnostic = _validationContext
                                    .getDiagnosticFactory()
                                    .create_MISSING_CLOSING_EXPR_BRACKET();
                            _validationContext.getReporter().report(diagnostic,
                                    offset, length);
                        }
                        return true;
                    }
                }
            }
        }
        return false;
    }

    private void validateELExpression(final IStructuredDocumentContext context,
            final IStructuredDocumentContext elContext, final List elVals,
            final String attributeVal, final String elText)
    {
        // Call EL validator which will perform at least the syntactical
        // validation
        final ELExpressionValidator elValidator = new ELExpressionValidator(
                elContext, elText, _validationContext
                        .getSymbolResolverFactory(), _validationContext
                        .getReporter());
        elValidator.validateXMLNode();

        final CompositeType exprType = elValidator.getExpressionType();
        if (exprType != null)
        {
            for (final Iterator it = elVals.iterator(); it.hasNext();)
            {
                final IValidELValues elval = (IValidELValues) it.next();
                CompositeType expectedType;
                Diagnostic status = null;
                try
                {
                    expectedType = elval.getExpectedRuntimeType();

                    if (expectedType != null)
                    {
                        
                        status = _typeComparator.calculateTypeCompatibility(
                                expectedType, exprType);
                        if (status.getSeverity() != Diagnostic.OK)
                        {
                            reportValidationMessage(status, context,
                                    attributeVal);
                        }
                    }
                }
                catch (final ELIsNotValidException e)
                {
                    reportValidationMessage(createValidationMessage(context,
                            attributeVal, IStatus.WARNING, e.getMessage(),
                            _validationContext.getFile()), context,
                            attributeVal);
                }
            }
        }
    }

    /**
     * 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 validateNonELAttributeValue(
            final IStructuredDocumentContext context,
            final Region2AttrAdapter attrAdapter)
    {
        final String attributeValue = attrAdapter.getValue();
        // else validate as static attribute value
        if (DEBUG)
        {
            System.out.println(addDebugSpacer(3) + "attrVal= "
                    + (attributeValue != null ? attributeValue : "null"));
        }

        final AttributeIdentifier attributeId = attrAdapter
                .getAttributeIdentifier();

        if (attributeId.getTagIdentifier() == null
                || attributeId.getTagIdentifier().getTagName() == null
                || attributeId.getTagIdentifier().getTagName() == null
                || attributeId.getName() == null)
        {
            return;
        }

        final List vv = MetaDataEnabledProcessingFactory.getInstance()
                .getAttributeValueRuntimeTypeFeatureProcessors(
                        IValidValues.class, context, attributeId);
        if (!vv.isEmpty())
        {
            for (final Iterator it = vv.iterator(); it.hasNext();)
            {
                final IValidValues v = (IValidValues) it.next();
                if (!v.isValidValue(attributeValue.trim()))
                {
                    if (DEBUG)
                    {
                        System.out.println(addDebugSpacer(4) + "NOT VALID ");
                    }

                    for (final Iterator msgs = v.getValidationMessages()
                            .iterator(); msgs.hasNext();)
                    {
                        final IValidationMessage msg = (IValidationMessage) msgs
                                .next();
                        reportValidationMessage(createValidationMessage(
                                context, attributeValue, msg.getSeverity(), msg
                                        .getMessage(), _validationContext
                                        .getFile()), context, attributeValue);
                    }
                }
                else if (DEBUG)
                {
                    System.out.println(addDebugSpacer(5) + "VALID ");
                }
            }
        }
        else if (DEBUG)
        {
            System.out.println(addDebugSpacer(4) + "NO META DATA ");
        }
    }

    private void reportValidationMessage(final Diagnostic problem,
            final IStructuredDocumentContext context,
            final String attributeValue)
    {
        final int start = context.getDocumentPosition() + 1;
        final int length = attributeValue.length();
        _validationContext.getReporter().report(problem, start, length);
    }

    private Diagnostic createValidationMessage(
            final IStructuredDocumentContext context,
            final String attributeValue, final int severity, final String msg,
            final IFile file)
    {
        // TODO: need factory
        final Diagnostic diagnostic = new BasicDiagnostic(severity, "", -1,
                msg, null);
        return diagnostic;
    }

    private String addDebugSpacer(final int count)
    {
        final String TAB = "\t";
        final StringBuffer ret = new StringBuffer("");
        for (int i = 0; i <= count; i++)
        {
            ret.append(TAB);
        }
        return ret.toString();
    }

}
