/*******************************************************************************
 * 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.IViewRootHandle;
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 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(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)
                            && 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)
    {
        if (disableAlternativeTypes())
        {
            return expectedType;
        }

        final IStructuredDocumentContext context = elementAdapter
                .getDocumentContext();
        final IViewRootHandle viewRootHandle = DTAppManagerUtil
                .getViewRootHandle(context);
        if (viewRootHandle != null)
        {
            // ok to call update view root here since validation not called
            // on the UI thread.
            final DTUIViewRoot viewRoot = viewRootHandle.updateViewRoot();
            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();
                        return createCompositeType(
                                expectedType,
                                exprTypes,
                                component
                                        .getDecorators(ComponentFactory.CONVERTER));
                    }
                }
            }
        }
        // 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
                        {
                            signature = Signature.createTypeSignature(signature, true);
                            _conversionTypes.add(signature);
                        }
                        catch (final Exception e)
                        {
                            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();
    }

}
