package org.eclipse.jst.jsf.facelet.ui.internal.contentassist;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.eclipse.core.resources.IProject;
import org.eclipse.jface.text.ITextViewer;
import org.eclipse.jface.text.contentassist.CompletionProposal;
import org.eclipse.jface.text.contentassist.ICompletionProposal;
import org.eclipse.jface.text.contentassist.IContentAssistProcessor;
import org.eclipse.jface.text.contentassist.IContextInformation;
import org.eclipse.jface.text.contentassist.IContextInformationValidator;
import org.eclipse.jst.jsf.common.runtime.internal.view.model.common.ITagElement;
import org.eclipse.jst.jsf.common.runtime.internal.view.model.common.Namespace;
import org.eclipse.jst.jsf.context.resolver.structureddocument.IDOMContextResolver;
import org.eclipse.jst.jsf.context.resolver.structureddocument.IStructuredDocumentContextResolverFactory;
import org.eclipse.jst.jsf.context.resolver.structureddocument.IWorkspaceContextResolver;
import org.eclipse.jst.jsf.context.resolver.structureddocument.internal.ITextRegionContextResolver;
import org.eclipse.jst.jsf.context.structureddocument.IStructuredDocumentContext;
import org.eclipse.jst.jsf.context.structureddocument.IStructuredDocumentContextFactory;
import org.eclipse.jst.jsf.designtime.internal.view.model.ITagRegistry;
import org.eclipse.jst.jsf.designtime.internal.view.model.TagRegistryFactory.TagRegistryFactoryException;
import org.eclipse.jst.jsf.facelet.core.internal.registry.FaceletRegistryManager.MyRegistryFactory;
import org.eclipse.jst.jsf.facelet.ui.internal.FaceletUiPlugin;
import org.eclipse.wst.xml.core.internal.regions.DOMRegionContext;
import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;

/**
 * Temporary.
 * 
 * @author cbateman
 *
 */
public class XHTMLContentAssistProcessor2 implements IContentAssistProcessor
{
    private final static ICompletionProposal[] NO_PROPOSALS = new ICompletionProposal[0];

    public ICompletionProposal[] computeCompletionProposals(ITextViewer viewer,
            int offset)
    {
        List<ICompletionProposal> proposals = new ArrayList<ICompletionProposal>();
        final IStructuredDocumentContext context = IStructuredDocumentContextFactory.INSTANCE
                .getContext(viewer, offset);

        if (context != null)
        {
            final IDOMContextResolver domContextResolver = IStructuredDocumentContextResolverFactory.INSTANCE
                    .getDOMContextResolver(context);

            final Document doc = domContextResolver.getDOMDocument();

            if (doc == null)
            {
                return NO_PROPOSALS;
            }

            // get the namespaces that are already declared
            final Map<String, PrefixEntry> documentNamespaces = getDocumentNamespaces(doc);

            final ITextRegionContextResolver resolver = IStructuredDocumentContextResolverFactory.INSTANCE
                    .getTextRegionResolver(context);

            if (resolver != null)
            {
                final String regionType = resolver.getRegionType();

                if (DOMRegionContext.XML_CONTENT.equals(regionType))
                {
                    // TODO: this may be in the open it may occur on the inside
                    // of a
                    // "<" that doesn't have any further tag name yet
                    proposals = getTagCompletionsForDocument(context,
                            documentNamespaces, TagPrefix.NO_PREFIX);
                }
                else if (DOMRegionContext.XML_TAG_NAME.equals(regionType))
                {
                    final TagPrefix tagPrefix = new TagPrefix(resolver
                            .getRegionText());
                    proposals = getTagCompletionsForDocument(context,
                            documentNamespaces, tagPrefix);
                }
                else
                {
                    System.out.println(regionType);
                }
            }
        }

        return proposals.toArray(NO_PROPOSALS);
    }

