/*******************************************************************************
 * Copyright (c) 2007 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:
 *    Cameron Bateman/Oracle - initial API and implementation
 *    
 ********************************************************************************/
package org.eclipse.jst.jsf.validation.internal.appconfig;

import java.io.StringReader;
import java.util.Iterator;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.emf.common.notify.Adapter;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.jdt.core.Flags;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.ITypeHierarchy;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.Signature;
import org.eclipse.jst.jsf.common.internal.types.TypeConstants;
import org.eclipse.jst.jsf.core.internal.JSFCorePlugin;
import org.eclipse.jst.jsf.facesconfig.emf.ListEntriesType;
import org.eclipse.jst.jsf.facesconfig.emf.ManagedBeanScopeType;
import org.eclipse.jst.jsf.facesconfig.emf.MapEntriesType;
import org.eclipse.jst.jsp.core.internal.java.jspel.JSPELParser;
import org.eclipse.jst.jsp.core.internal.java.jspel.ParseException;
import org.eclipse.wst.validation.internal.provisional.core.IMessage;
import org.eclipse.wst.xml.core.internal.emf2xml.EMF2DOMSSEAdapter;
import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;
import org.w3c.dom.Node;

/**
 * Common functions for app config validation
 * 
 * @author cbateman
 *
 */
public final class AppConfigValidationUtil 
{
    /**
     * Per the fully-qualified-classType in the Faces 1.2 schema and
     * the ClassName entity in the 1.1 DTD
     * 
     * @param fullyQualifiedName
     * @param instanceOf 
     * @param project 
     * @return null if no problems or a Message if problem found
     */
    public static IMessage validateClassName(final String fullyQualifiedName, 
                                             final String instanceOf,
                                             final IProject project)
    {
        try
        {
            IType type = getType(project, fullyQualifiedName);
            if (type == null)
            {
                return DiagnosticFactory
                        .create_CANNOT_FIND_CLASS_NAME(fullyQualifiedName);
            }
            
            // must be a class, not an interface or enum
            if (!type.isClass())
            {
                return DiagnosticFactory
                        .create_FULLY_QUALIFIED_NAME_MUST_BE_A_CLASS
                            (fullyQualifiedName);
            }
            
            // must not be abstract since it must instantiable
            if (Flags.isAbstract(type.getFlags()))
            {
                return DiagnosticFactory
                        .create_CLASS_MUST_BE_CONCRETE(fullyQualifiedName);
            }

            if (instanceOf != null)
            {
                if (!isInstanceOf(type, instanceOf))
                {
                    // if we get to here, we haven't found the expected
                    // the super type so error
                    return DiagnosticFactory.create_CLASS_MUST_BE_INSTANCE_OF
                        (fullyQualifiedName, Messages.AppConfigValidationUtil_0, instanceOf);
                }
            }
        }
        catch(JavaModelException jme)
        {
            // fall-through, not found
            JSFCorePlugin.log(jme, 
                "Error resolving fully qualified class name: "+fullyQualifiedName); //$NON-NLS-1$
        }

        // either found the class or had an exception so don't report error
        return null;
    }
    
    private static IType getType(final IProject project,
                        final String fullyQualifiedName) throws JavaModelException
    {
        final IJavaProject javaProject = JavaCore.create(project);
        return javaProject.findType(fullyQualifiedName);
    }
    
    /**
     * Per the faces-config-el-expressionType in the Faces 1.2 schema and
     * the Action entity in the 1.1 DTD
     * 
     * @param textContent
     * @return an validation diagnostic or null if the textContent
     * represent an expected EL expression
     */
    public static IMessage validateELExpression(final String textContent)
    {
        final ELResultWrapper result = extractELExpression(textContent);
        
        if (result.elText != null)
        {
             JSPELParser parser = new JSPELParser(new StringReader(result.elText));
            
            try {
                parser.Expression();
            } catch (ParseException e) {
                // syntax error
                return DiagnosticFactory.create_SYNTAX_ERROR_IN_EL();
            }
            
            return null;
        }
        
        return result.message;
    }

