/*******************************************************************************
 * 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.emf.common.util.Diagnostic;
import org.eclipse.jst.jsf.common.dom.DOMAdapter;
import org.eclipse.jst.jsf.common.dom.TagIdentifier;
import org.eclipse.jst.jsf.common.internal.JSPUtil;
import org.eclipse.jst.jsf.common.metadata.Entity;
import org.eclipse.jst.jsf.common.metadata.Trait;
import org.eclipse.jst.jsf.common.metadata.query.ITaglibDomainMetaDataModelContext;
import org.eclipse.jst.jsf.common.metadata.query.TaglibDomainMetaDataQueryHelper;
import org.eclipse.jst.jsf.common.sets.AxiomaticSet;
import org.eclipse.jst.jsf.common.sets.ConcreteAxiomaticSet;
import org.eclipse.jst.jsf.context.resolver.structureddocument.IDOMContextResolver;
import org.eclipse.jst.jsf.context.resolver.structureddocument.IStructuredDocumentContextResolverFactory;
import org.eclipse.jst.jsf.context.structureddocument.IStructuredDocumentContext;
import org.eclipse.jst.jsf.core.internal.JSFCorePlugin;
import org.eclipse.jst.jsf.core.internal.region.Region2ElementAdapter;
import org.eclipse.jst.jsf.core.internal.tld.IJSFConstants;
import org.eclipse.jst.jsf.core.internal.tld.TagIdentifierFactory;
import org.eclipse.jst.jsf.core.set.constraint.MemberConstraint;
import org.eclipse.jst.jsf.core.set.mapping.ElementToTagIdentifierMapping;
import org.eclipse.jst.jsf.core.tagmatcher.EvaluationException;
import org.eclipse.jst.jsf.core.tagmatcher.InvalidExpressionException;
import org.eclipse.jst.jsf.core.tagmatcher.XPathMatchingAlgorithm;
import org.eclipse.jst.jsf.validation.internal.AbstractXMLViewValidationStrategy;
import org.eclipse.jst.jsf.validation.internal.JSFValidationContext;
import org.eclipse.jst.jsf.validation.internal.constraints.ContainsTagConstraint;
import org.eclipse.jst.jsf.validation.internal.constraints.TagId;
import org.eclipse.jst.jsf.validation.internal.constraints.TagSet;
import org.w3c.dom.Node;

/**
 * @author cbateman
 * 
 */