    private List<ICompletionProposal> getTagCompletionsForDocument(
            final IStructuredDocumentContext context,
            final Map<String, PrefixEntry> namespaces, final TagPrefix tagPrefix)
    {
        final List<ICompletionProposal> proposals = new ArrayList<ICompletionProposal>();

        final IWorkspaceContextResolver wkspaceResolver = IStructuredDocumentContextResolverFactory.INSTANCE
                .getWorkspaceContextResolver(context);
        final IProject project = wkspaceResolver.getProject();

        MyRegistryFactory factory = new MyRegistryFactory();
        ITagRegistry registry;
        try
        {
            registry = factory.createTagRegistry(project);
            if (registry == null)
            {
                return proposals;
            }

            final Collection<? extends Namespace> tagLibs = registry
                    .getAllTagLibraries();

            for (final Namespace tagLib : tagLibs)
            {
                final PrefixEntry ns = namespaces.get(tagLib.getNSUri());

                // if the tag library is not initialized, don't trigger
                // a potentially expensive operation during the content assist
                if (ns != null && tagLib.isInitialized())
                {
                    // only add if this namespace's prefix starts with
                    // the prefix that the user provided
                    if (ns._prefix.startsWith(tagPrefix.getPrefix()))
                    {
                        final Collection<?> tags = tagLib.getViewElements();

                        for (final Iterator<?> it = tags.iterator(); it
                                .hasNext();)
                        {
                            final ITagElement tagElement = (ITagElement) it
                                    .next();

                            // only add an element it starts with the prefix
                            // provided
                            if (tagElement.getName().startsWith(
                                    tagPrefix.getLocalName()))
                            {
                                final String userPrefix = tagPrefix
                                        .getUserPrefix();

                                final String tagName = ns._prefix + ":"
                                        + tagElement.getName();
                                String replacementText = "";
                                if ("".equals(userPrefix))
                                {
                                    replacementText = "<" + tagName + "></"
                                            + tagName + ">";
                                }
                                else
                                {
                                    replacementText = tagName
                                            .substring(userPrefix.length());
                                }
                                proposals.add(new CompletionProposal(
                                        replacementText, context
                                                .getDocumentPosition(), 0, 0,
                                        null, tagName, null, null));
                            }
                        }
                    }
                }
            }
        }
        catch (TagRegistryFactoryException e)
        {
            FaceletUiPlugin.log(e);
        }

        return proposals;
    }

    private Map<String, PrefixEntry> getDocumentNamespaces(Document doc)
    {
        final Map<String, PrefixEntry> namespaces = new HashMap<String, PrefixEntry>();

        Element rootElement = doc.getDocumentElement();

        if (rootElement != null)
        {
            NamedNodeMap attrs = rootElement.getAttributes();
            for (int i = 0; i < attrs.getLength(); i++)
            {
                Attr a = (Attr) attrs.item(i);
                PrefixEntry ns = PrefixEntry.parseNamespace(a);
                if (ns != null)
                {
                    namespaces.put(ns.getUri(), ns);
                }
            }
        }

        return namespaces;
    }

    private static class TagPrefix
    {
        public final static TagPrefix NO_PREFIX = new TagPrefix("");

        private final String          _prefix;
        private final String          _localName;
        private final boolean         _hasColon;

        public TagPrefix(final String tagName)
        {
            int prefixIdx = tagName.indexOf(':');

            if (prefixIdx != -1)
            {
                _prefix = tagName.substring(0, prefixIdx);
                _hasColon = true;
                if (tagName.length() > prefixIdx)
                {
                    _localName = tagName.substring(prefixIdx + 1);
                }
                else
                {
                    _localName = "";
                }
            }
            else
            {
                _hasColon = false;
                _prefix = tagName;
                _localName = "";
            }
        }

        public String getUserPrefix()
        {
            String userPrefix = _prefix;

            if (_hasColon)
            {
                userPrefix += ":";
                userPrefix += _localName;
            }

            return userPrefix;
        }

        public String getPrefix()
        {
            return _prefix;
        }

        public String getLocalName()
        {
            return _localName;
        }
    }

    private static class PrefixEntry
    {
        private final String _uri;
        private final String _prefix;

        public static PrefixEntry parseNamespace(Attr attr)
        {
            final String prefix = attr.getPrefix();

            if ("xmlns".equals(prefix))
            {
                final String prefixName = attr.getLocalName();
                if (prefixName != null)
                {
                    final String uri = attr.getNodeValue();

                    if (uri != null)
                    {
                        return new PrefixEntry(uri, prefixName);
                    }
                }
            }

            return null;
        }

        public PrefixEntry(final String uri, final String prefix)
        {
            _uri = uri;
            _prefix = prefix;
        }

        public final String getUri()
        {
            return _uri;
        }

        public int hashCode()
        {
            return _uri.hashCode();
        }

        public boolean equals(Object obj)
        {
            return _uri.equals(obj);
        }
    }

    public IContextInformation[] computeContextInformation(ITextViewer viewer,
            int offset)
    {
        return null;
    }

    public char[] getCompletionProposalAutoActivationCharacters()
    {
        return null;
    }

    public char[] getContextInformationAutoActivationCharacters()
    {
        return null;
    }

    public IContextInformationValidator getContextInformationValidator()
    {
        return null;
    }

    public String getErrorMessage()
    {
        return null;
    }

}
