package org.eclipse.jst.jsf.validation.internal.appconfig;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Set;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.ISchedulingRule;
import org.eclipse.jst.jsf.core.internal.JSFCorePlugin;
import org.eclipse.jst.jsf.core.internal.provisional.jsfappconfig.JSFAppConfigUtils;
import org.eclipse.jst.jsf.facesconfig.emf.FacesConfigType;
import org.eclipse.jst.jsf.facesconfig.util.FacesConfigArtifactEdit;
import org.eclipse.jst.jsp.core.internal.Logger;
import org.eclipse.wst.common.project.facet.core.IFacetedProject;
import org.eclipse.wst.common.project.facet.core.IProjectFacetVersion;
import org.eclipse.wst.common.project.facet.core.ProjectFacetsManager;
import org.eclipse.wst.validation.internal.core.Message;
import org.eclipse.wst.validation.internal.core.ValidationException;
import org.eclipse.wst.validation.internal.provisional.core.IMessage;
import org.eclipse.wst.validation.internal.provisional.core.IReporter;
import org.eclipse.wst.validation.internal.provisional.core.IValidationContext;
import org.eclipse.wst.validation.internal.provisional.core.IValidatorJob;
import org.eclipse.wst.xml.core.internal.provisional.document.IDOMDocument;
import org.eclipse.wst.xml.core.internal.provisional.document.IDOMModel;
import org.w3c.dom.DocumentType;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

/** 
 * General build-time validator for the JSF application configuration file  (faces-config.xml)b
 *
 * @author cbateman
 *
 */
public class AppConfigValidator implements IValidatorJob {

    public ISchedulingRule getSchedulingRule(IValidationContext helper) {
        // no scheduling rule
        return null;
    }

    public IStatus validateInJob(IValidationContext helper, IReporter reporter)
            throws ValidationException {
        IStatus status = Status.OK_STATUS;
        try {
            validate(helper, reporter);
        }
        catch (ValidationException e) {
            Logger.logException(e);
            status = new Status(IStatus.ERROR, JSFCorePlugin.getDefault().getPluginID(), IStatus.ERROR, e.getLocalizedMessage(), e);
        }
        return status;
    }

    public void cleanup(IReporter reporter) {
        // no cleanup

    }

    public void validate(IValidationContext helper, IReporter reporter)
            throws ValidationException 
    {
        String[] uris = helper.getURIs();
        IWorkspaceRoot wsRoot = ResourcesPlugin.getWorkspace().getRoot();
        if (uris.length > 0) {
            IFile currentFile = null;

            for (int i = 0; i < uris.length && !reporter.isCancelled(); i++) {
                currentFile = wsRoot.getFile(new Path(uris[i]));
                if (currentFile != null && currentFile.exists()) {
//                    if (shouldValidate(currentFile) && fragmentCheck(currentFile)) {

//                        int percent = (i * 100) / uris.length + 1;
//Message message = new LocalizedMessage(IMessage.LOW_SEVERITY, percent + "% " + uris[i]);
  //                      reporter.displaySubtask(this, message);

                        validateFile(currentFile, reporter);
                }
            }
        }
        
        // copied from JSPValidator TODO: perhaps just use app config locator?
//        else {
//
//            // if uris[] length 0 -> validate() gets called for each project
//            if (helper instanceof IWorkbenchContext) {
//
//                IProject project = ((IWorkbenchContext) helper).getProject();
//                JSPFileVisitor visitor = new JSPFileVisitor(reporter);
//                try {
//                    // collect all jsp files for the project
//                    project.accept(visitor, IResource.DEPTH_INFINITE);
//                }
//                catch (CoreException e) {
//                    if (DEBUG)
//                        e.printStackTrace();
//                }
//                IFile[] files = visitor.getFiles();
//                for (int i = 0; i < files.length && !reporter.isCancelled(); i++) {
//                    if (shouldValidate(files[i]) && fragmentCheck(files[i])) {
//                        int percent = (i * 100) / files.length + 1;
//                        Message message = new LocalizedMessage(IMessage.LOW_SEVERITY, percent + "% " + files[i].getFullPath().toString());
//                        reporter.displaySubtask(this, message);
//
//                        validateFile(files[i], reporter);
//                    }
//                    if (DEBUG)
//                        System.out.println("validating: [" + files[i] + "]"); //$NON-NLS-1$ //$NON-NLS-2$
//                }
//            }
//        }
    }

    private void validateFile(IFile file, IReporter reporter)
    {
        FacesConfigArtifactEdit  facesConfigEdit = null;
        
        try
        {
            IPath path = JSFAppConfigUtils.getWebContentFolderRelativePath(file);
            facesConfigEdit = FacesConfigArtifactEdit.
                getFacesConfigArtifactEditForRead(file.getProject(), path.toString());
            
            if (facesConfigEdit != null
                    && facesConfigEdit.getFacesConfig()!=null)
            {
                String version = validateVersioning(file, facesConfigEdit, reporter);
                validateModel(file, facesConfigEdit,reporter, version);
            }
        }
        finally
        {
            if (facesConfigEdit != null)
            {
                facesConfigEdit.dispose();
            }
        }
    }
    
