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.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) {
            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) {
                e.printStackTrace();
            }
        }
    }

	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;
    }
}