public class ContainmentValidatingStrategy extends
        AbstractXMLViewValidationStrategy
{
    /**
     * identifier
     */
    public final static String                         ID = 
        "org.eclipse.jst.jsf.validation.strategy.ElementValidatingStrategy"; //$NON-NLS-1$
    private final static String                        DISPLAY_NAME =
        Messages.ContainmentValidatingStrategy_DisplayName;
    private final static ElementToTagIdentifierMapping elem2TagIdMapper = 
        new ElementToTagIdentifierMapping();
    
    private static final  String  ENABLE_CONTAINMENT_VALIDATION_KEY  = "jsfCoreEnableContainmentValidation"; //$NON-NLS-1$
    
    private int                                        _containmentValidationCount;  // = 0;
    private final JSFValidationContext                 _jsfValidationContext;
    private boolean 								   _enabled;						

    /**
     * @param jsfValidationContext
     */
    public ContainmentValidatingStrategy(
            final JSFValidationContext jsfValidationContext)
    {
        super(ID, DISPLAY_NAME);
        _jsfValidationContext = jsfValidationContext;
        _enabled = getEnablementProperty();
    }

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

    @Override
    public void validate(DOMAdapter domAdapter)
    {
        if (_enabled 
        		&& domAdapter instanceof Region2ElementAdapter)
        {
            final Region2ElementAdapter elementAdapter = 
                (Region2ElementAdapter) domAdapter;
            validateContainment(elementAdapter, _jsfValidationContext);
        }
    }

    private boolean getEnablementProperty() {
		 String res = System.getProperty(ENABLE_CONTAINMENT_VALIDATION_KEY);
		 if (res == null) {
		     //check env var also
		     res = System.getenv(ENABLE_CONTAINMENT_VALIDATION_KEY);
		 }
		 return res != null;		
	}
    
    private void validateContainment(
            final Region2ElementAdapter elementAdapter,
            final JSFValidationContext jsfValidationContext)
    {
        // don't validate JSP fragments since the necessary containment may
        // existing
        // in the JSP files that include them
        // also only validate the first instance of containment violation in a
        // file
        if (JSPUtil.isJSPFragment(jsfValidationContext.getFile())
                || _containmentValidationCount > 0)
        {
            return;
        }

        final IStructuredDocumentContext context = elementAdapter
                .getDocumentContext();
        final IDOMContextResolver resolver = IStructuredDocumentContextResolverFactory.INSTANCE
                .getDOMContextResolver(context);
        final Node node = resolver.getNode();

        final String uri = elementAdapter.getNamespace();
        final String tagName = elementAdapter.getLocalName();
        // final Element node = elementAdapter.

        final ITaglibDomainMetaDataModelContext modelContext = TaglibDomainMetaDataQueryHelper
                .createMetaDataModelContext(jsfValidationContext.getFile()
                        .getProject(), uri);
        final Entity entity = TaglibDomainMetaDataQueryHelper.getEntity(
                modelContext, tagName);
        if (entity != null)
        {
            final Trait trait = TaglibDomainMetaDataQueryHelper.getTrait(
                    entity, "containment-constraint"); //$NON-NLS-1$

            if (trait != null)
            {
                final ContainsTagConstraint tagConstraint = (ContainsTagConstraint) trait
                        .getValue();

                final String algorithm = tagConstraint.getSetGenerator()
                        .getAlgorithm();

                // TODO: need generalized factory mechanism for registering and
                // constructing algorithms.
                if (!"xpath".equals(algorithm)) //$NON-NLS-1$
                {
                    return;
                }

                final String expr = tagConstraint.getSetGenerator()
                        .getExpression();

                // TODO: optimize on the expression and cache for reuse
                final XPathMatchingAlgorithm xpathAlg = new XPathMatchingAlgorithm(
                        expr);

                AxiomaticSet set = null;

                try
                {
                    set = xpathAlg.evaluate(node);
                    // map dom nodes to tag identifiers
                    set = elem2TagIdMapper.map(set);
                }
                catch (final InvalidExpressionException e)
                {
                    JSFCorePlugin.log(e, "Problem with expression: " + expr //$NON-NLS-1$
                            + " on node " + node); //$NON-NLS-1$
                    return;
                }
                catch (final EvaluationException e)
                {
                    JSFCorePlugin.log(e, "Problem evaluating expression: " //$NON-NLS-1$
                            + expr + " on node " + node); //$NON-NLS-1$
                    return;
                }

                final TagSet constraintData = tagConstraint.getSatisfiesSet();
                final AxiomaticSet constraintSet = new ConcreteAxiomaticSet();
                for (final Iterator it = constraintData.getTags().iterator(); it
                        .hasNext();)
                {
                    final TagId tagId = (TagId) it.next();
                    constraintSet.add(TagIdentifierFactory.createJSPTagWrapper(
                            tagId.getUri(), tagId.getName()));
                }
                final MemberConstraint memberConstraint = new MemberConstraint(
                        constraintSet);
                final Diagnostic diag = memberConstraint.isSatisfied(set);

                if (diag.getSeverity() != Diagnostic.OK)
                {
                    _containmentValidationCount++; // found a violation

                    final List data = diag.getData();

                    for (final Iterator it = data.iterator(); it.hasNext();)
                    {
                        final TagIdentifier missingParent = (TagIdentifier) it
                                .next();

                        reportContainmentProblem(context, node, missingParent);
                    }
                }
            }
        }
    }

    private void reportContainmentProblem(
            final IStructuredDocumentContext context,
            final Node node,
            final TagIdentifier missingParent)
    {

    	Diagnostic diagnostic = null;
    	if (missingParent.equals(IJSFConstants.TAG_IDENTIFIER_VIEW)) {
    		diagnostic = DiagnosticFactory.create_CONTAINMENT_ERROR_MISSING_VIEW(node.getNodeName());
    	}
    	else if (missingParent.equals(IJSFConstants.TAG_IDENTIFIER_FORM)) {
    		diagnostic = DiagnosticFactory.create_CONTAINMENT_ERROR_MISSING_FORM(node.getNodeName());
    	}
    	else {
    		diagnostic = DiagnosticFactory.create_CONTAINMENT_ERROR_MISSING_ANCESTOR(node.getNodeName(), missingParent);
    	} 

        // add one so that the start offset is at the node name, rather
        // than the opening brace.
        final int start = context.getDocumentPosition()+1;
        final int length = node.getNodeName().length();

       _jsfValidationContext.getReporter().report(diagnostic, start, length);
    }
    
}
