package org.eclipse.jst.jsp.core.internal.taglib;


import java.io.File;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import javax.servlet.jsp.tagext.TagAttributeInfo;
import javax.servlet.jsp.tagext.TagData;
import javax.servlet.jsp.tagext.TagExtraInfo;
import javax.servlet.jsp.tagext.TagInfo;
import javax.servlet.jsp.tagext.TagLibraryInfo;
import javax.servlet.jsp.tagext.VariableInfo;

import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Platform;
import org.eclipse.jdt.core.IClasspathContainer;
import org.eclipse.jdt.core.IClasspathEntry;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jst.jsp.core.internal.Logger;
import org.eclipse.jst.jsp.core.internal.contentmodel.TaglibController;
import org.eclipse.jst.jsp.core.internal.contentmodel.tld.TLDCMDocumentManager;
import org.eclipse.jst.jsp.core.internal.contentmodel.tld.TaglibTracker;
import org.eclipse.jst.jsp.core.internal.contentmodel.tld.provisional.TLDAttributeDeclaration;
import org.eclipse.jst.jsp.core.internal.contentmodel.tld.provisional.TLDElementDeclaration;
import org.eclipse.jst.jsp.core.internal.contentmodel.tld.provisional.TLDVariable;
import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel;
import org.eclipse.wst.sse.core.internal.provisional.StructuredModelManager;
import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocument;
import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocumentRegion;
import org.eclipse.wst.sse.core.internal.provisional.text.ITextRegion;
import org.eclipse.wst.sse.core.internal.provisional.text.ITextRegionList;
import org.eclipse.wst.sse.core.internal.util.StringUtils;
import org.eclipse.wst.xml.core.internal.contentmodel.CMDocument;
import org.eclipse.wst.xml.core.internal.contentmodel.CMNamedNodeMap;
import org.eclipse.wst.xml.core.internal.contentmodel.CMNode;
import org.eclipse.wst.xml.core.internal.contentmodel.modelquery.ModelQuery;
import org.eclipse.wst.xml.core.internal.modelquery.ModelQueryUtil;
import org.eclipse.wst.xml.core.internal.provisional.contentmodel.CMNodeWrapper;
import org.eclipse.wst.xml.core.internal.regions.DOMRegionContext;

/**
 * This class helps find TaglibVariables in a JSP file.
 * 
 * @author pavery
 */
public class TaglibHelper {

    // for debugging
    private static final boolean DEBUG;
    static {
        String value = Platform.getDebugOption("org.eclipse.jst.jsp.core/debug/taglibvars"); //$NON-NLS-1$
        DEBUG = value != null && value.equalsIgnoreCase("true"); //$NON-NLS-1$
    }

    private IProject fProject = null;
    private TaglibClassLoader fLoader = null;
    
    private Set fProjectEntries = null;
    private Set fContainerEntries = null;
    
    public TaglibHelper(IProject project) {
        setProject(project);
        fProjectEntries = new HashSet();
        fContainerEntries = new HashSet();
    }

    /**
     * @param tagToAdd
     *            is the name of the tag whose variables we want
     * @param structuredDoc
     *            is the IStructuredDocument where the tag is found
     * @param customTag
     *            is the IStructuredDocumentRegion opening tag for the custom
     *            tag
     */
    public TaglibVariable[] getTaglibVariables(String tagToAdd, IStructuredDocument structuredDoc, IStructuredDocumentRegion customTag) {

        List results = new ArrayList();
        ModelQuery mq = getModelQuery(structuredDoc);
        if (mq != null) {
			TLDCMDocumentManager mgr = TaglibController.getTLDCMDocumentManager(structuredDoc);
			
            //TaglibSupport support = ((TaglibModelQuery) mq).getTaglibSupport();
            if (mgr == null)
                return new TaglibVariable[0];
			
			List trackers = mgr.getCMDocumentTrackers(customTag.getEndOffset());
			Iterator taglibs = trackers.iterator();
			
//            TaglibSupport support = ((TaglibModelQuery) mq).getTaglibSupport();
//            if (support == null)
//                return new TaglibVariable[0];
//
//            Iterator taglibs = support.getCMDocuments(customTag.getStartOffset()).iterator();
            CMDocument doc = null;
            CMNamedNodeMap elements = null;
            while (taglibs.hasNext()) {
                doc = (CMDocument) taglibs.next();
                CMNode node = null;
                if ((elements = doc.getElements()) != null && (node = elements.getNamedItem(tagToAdd)) != null && node.getNodeType() == CMNode.ELEMENT_DECLARATION) {

                    if (node instanceof CMNodeWrapper) {
                        node = ((CMNodeWrapper) node).getOriginNode();
                    }

                    // 1.2+ taglib style
                    addVariables(results, node);

                    // for 1.1 need more info from taglib tracker
                    if (doc instanceof TaglibTracker) {
                        String uri = ((TaglibTracker) doc).getURI();
                        String prefix = ((TaglibTracker) doc).getPrefix();
                        // only for 1.1 taglibs
                        addTEIVariables(customTag, results, (TLDElementDeclaration) node, prefix, uri);
                    }
                }
            }
        }

        return (TaglibVariable[]) results.toArray(new TaglibVariable[results.size()]);
    }