    /**
     * @param textContent
     * @return the result of trying to extract an EL  expression from the
     * textContent string.  The content is expected to be of the form
     * #{elText}.  elText in the return value will be set to this value
     * from within the braces.  If a syntax error occurs in this extraction
     * message property of the result object will contain a validation message
     * and elText will be set to null.
     */
    public static ELResultWrapper extractELExpression(final String textContent)
    {
        final String elRegex = "#\\{(.*)\\}"; //$NON-NLS-1$
        Pattern pattern = Pattern.compile(elRegex);
        Matcher matcher = pattern.matcher(textContent.trim());
        if (matcher.matches())
        {
           final String elText = matcher.group(1).trim();
            
            if ("".equals(elText) || elText == null) //$NON-NLS-1$
            {
                return new ELResultWrapper(DiagnosticFactory.create_SYNTAX_ERROR_IN_EL(), null);
            }
            return new ELResultWrapper(null, elText);
        }
        return new ELResultWrapper(DiagnosticFactory.create_EL_EXPR_MUST_BE_IN_HASH_BRACES(), null);
    }

    /**
     * Value object that wraps the result of trying
     * to extract an EL expression from an arbitrary String
     */
    public static class ELResultWrapper
    {
        private final IMessage    message;
        private final String      elText;
        
        ELResultWrapper(IMessage message, String elText) {
            super();
            this.message = message;
            this.elText = elText;
        }

        /**
         * @return a message indicating a problem encountered
         * trying to extract, or null if no problem was encountered
         */
        public IMessage getMessage() {
            return message;
        }

        /**
         * @return the el expression string raw, stripped of any
         * sorrounding #{} syntax or null if could not be extracted
         */
        public String getElText() {
            return elText;
        }
    }
    
    /**
     * @param eObj
     * @return the offset character offset in to the XML document of the
     * XML node that eObj was constructed from or -1 if not 
     * computable
     */
    public static int getStartOffset(EObject eObj)
    {
        IDOMNode node = getDomNode(eObj);
        
        if (node != null)
        {
            return node.getStartStructuredDocumentRegion().getStartOffset();
        }
        
        return -1;
    }

    /**
     * @param eObj
     * @return the length in characters of the XML node that
     * eObj was constructed from or -1 if no computable
     */
    public static int getLength(EObject eObj)
    {
        IDOMNode node = getDomNode(eObj);
        
        if (node != null)
        {
            return node.getEndStructuredDocumentRegion().getEndOffset()
                      - node.getStartStructuredDocumentRegion().getStartOffset();
        }
        
        return -1;
    }
    
    /**
     * @param eObj
     * @return the DOM node that eObj was constructed from or
     * null if not computable
     */
    public static IDOMNode getDomNode(EObject eObj)
    {
        for (Iterator it = eObj.eAdapters().iterator(); it.hasNext();)
        {
            Adapter adapter = (Adapter) it.next();
            
            if (adapter instanceof EMF2DOMSSEAdapter)
            {
                final EMF2DOMSSEAdapter sseAdapter = (EMF2DOMSSEAdapter) adapter;
                final Node node = sseAdapter.getNode();
                if (node instanceof IDOMNode)
                {
                    return (IDOMNode) node;
                }
            }
        }
        
        return null;
    }
    
    /**
     * @param scope
     * @return an error message if scope does not match a valid
     * scope enum.
     */
    public static IMessage validateManagedBeanScope(ManagedBeanScopeType scope)
    {
        // scope must be one of a few enums
        if (!"request".equals(scope.getTextContent()) //$NON-NLS-1$
                && !"session".equals(scope.getTextContent()) //$NON-NLS-1$
                && !"application".equals(scope.getTextContent()) //$NON-NLS-1$
                && !"none".equals(scope.getTextContent())) //$NON-NLS-1$
        {
            return DiagnosticFactory.create_BEAN_SCOPE_NOT_VALID();
        }
        
        return null;
    }

    /**
     * @param targetName 
     * @param targetType the type of the object that mapEntries will be assigned to
     * @param mapEntries
     * @param project
     * @return null if okay or an error message if the mapEntries type is 
     * invalid in some way
     * Note: when Java 1.5 support is added we can validate against the template types
     */
    public static IMessage validateMapEntries(String targetName, String targetType, MapEntriesType mapEntries, IProject project)
    {
        if (mapEntries == null || targetType == null || project == null)
        {
            throw new AssertionError("Arguments to validateMapEntries can't be null"); //$NON-NLS-1$
        }
        
        try
        {
            // TODO: do a bean look-up for targetName to verify that it a) matches the type
            // and b) exists on the bean
            IType type = getType(project, targetType);
            
            if (type != null &&
                    !(isInstanceOf(type, Signature.toString(TypeConstants.TYPE_MAP))))
            {
                return DiagnosticFactory
                    .create_MAP_ENTRIES_CAN_ONLY_BE_SET_ON_MAP_TYPE(targetName);
            }
            // TODO: validate the the map entries
            // TODO: validate the types of the map entries against the values present
            // TODO: validate the map key and value types against the template
        }
        catch (JavaModelException jme)
        {
            JSFCorePlugin.log(new Exception(jme), "Exception while validating mapEntries"); //$NON-NLS-1$
        }
        // if we get to here, we have not found anything meaningful to report
        return null;
    }
    