    /**
     * Ensure that the expected project version (facet) jives with what is in
     * the faces-config.  Generally this means:
     * 
     * if (version == 1.1) then no 1.2 artifacts (errors)
     * if (version == 1.2) then warn if using old artifacts (warning)
     */
    private String validateVersioning(IFile file, FacesConfigArtifactEdit facesConfigEdit, IReporter reporter)
    {
        final String appConfigFileVersion = getAppConfigFileVersion(facesConfigEdit);
        
        if (appConfigFileVersion != null)
        {
            final String projectVersion = getJSFVersion(file.getProject());
            
            if ("1.1".equals(projectVersion)
                    || "1.0".equals(projectVersion))
            {
                if ("1.2".equals(appConfigFileVersion))
                {
                    reporter.addMessage(this, new LocalizedMessage(IMessage.HIGH_SEVERITY, "Faces 1.2 application configuration cannot be used in projects for Faces 1.1 or before", file));
                }
            }
            else if ("1.2".equals(projectVersion))
            {
                if ("1.1".equals(appConfigFileVersion))
                {
                    reporter.addMessage(this, new LocalizedMessage(IMessage.LOW_SEVERITY, "Faces "+appConfigFileVersion+" application configuration being used in Faces 1.2 project.  Not all available Faces 1.2 features will be available", file));
                }
            }
            // if no exact match, don't make any assumptions
        }
        return appConfigFileVersion;
    }
    
    /**
     * @param facesConfigEdit
     * @return the version of the app config file or null if not determinant
     */
    private String getAppConfigFileVersion(FacesConfigArtifactEdit facesConfigEdit)
    {
        String appConfigVersion = null;
        
        final IDOMModel domModel = facesConfigEdit.getIDOMModel();
        final IDOMDocument document = domModel.getDocument();
        if (document == null) {return null;}
        
        final DocumentType docType = domModel.getDocument().getDoctype();
        
        // if we have DTD doctype then we're looking at 1.1 or before
        if (docType != null)
        {
            final String publicId = docType.getPublicId();
            final String ids[] = publicId.split("\\/\\/");
            if (ids.length > 2)
            {
                // verify that the class type is a DTD
                if ("DTD".equals(ids[2].split("\\s*")))
                {
                    appConfigVersion = "1.1";
                }
            }
        }
        else
        {
            NodeList rootNodes = domModel.getDocument().getChildNodes();
            
            for (int i = 0; i < rootNodes.getLength(); i++)
            {
                Node node = rootNodes.item(i);
                if (node.getNodeType() == Node.ELEMENT_NODE
                        && "faces-config".equals(node.getLocalName()))
                {
                    NamedNodeMap map = node.getAttributes();
                    // the most accurate thing is the version
                    Node versionAttrib = map.getNamedItem("version");
                    
                    if (versionAttrib != null)
                    {
                        appConfigVersion = versionAttrib.getNodeValue();
                        break;
                    }
                    
                    // TODO: add additional heuristic to parse out
                    // the schema
                }
            }
        }
        
        return appConfigVersion;
    }
    
    private void validateModel(final IFile file, 
                               final FacesConfigArtifactEdit facesConfigEdit, 
                               final IReporter reporter,
                               final String version)
    {
        final FacesConfigType facesConfigType = facesConfigEdit.getFacesConfig();
        FacesConfigValidator validator = new FacesConfigValidator(version);
        List messages = new ArrayList();
        validator.validate(facesConfigType, messages, file);
        
        for (final Iterator it = messages.iterator(); it.hasNext();)
        {
            IMessage message = (IMessage) it.next();
            reporter.addMessage(this, message);
        }
    }
    
    /**
     * @param project
     * @return the version string for the JSF facet on project
     * or null if not found
     */
    private String getJSFVersion(final IProject project)
    {
        try
        {
            final IFacetedProject facetedProject = ProjectFacetsManager.create(project);
            Set facets = facetedProject.getProjectFacets();
            
            for (final Iterator it = facets.iterator(); it.hasNext();)
            {
                IProjectFacetVersion  facetVersion = 
                    (IProjectFacetVersion) it.next();
                
                if ("jst.jsf".equals(facetVersion.getProjectFacet().getId()))
                {
                    return facetVersion.getVersionString();
                }
            }
        }
        catch (CoreException ce)
        {
            JSFCorePlugin.log(ce, "Problem loading faceted project");
            // fall-through and return null
        }
        return null;
    }
    

    private class LocalizedMessage extends Message {

        private String _message = null;

        LocalizedMessage(int severity, String messageText) {
            this(severity, messageText, null);
        }

        LocalizedMessage(int severity, String messageText, IResource targetObject) {
            this(severity, messageText, (Object) targetObject);
        }

        LocalizedMessage(int severity, String messageText, Object targetObject) {
            super(null, severity, null);
            setLocalizedMessage(messageText);
            setTargetObject(targetObject);
        }

        /**
         * @param message
         */
        public void setLocalizedMessage(String message) {
            _message = message;
        }

        /**
         * @return the localized message text
         */
        public String getLocalizedMessage() {
            return _message;
        }

        public String getText() {
            return getLocalizedMessage();
        }

        public String getText(ClassLoader cl) {
            return getLocalizedMessage();
        }

        public String getText(Locale l) {
            return getLocalizedMessage();
        }

        public String getText(Locale l, ClassLoader cl) {
            return getLocalizedMessage();
        }
    }

}