    /**
     * Adds 1.2 style TaglibVariables to the results list.
     * 
     * @param results
     *            list where the <code>TaglibVariable</code> s are added
     * @param node
     */
    private void addVariables(List results, CMNode node) {

        List list = ((TLDElementDeclaration) node).getVariables();
        Iterator it = list.iterator();
        while (it.hasNext()) {
            TLDVariable var = (TLDVariable) it.next();
            String varName = var.getNameGiven();
            if (varName == null) {
                varName = var.getNameFromAttribute();
            }
            if (varName != null) {
                String varClass = "java.lang.String"; //$NON-NLS-1$ // the default class...
                if (var.getVariableClass() != null) {
                    varClass = var.getVariableClass();
                }
                results.add(new TaglibVariable(varClass, varName));
            }
        }
    }

    /**
     * Adds 1.1 style TaglibVariables (defined in a TagExtraInfo class) to the
     * results list.
     * 
     * @param customTag
     * @param results
     *            list where the <code>TaglibVariable</code> s are added
     * @param decl
     *            TLDElementDelcaration for the custom tag
     * @param prefix
     *            custom tag prefix
     * @param uri
     *            URI where the tld can be found
     */
    private void addTEIVariables(IStructuredDocumentRegion customTag, List results, TLDElementDeclaration decl, String prefix, String uri) {

        String teiClassname = decl.getTeiclass();
        if (teiClassname == null || teiClassname.length() == 0)
            return;

        ClassLoader loader = getClassloader();
    
        Class teiClass = null;
        try {
            teiClass = Class.forName(teiClassname, true, loader);
            if (teiClass != null) {
                Object teiObject = (TagExtraInfo) teiClass.newInstance();
                if (TagExtraInfo.class.isInstance(teiObject)) {
                    TagExtraInfo tei = (TagExtraInfo) teiObject;
                    Hashtable tagDataTable = extractTagData(customTag);
                    TagInfo info = getTagInfo(decl, tei, prefix, uri);
                    if (info != null) {
                        tei.setTagInfo(info);

                        // add to results
                        TagData td = new TagData(tagDataTable);
                        if (tei.isValid(td)) {
                            VariableInfo[] vInfos = tei.getVariableInfo(td);
                            if(vInfos != null) {
	                            for (int i = 0; i < vInfos.length; i++) {
	                                results.add(new TaglibVariable(vInfos[i].getClassName(), vInfos[i].getVarName()));
	                            }
                            }
                        }
                    }
                }
            }
        } catch (ClassNotFoundException e) {
            // TEI class wasn't on classpath
            if (DEBUG)
                logException(teiClassname, e);
        } catch (InstantiationException e) {
            if (DEBUG)
                logException(teiClassname, e);
        } catch (IllegalAccessException e) {
            if (DEBUG)
                logException(teiClassname, e);
        } catch (ClassCastException e) {
            // TEI class wasn't really a subclass of TagExtraInfo
            if (DEBUG)
                logException(teiClassname, e);
        } catch (Exception e) {
            // this is 3rd party code, need to catch all exceptions
            if (DEBUG)
                logException(teiClassname, e);
        } catch (Error e) {
            // this is 3rd party code, need to catch all errors
            if (DEBUG)
                logException(teiClassname, e);
        }
        finally {
           // Thread.currentThread().setContextClassLoader(oldLoader);
        }
    }

    /**
     * @param decl
     * @return the TagInfo for the TLDELementDeclaration if the declaration is
     *         valid, otherwise null
     */
    private TagInfo getTagInfo(TLDElementDeclaration decl, TagExtraInfo tei, String prefix, String uri) {

        TagLibraryInfo libInfo = new TagLibraryInfo(prefix, uri) { /*dummy impl*/};

        CMNamedNodeMap attrs = decl.getAttributes();
        TagAttributeInfo[] attrInfos = new TagAttributeInfo[attrs.getLength()];
        TLDAttributeDeclaration attr = null;
        String type = ""; //$NON-NLS-1$ 
        
        // get tag attribute infos
        for (int i = 0; i < attrs.getLength(); i++) {
            attr = (TLDAttributeDeclaration) attrs.item(i);
            type = attr.getType();
            // default value for type is String
            if (attr.getType() == null || attr.getType().equals(""))  //$NON-NLS-1$ 
                type = "java.lang.String"; //$NON-NLS-1$ 
            attrInfos[i] = new TagAttributeInfo(attr.getAttrName(), attr.isRequired(), type, false);
        }
        
        String tagName = decl.getNodeName();
        String tagClass = decl.getTagclass();
        String bodyContent = decl.getBodycontent();
        if (tagName != null && tagClass != null && bodyContent != null)
            return new TagInfo(tagName, tagClass, bodyContent, decl.getInfo(), libInfo, tei, attrInfos);
        return null;

    }

