/*******************************************************************************
 * 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 mustBeAClass 
     * @param project 
     * @return null if no problems or a Message if problem found
     */
    public static IMessage validateClassName(final String fullyQualifiedName, 
                                             final String instanceOf,
                                             final boolean mustBeAClass,
                                             final IProject project)
    {
        try
        {
            IType type = getType(project, fullyQualifiedName);
            if (type == null || !type.exists())
            {
                return DiagnosticFactory
                        .create_CANNOT_FIND_CLASS_NAME(fullyQualifiedName);
            }
            
            // must be a class, not an interface or enum
            if (mustBeAClass && !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.
     * TODO: move this somewhere more generic and shared.
     */
    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
    }
}
