/*
 * Copyright 2005-2008 Sascha Weinreuter
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.intellij.lang.xpath.xslt.impl;

import com.intellij.navigation.NavigationItem;
import com.intellij.openapi.fileTypes.StdFileTypes;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.JarFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiManager;
import com.intellij.psi.PsiNamedElement;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.xml.XmlFile;
import com.intellij.psi.xml.XmlTag;
import com.intellij.util.ArrayUtil;
import com.intellij.util.indexing.*;
import com.intellij.util.io.*;
import com.intellij.util.text.CharArrayUtil;
import com.intellij.util.xml.NanoXmlUtil;
import org.intellij.lang.xpath.xslt.XsltSupport;
import org.intellij.lang.xpath.xslt.psi.*;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.*;

/*
* Created by IntelliJ IDEA.
* User: sweinreuter
* Date: 15.12.2008
*/
public class XsltSymbolIndex extends FileBasedIndexExtension<String, XsltSymbolIndex.Kind> {
    @NonNls
    public static final ID<String, Kind> NAME = ID.create("XsltSymbolIndex");

    enum Kind {
        PARAM(XsltParameter.class), VARIABLE(XsltVariable.class), TEMPLATE(XsltTemplate.class), ANYTHING(null);

        final Class<? extends XsltElement> myClazz;

        Kind(Class<? extends XsltElement> clazz) {
            myClazz = clazz;
        }

        @Nullable
        public XsltElement wrap(XmlTag tag) {
            final Class<? extends XsltElement> clazz;
            if (myClazz != null) {
                if (!name().toLowerCase().equals(tag.getLocalName())) {
                    return null;
                }
                clazz = myClazz;
            } else {
                try {
                    clazz = valueOf(tag.getLocalName().toUpperCase()).myClazz;
                } catch (IllegalArgumentException e) {
                    return null;
                }
            }
            return XsltElementFactory.getInstance().wrapElement(tag, clazz);
        }
    }

    @Override
    @NotNull
    public ID<String, Kind> getName() {
        return NAME;
    }

    @Override
    @NotNull
    public DataIndexer<String, Kind, FileContent> getIndexer() {
        return new DataIndexer<String, Kind, FileContent>() {
            @Override
            @NotNull
            public Map<String, Kind> map(@NotNull FileContent inputData) {
                CharSequence inputDataContentAsText = inputData.getContentAsText();
                if (CharArrayUtil.indexOf(inputDataContentAsText, XsltSupport.XSLT_NS, 0) == -1) {
                  return Collections.emptyMap();
                }
                final HashMap<String, Kind> map = new HashMap<String, Kind>();
                NanoXmlUtil.parse(CharArrayUtil.readerFromCharSequence(inputData.getContentAsText()), new NanoXmlUtil.IXMLBuilderAdapter() {
                    NanoXmlUtil.IXMLBuilderAdapter attributeHandler;
                    int depth;

                    @Override
                    public void addAttribute(String key, String nsPrefix, String nsURI, String value, String type) throws Exception {
                        if (attributeHandler != null) {
                            attributeHandler.addAttribute(key, nsPrefix, nsURI, value, type);
                        }
                    }

                    @Override
                    public void startElement(String name, String nsPrefix, String nsURI, String systemID, int lineNr) throws Exception {
                        attributeHandler = null;
                        if (depth == 1 && XsltSupport.XSLT_NS.equals(nsURI)) {
                            if ("template".equals(name)) {
                                attributeHandler = new MyAttributeHandler(map, Kind.TEMPLATE);
                            } else if ("variable".equals(name)) {
                                attributeHandler = new MyAttributeHandler(map, Kind.VARIABLE);
                            } else if ("param".equals(name)) {
                                attributeHandler = new MyAttributeHandler(map, Kind.PARAM);
                            }
                        }
                        depth++;
                    }

                    @Override
                    public void endElement(String name, String nsPrefix, String nsURI) throws Exception {
                        attributeHandler = null;
                        depth--;
                    }
                });
                return map;
            }
        };
    }