    /**
     * @param targetName 
     * @param targetType the type of the object that mapEntries will be assigned to
     * @param listEntries
     * @param project
     * @return null if okay or an error message if the listEntries type is 
     * invalid in some way
     * Note: when Java 1.5 support is added we can validate against the template types
     */
    public static IMessage validateListEntries(String targetName, String targetType, ListEntriesType listEntries, IProject project)
    {
        if (listEntries == null || targetType == null || project == null)
        {
            throw new AssertionError("Arguments to validateMapEntries can't be null"); //$NON-NLS-1$
        }
        
        try
        {
            IType type = getType(project, targetType);
            // TODO: do a bean look-up for targetName to verify that it a) matches the type
            // and b) exists on the bean
            if (type != null &&
                    !(isInstanceOf(type, Signature.toString(TypeConstants.TYPE_LIST))))
            {
                return DiagnosticFactory
                    .create_LIST_ENTRIES_CAN_ONLY_BE_SET_ON_LIST_TYPE(targetName);
            }
            // TODO: validate the the list entries
            // TODO: validate the types of the list entries against the values present
            // TODO: validate the value types against the template
        }
        catch (JavaModelException jme)
        {
            JSFCorePlugin.log(new Exception(jme), "Exception while validating mapEntries"); //$NON-NLS-1$
        }
        // if we get to here, we have not found anything meaningful to report
        return null;
    }
    
    /**
     * @param localeType
     * @return a diagnostic if 'localeType' does not match the
     * expected format or null if all is clear
     */
    public static IMessage validateLocaleType(final String localeType)
    {
        // based on the localeType in the Faces 1.2 schema.  This is safe
        // to apply to 1.1 since it expects the same pattern even though 
        // the DTD cannot validate it
        final String localeTypePattern = "[a-z]{2}(_|-)?([\\p{L}\\-\\p{Nd}]{2})?"; //$NON-NLS-1$
        final Matcher matcher = Pattern.compile(localeTypePattern).matcher(localeType);
        
        if (!matcher.matches())
        {
            return DiagnosticFactory.create_LOCALE_FORMAT_NOT_VALID();
        }
        
        return null;
    }
    
    /**
     * @param type
     * @param instanceOf
     * @return true if type instanceof instanceOf is true
     * 
     * @throws JavaModelException
     */
    public static boolean isInstanceOf(final IType type, final String instanceOf) throws JavaModelException
    {
        if (instanceOf != null)
        {
            // must have either a no-arg constructor or an adapter constructor
            // that is of the type of instanceOf
//            IType  constructorParam = getType(project, instanceOf);
//            if (constructorParam != null)
//            {
//                final String constructorMethodName = 
//                    type.getElementName();
//                final IMethod defaultConstructor = 
//                    type.getMethod(constructorMethodName, new String[0]);
//                final IMethod adapterConstructor =
//                    type.getMethod(constructorMethodName, new String[]{instanceOf});
//                final boolean isDefaultConstructor =
//                    defaultConstructor != null && defaultConstructor.isConstructor();
//                final boolean isAdapterConstructor =
//                    adapterConstructor != null && adapterConstructor.isConstructor();
//                if (!isDefaultConstructor && !isAdapterConstructor)
//                {
                    // TODO: no constructor == default constructor...
//                }
//            }

            // if the type is an exact match
            if (instanceOf.equals(type.getFullyQualifiedName()))
            {
                return true;
            }

            final ITypeHierarchy typeHierarchy = 
                type.newSupertypeHierarchy(new NullProgressMonitor());
            
            final IType[] supers = typeHierarchy.getAllSupertypes(type);
            for (int i = 0; i < supers.length; i++)
            {
                if (instanceOf.equals(supers[i].getFullyQualifiedName()))
                {
                    return true;
                }
            }
        }
        return false;
    }
    
    private AppConfigValidationUtil()
    {
        // no external construction
    }
}