    /**
     * @param e
     */
    private void logException(String teiClassname, Throwable e) {

        String message = "teiClassname: ["; //$NON-NLS-1$ 
        if (teiClassname != null)
            message += teiClassname;
        message += "]";
        Logger.logException(message, e);
    }

    /**
     * Returns all attribute -> value pairs for the tag in a Hashtable.
     * 
     * @param customTag
     * @return
     */
    private Hashtable extractTagData(IStructuredDocumentRegion customTag) {

        Hashtable tagDataTable = new Hashtable();
        ITextRegionList regions = customTag.getRegions();
        ITextRegion r = null;
        String attrName = "";
        String attrValue = "";
        for (int i = 0; i < regions.size(); i++) {
            r = regions.get(i);
            // check if attr name
            if (r.getType() == DOMRegionContext.XML_TAG_ATTRIBUTE_NAME) {
                attrName = customTag.getText(r);
                // check equals is next region
                if (regions.size() > ++i) {
                    r = regions.get(i);
                    if (r.getType() == DOMRegionContext.XML_TAG_ATTRIBUTE_EQUALS && regions.size() > ++i) {
                        // get attr value
                        r = regions.get(i);
                        if (r.getType() == DOMRegionContext.XML_TAG_ATTRIBUTE_VALUE) {
                            r = regions.get(i);
                            // attributes in our document have quotes, so we
                            // need to strip them
                            attrValue = StringUtils.stripQuotes(customTag.getText(r));
                            tagDataTable.put(attrName, attrValue);
                        }
                    }
                }
            }
        }
        return tagDataTable;
    }

    private ClassLoader getClassloader() {
        
        if(fLoader == null) {
	        fLoader = new TaglibClassLoader(this.getClass().getClassLoader());
	        fProjectEntries.clear();
	        fContainerEntries.clear();
	        addClasspathEntriesForProject(getProject(), fLoader);
        }
        return fLoader;
    }

    /**
     * @param loader
     */
    private void addClasspathEntriesForProject(IProject p, TaglibClassLoader loader) {
       
        // avoid infinite recursion
        if(fProjectEntries.contains(p.getFullPath().toString()))
            return;
        fProjectEntries.add(p.getFullPath().toString());
    
       // add things on classpath that we are interested in
        if (p != null) {
        	try {
	        	if(p.hasNature(JavaCore.NATURE_ID)) {
	        		
		            IJavaProject project = JavaCore.create(p);
		            IPath wkspaceRoot = ResourcesPlugin.getWorkspace().getRoot().getLocation();
		
		            try {
		                IClasspathEntry[] entries = project.getRawClasspath();
		                addDefaultDirEntry(loader, project, wkspaceRoot);
		                addClasspathEntries(loader, project, wkspaceRoot, entries);        
		            } catch (JavaModelException e) {
		            	Logger.logException(e);
		            }
	        	}
        	}
        	catch(CoreException e) {
        		Logger.logException(e);
        	}
        }
    }

	private void addClasspathEntries(TaglibClassLoader loader, IJavaProject project, IPath wkspaceRoot, IClasspathEntry[] entries) throws JavaModelException {
		IClasspathEntry entry;
		for (int i = 0; i < entries.length; i++) {

		    entry = entries[i];
		    if(DEBUG)
		        System.out.println("current entry is: " + entry);
		    
		    switch (entry.getEntryKind()) {
		        case IClasspathEntry.CPE_SOURCE:
		            addSourceEntry(loader, wkspaceRoot, entry);
		            break;
		        case IClasspathEntry.CPE_LIBRARY:
		            addLibraryEntry(loader, wkspaceRoot, entry.getPath().toString());
		            break;
		        case IClasspathEntry.CPE_PROJECT:
		            addProjectEntry(loader, entry); 
		            break;
		        case IClasspathEntry.CPE_VARIABLE:
		            addVariableEntry(loader, wkspaceRoot, entry);
		            break;
		        case IClasspathEntry.CPE_CONTAINER:
		            addContainerEntry(loader, project, wkspaceRoot, entry);
		            break;
		    }
		}
	}