    @NotNull
    @Override
    public DataExternalizer<Kind> getValueExternalizer() {
        return new EnumDataDescriptor<Kind>(Kind.class);
    }

    @NotNull
    @Override
    public KeyDescriptor<String> getKeyDescriptor() {
        return new EnumeratorStringDescriptor();
    }

    @NotNull
    @Override
    public FileBasedIndex.InputFilter getInputFilter() {
        return new DefaultFileTypeSpecificInputFilter(StdFileTypes.XML) {
            @Override
            public boolean acceptInput(@NotNull VirtualFile file) {
                return !(file.getFileSystem() instanceof JarFileSystem);
            }
        };
    }

    @Override
    public boolean dependsOnFileContent() {
        return true;
    }

    @Override
    public int getVersion() {
        return 0;
    }

    @SuppressWarnings({ "UnusedDeclaration" })
    public static Collection<String> getSymbolNames(Project project) {
        return FileBasedIndex.getInstance().getAllKeys(NAME, project);
    }

    public static NavigationItem[] getSymbolsByName(final String name, Project project, boolean includeNonProjectItems) {
        final GlobalSearchScope scope = includeNonProjectItems ? GlobalSearchScope.allScope(project) : GlobalSearchScope.projectScope(project);
        final SymbolCollector collector = new SymbolCollector(name, project, scope);
        FileBasedIndex.getInstance().processValues(NAME, name, null, collector, scope);
        return collector.getResult();
    }

    private static class MyAttributeHandler extends NanoXmlUtil.IXMLBuilderAdapter {
        private final HashMap<String, Kind> myMap;
        private final Kind myKind;

        public MyAttributeHandler(HashMap<String, Kind> map, Kind k) {
            myMap = map;
            myKind = k;
        }

        @Override
        public void addAttribute(String key, String nsPrefix, String nsURI, String value, String type) throws Exception {
            if (key.equals("name") && (nsURI == null || nsURI.length() == 0) && value != null) {
                if (myMap.put(value, myKind) != null) {
                    myMap.put(value, Kind.ANYTHING);
                }
            }
        }
    }

    private static class SymbolCollector implements FileBasedIndex.ValueProcessor<Kind> {
        private final GlobalSearchScope myScope;
        private final PsiManager myMgr;
        private final String myName;

        private final Collection<NavigationItem> myResult = new ArrayList<NavigationItem>();

        public SymbolCollector(String name, Project project, GlobalSearchScope scope) {
            myMgr = PsiManager.getInstance(project);
            myScope = scope;
            myName = name;
        }

        @Override
        public boolean process(VirtualFile file, Kind kind) {
            if (myScope.contains(file)) {
                final PsiFile psiFile = myMgr.findFile(file);
                if (XsltSupport.isXsltFile(psiFile)) {
                    final XmlTag[] tags;
                    try {
                        final XmlTag root = ((XmlFile)psiFile).getDocument().getRootTag();
                        if (kind == Kind.ANYTHING) {
                            final XmlTag[] v = root.findSubTags("variable", XsltSupport.XSLT_NS);
                            final XmlTag[] p = root.findSubTags("param", XsltSupport.XSLT_NS);
                            final XmlTag[] t = root.findSubTags("template", XsltSupport.XSLT_NS);
                            tags = ArrayUtil.mergeArrays(ArrayUtil.mergeArrays(v, p), t);
                        } else {
                            tags = root.findSubTags(kind.name().toLowerCase(), XsltSupport.XSLT_NS);
                        }
                    } catch (NullPointerException e) {
                        // something is null, don't bother
                        return true;
                    }

                    for (XmlTag tag : tags) {
                        assert XsltSupport.isXsltTag(tag);

                        final XsltElement el = kind.wrap(tag);
                        if (el instanceof PsiNamedElement && el instanceof NavigationItem) {
                            if (myName.equals(((PsiNamedElement)el).getName())) {
                                myResult.add((NavigationItem)el);
                            }
                        }
                    }
                }
            }
          return true;
        }

        public NavigationItem[] getResult() {
            return myResult.toArray(new NavigationItem[myResult.size()]);
        }
    }
}
