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

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.IAdaptable;
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.jdt.core.Signature;
import org.eclipse.jface.preference.IPreferenceStore;
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.common.runtime.internal.model.ViewObject;
import org.eclipse.jst.jsf.common.runtime.internal.model.component.ComponentFactory;
import org.eclipse.jst.jsf.common.runtime.internal.model.component.ComponentInfo;
import org.eclipse.jst.jsf.common.runtime.internal.model.decorator.ConverterDecorator;
import org.eclipse.jst.jsf.common.runtime.internal.model.decorator.ConverterTypeInfo;
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.core.internal.region.Region2ElementAdapter;
import org.eclipse.jst.jsf.core.jsfappconfig.JSFAppConfigManager;
import org.eclipse.jst.jsf.designtime.DTAppManagerUtil;
import org.eclipse.jst.jsf.designtime.internal.view.DTUIViewRoot;
import org.eclipse.jst.jsf.designtime.internal.view.XMLViewDefnAdapter;
import org.eclipse.jst.jsf.designtime.internal.view.XMLViewObjectMappingService;
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.designtime.internal.view.XMLViewObjectMappingService.ElementData;
import org.eclipse.jst.jsf.facesconfig.emf.ConverterForClassType;
import org.eclipse.jst.jsf.facesconfig.emf.ConverterType;
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
{
    private static final  String       DISABLE_ALTERATIVE_TYPES_KEY = "jsfCoreDisableConverterValidation"; //$NON-NLS-1$
    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"; //$NON-NLS-1$
    private final static String        DISPLAY_NAME = "Attribute Validator"; //$NON-NLS-1$

    private final JSFValidationContext _validationContext;
    private final TypeComparator       _typeComparator;
    private Set<String>                _conversionTypes;

    /**
     * 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 long curTime = System.nanoTime();
            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);
            }
            if (DEBUG)
            {
                System.out.println(String.format("Validation for attribute: %s took %d"
                    , domAdapter.toString()
                    , Long.valueOf(System.nanoTime()-curTime)));
            }
        }
    }

    /**
     * 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(final Throwable exception)
            {
                JSFCorePlugin.log(String.format(
                        "Error validating attribute: %s on element %s", //$NON-NLS-1$
                        attrAdapter.getNodeName(), attrAdapter
                        .getOwningElement().getNodeName()), exception);
            }

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

    private boolean checkIfELAndValidate(final Region2ElementAdapter elementAdapter,
            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= " //$NON-NLS-1$
                                + 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())) //$NON-NLS-1$
                        {
                            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]", " "); //$NON-NLS-1$ //$NON-NLS-2$
                            validateELExpression(context, elContext, elVals,
                                    elementAdapter, attrAdapter, 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)
            {
                final 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 || 
                            openQuote.getType() == DOMJSPRegionContexts.JSP_TAG_ATTRIBUTE_VALUE_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 Region2ElementAdapter elementAdapter,
            final Region2AttrAdapter attrAdapter, 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();
                final String attributeVal = attrAdapter.getValue();
                CompositeType expectedType;
                Diagnostic status = null;
                try
                {
                    expectedType = elval.getExpectedRuntimeType();

                    if (expectedType != null)
                    {
                        expectedType = maybeAddAlternativeTypes(
                                expectedType, exprType, elementAdapter,
                                attrAdapter);
                        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);
                }
            }
        }
    }

    private boolean disableAlternativeTypes()
    {
        String res = System.getProperty(DISABLE_ALTERATIVE_TYPES_KEY);
        if (res == null) {
            //check env var also
            res = System.getenv(DISABLE_ALTERATIVE_TYPES_KEY);
        }
        if (res != null)
        {
            return true;
        }
        final IPreferenceStore prefStore = JSFCorePlugin.getDefault().getPreferenceStore();
        return prefStore.getBoolean("org.eclipse.jst.jsf.core."+DISABLE_ALTERATIVE_TYPES_KEY); //$NON-NLS-1$
    }
    /**
     * @return true if alternative type comparison (i.e. post-conversion) passes
     */
    private CompositeType maybeAddAlternativeTypes(
            final CompositeType expectedType, final CompositeType exprTypes,
            final Region2ElementAdapter elementAdapter,
            final Region2AttrAdapter attrAdapter)
    {
        final long curTime = System.nanoTime();
        if (disableAlternativeTypes())
        {
            return expectedType;
        }

        final IStructuredDocumentContext context = elementAdapter
                .getDocumentContext();
        final DTUIViewRoot viewRoot = _validationContext.getViewRootHandle().getCachedViewRoot();
        final IAdaptable serviceAdaptable = viewRoot.getServices();
        final XMLViewObjectMappingService mappingService = (XMLViewObjectMappingService) serviceAdaptable
                .getAdapter(XMLViewObjectMappingService.class);
        if (mappingService != null)
        {
            final ElementData elementData = XMLViewObjectMappingService
                    .createElementData(elementAdapter.getNamespace(),
                            elementAdapter.getLocalName(), context,
                            Collections.EMPTY_MAP);
            final ViewObject viewObject = mappingService
                    .findViewObject(elementData);
            // if the corresponding view object is a valueholder, then
            // we need to see if you think there a valid conversion
            // available
            if (viewObject instanceof ComponentInfo
                    && ((ComponentInfo) viewObject).getComponentTypeInfo() != null
                    && ((ComponentInfo) viewObject).getComponentTypeInfo()
                            .isInstanceOf(
                                    ComponentFactory.INTERFACE_VALUEHOLDER))
            {
                final ComponentInfo component = (ComponentInfo) viewObject;
                // get the original elementData
                final ElementData mappedElementData = mappingService
                        .findElementData(component);
                final String propName = mappedElementData
                        .getPropertyName(attrAdapter.getLocalName());
                if ("value".equals(propName)) //$NON-NLS-1$
                {
                    // final List converters =
                    // component.getDecorators(ComponentFactory.CONVERTER);

                    // (ConverterDecorator) it.next();
                    final CompositeType alternativeTypes = createCompositeType(
                            expectedType, exprTypes, component
                                    .getDecorators(ComponentFactory.CONVERTER));
                    if (DEBUG)
                    {
                        System.out.println(String.format(
                                "maybeAddAlternative took %d", Long.valueOf(System
                                        .nanoTime()
                                            - curTime)));
                    }
                    return alternativeTypes;
                }
            }
        }
        if (DEBUG)
        {
            System.out.println(String.format("maybeAddAlternative took %d", Long
                .valueOf(System.nanoTime() - curTime)));
        }
        // don't add anything by default
        return expectedType;
    }

    private CompositeType createCompositeType(final CompositeType initialTypes,
            final CompositeType testTypes, final List<ConverterDecorator> decorators)
    {
        // indicates unknown converter
        final Set<String> types = new HashSet(Arrays.asList(initialTypes
                .getSignatures()));
        // look for converters.  If there's one where we don't know the type,
        // simply copy over the testTypes to force validation to ignore, since
        // we have no  idea.
        for (final ConverterDecorator decorator : decorators)
        {
            if (decorator.getTypeInfo() != null)
            {
                final ConverterTypeInfo converterTypeInfo = decorator.getTypeInfo();
                if (converterTypeInfo.getForClass().length == 0)
                {
                    types.addAll(Arrays.asList(testTypes.getSignatures()));
                    break;
                }
                types.addAll(createSignatures(converterTypeInfo.getForClass()));
            }
        }
        types.addAll(getRegisteredConversionTypesByClass());
        return new CompositeType(types.toArray(new String[0])
                , initialTypes.getAssignmentTypeMask());
    }

    private Set<String>  getRegisteredConversionTypesByClass()
    {
        if (_conversionTypes == null)
        {
            _conversionTypes = new HashSet<String>();
            final IProject project = _validationContext.getFile().getProject();
            final JSFAppConfigManager appConfig = JSFAppConfigManager.getInstance(project);
            final List converters = appConfig.getConverters();
            for (final Iterator it = converters.iterator(); it.hasNext();)
            {
                final ConverterType converterType = (ConverterType) it.next();
                final ConverterForClassType forClassType = converterType.getConverterForClass();
                if (forClassType != null)
                {
                    final String forClass = forClassType.getTextContent();
                    if (forClass != null)
                    {
                        String signature = forClass.trim();
                        try
                        {
                            // arrays are a special case where the 
                            // [Ljava.lang.String; syntax is valid.
                            if (Signature.getArrayCount(signature)>0)
                            {
                                _conversionTypes.add(signature);
                            }
                        }
                        catch (final IllegalArgumentException e)
                        {
                            // ignore
                        }

                        try
                        {
                            signature = Signature.createTypeSignature(signature, true);
                            _conversionTypes.add(signature);
                        }
                        catch (final Exception e)
                        {
                            // ignore: JSFCorePlugin.log(IStatus.INFO, "Could not use registered converter for-class: "+forClass); //$NON-NLS-1$
                        }
                    }
                }
            }
        }
        return _conversionTypes;
    }

    private List<String> createSignatures(final String[] classNames)
    {
        final List<String> signatures = new ArrayList<String>();
        for (final String className : classNames)
        {
            try
            {
                String signature = Signature.createTypeSignature(className, true);
                signatures.add(signature);
            }
            catch (final Exception e)
            {
                JSFCorePlugin.log(e, "Trying to create signature"); //$NON-NLS-1$
            }
        }
        return signatures;
    }

    /**
     * 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= " //$NON-NLS-1$
                    + (attributeValue != null ? attributeValue : "null")); //$NON-NLS-1$
        }

        final AttributeIdentifier attributeId = attrAdapter
        .getAttributeIdentifier();

        if (attributeId.getTagIdentifier() == 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 "); //$NON-NLS-1$
                    }

                    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 "); //$NON-NLS-1$
                }
            }
        }
        else if (DEBUG)
        {
            System.out.println(addDebugSpacer(4) + "NO META DATA "); //$NON-NLS-1$
        }
    }

    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, //$NON-NLS-1$
                msg, null);
        return diagnostic;
    }

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

}