    /**
     * @param loader
     * @param entry
     */
    private void addVariableEntry(TaglibClassLoader loader, IPath wkspaceRoot, IClasspathEntry entry) {

        if (DEBUG)
            System.out.println(" -> adding variable entry: [" + entry + "]");
        
        // variable should either be a project or a library entry

        String variableName = entry.getPath().toString();
        IPath variablePath = JavaCore.getClasspathVariable(variableName);
        
        // RATLC01076854 
        // variable paths may not exist
        // in that case null will be returned
        if(variablePath != null) {
	        if (variablePath.segments().length == 1) {
	            IProject varProj = ResourcesPlugin.getWorkspace().getRoot().getProject(variablePath.toString());
	            if (varProj != null && varProj.exists()) {
	                addClasspathEntriesForProject(varProj, loader);
	                return;
	            }
	        } 
	        addLibraryEntry(loader, wkspaceRoot, variablePath.toString());
        }
    }

    /**
     * @param loader
     * @param project
     * @param wkspaceRoot
     * @param entry
     * @throws JavaModelException
     */
    private void addContainerEntry(TaglibClassLoader loader, IJavaProject project, IPath wkspaceRoot, IClasspathEntry entry) throws JavaModelException {

        IClasspathContainer container = JavaCore.getClasspathContainer(entry.getPath(), project);
        if(container != null) {
        	// avoid infinite recursion
            if(!fContainerEntries.contains(container.getPath().toString())) {                   
                fContainerEntries.add(container.getPath().toString());
                
            	IClasspathEntry[] cpes = container.getClasspathEntries();
            	// recursive call here
            	addClasspathEntries(loader, project, wkspaceRoot, cpes);
            }
        }
    }

    /**
     * @param loader
     * @param entry
     */
    private void addProjectEntry(TaglibClassLoader loader, IClasspathEntry entry) {

        if (DEBUG)
            System.out.println(" -> project entry: [" + entry + "]");
        
        IPath path = entry.getPath();
        IProject refereceProj = ResourcesPlugin.getWorkspace().getRoot().getProject(path.toString());
        if(refereceProj != null && refereceProj.exists())
            addClasspathEntriesForProject(refereceProj, loader);
    }

    /**
     * @param loader
     * @param project
     * @param wkspaceRoot
     * @throws JavaModelException
     */
    private void addDefaultDirEntry(TaglibClassLoader loader, IJavaProject project, IPath wkspaceRoot) throws JavaModelException {

        // add default bin directory for the project
        IPath outputLocation = project.getOutputLocation();
        if (!outputLocation.toFile().exists()) {
            outputLocation = wkspaceRoot.append(outputLocation);
        }
        loader.addDirectory(outputLocation.toString());
    }

    /**
     * @param loader
     * @param wkspaceRoot
     * @param entry
     */
    private void addLibraryEntry(TaglibClassLoader loader, IPath wkspaceRoot, String libPath) {

        String jarPath = libPath;
        File file = new File(jarPath);
        
        // if not absolute path, it's workspace relative
        if (!file.exists()) {
            jarPath = wkspaceRoot.append(jarPath).toString();
        }
        
        if(jarPath.endsWith(".jar")) { //$NON-NLS-1$ 
            loader.addJar(jarPath);
        }
        else if(file.isDirectory()) {
            // it's actually a folder containing binaries
            loader.addDirectory(jarPath);
        }
    }

    /**
     * @param loader
     * @param wkspaceRoot
     * @param entry
     */
    private void addSourceEntry(TaglibClassLoader loader, IPath wkspaceRoot, IClasspathEntry entry) {

        // add bin directory for specific entry if it has
        // one
        if (entry.getOutputLocation() != null) {
            String outputPath = entry.getOutputLocation().toString();
            File file = entry.getOutputLocation().toFile();
            // if not absolute path, it's workspace relative
            if (!file.exists()) {
                outputPath = wkspaceRoot.append(entry.getOutputLocation()).toString();
            }
            loader.addDirectory(outputPath);
        }
    }

    /**
     * @return Returns the fModelQuery.
     */
    public ModelQuery getModelQuery(IDocument doc) {
        IStructuredModel model = null;
        ModelQuery mq = null;
		try {
			model = StructuredModelManager.getModelManager().getExistingModelForRead(doc);
			mq = ModelQueryUtil.getModelQuery(model);
		}
		finally {
		    if(model != null)
		        model.releaseFromRead();
		}
        return mq;
    }


    /**
     * @return Returns the fFile.
     */
    public IProject getProject() {

        return fProject;
    }

    /**
     * @param file
     *            The fFile to set.
     */
    public void setProject(IProject p) {
        fProject = p;
    }
}
