/*
 * Copyright 2000-2014 JetBrains s.r.o.
 *
 * 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 com.intellij.xml.index;

import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleUtilCore;
import com.intellij.openapi.project.DumbService;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiFile;
import com.intellij.psi.xml.XmlFile;
import com.intellij.util.NullableFunction;
import com.intellij.util.indexing.DataIndexer;
import com.intellij.util.indexing.FileBasedIndex;
import com.intellij.util.indexing.FileContent;
import com.intellij.util.indexing.ID;
import com.intellij.util.io.DataExternalizer;
import com.intellij.util.text.CharArrayUtil;
import com.intellij.xml.util.XmlUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.io.DataInput;
import java.io.DataOutput;
import java.io.File;
import java.io.IOException;
import java.util.*;

/**
 * @author Dmitry Avdeev
 */
public class XmlNamespaceIndex extends XmlIndex<XsdNamespaceBuilder> {

  @Nullable
  public static String getNamespace(@NotNull VirtualFile file, final Project project, PsiFile context) {
    if (DumbService.isDumb(project) || (context != null && XmlUtil.isStubBuilding())) {
      try {
        return XsdNamespaceBuilder.computeNamespace(file.getInputStream());
      }
      catch (IOException e) {
        return null;
      }
    }
    final List<XsdNamespaceBuilder> list = FileBasedIndex.getInstance().getValues(NAME, file.getUrl(), createFilter(project));
    return list.size() == 0 ? null : list.get(0).getNamespace();
  }

  public static List<IndexedRelevantResource<String, XsdNamespaceBuilder>> getResourcesByNamespace(String namespace,
                                                                                                   @NotNull Project project,
                                                                                                   @Nullable Module module) {
    List<IndexedRelevantResource<String, XsdNamespaceBuilder>> resources =
      IndexedRelevantResource.getResources(NAME, namespace, module, project, null);
    Collections.sort(resources);
    return resources;
  }

  public static List<IndexedRelevantResource<String, XsdNamespaceBuilder>> getAllResources(@Nullable final Module module,
                                                                                           @NotNull Project project,
                                                                                           @Nullable NullableFunction<List<IndexedRelevantResource<String, XsdNamespaceBuilder>>, IndexedRelevantResource<String, XsdNamespaceBuilder>> chooser) {
    return IndexedRelevantResource.getAllResources(NAME, module, project, chooser);
  }
  
  public static final ID<String,XsdNamespaceBuilder> NAME = ID.create("XmlNamespaces");

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

  @Override
  @NotNull
  public DataIndexer<String, XsdNamespaceBuilder, FileContent> getIndexer() {
    return new DataIndexer<String, XsdNamespaceBuilder, FileContent>() {
      @Override
      @NotNull
      public Map<String, XsdNamespaceBuilder> map(@NotNull final FileContent inputData) {
        final XsdNamespaceBuilder builder;
        if ("dtd".equals(inputData.getFile().getExtension())) {
          builder = new XsdNamespaceBuilder(inputData.getFileName(), "", Collections.<String>emptyList());
        }
        else {
          builder = XsdNamespaceBuilder.computeNamespace(CharArrayUtil.readerFromCharSequence(inputData.getContentAsText()));
        }
        final HashMap<String, XsdNamespaceBuilder> map = new HashMap<String, XsdNamespaceBuilder>(2);
        String namespace = builder.getNamespace();
        if (namespace != null) {
          map.put(namespace, builder);
        }
        // so that we could get ns by file url (see getNamespace method above)
        map.put(inputData.getFile().getUrl(), builder);
        return map;
      }
    };
  }

  @NotNull
  @Override
  public DataExternalizer<XsdNamespaceBuilder> getValueExternalizer() {
    return new DataExternalizer<XsdNamespaceBuilder>() {
      @Override
      public void save(@NotNull DataOutput out, XsdNamespaceBuilder value) throws IOException {
        out.writeUTF(value.getNamespace() == null ? "" : value.getNamespace());
        out.writeUTF(value.getVersion() == null ? "" : value.getVersion());
        out.writeInt(value.getTags().size());
        for (String s : value.getTags()) {
          out.writeUTF(s);
        }
      }

      @Override
      public XsdNamespaceBuilder read(@NotNull DataInput in) throws IOException {

        int count;
        XsdNamespaceBuilder builder = new XsdNamespaceBuilder(in.readUTF(), in.readUTF(), new ArrayList<String>(count = in.readInt()));
        for (int i = 0; i < count; i++) {
          builder.getTags().add(in.readUTF());
        }
        return builder;
      }
    };
  }

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

  @Nullable
  public static IndexedRelevantResource<String, XsdNamespaceBuilder> guessSchema(String namespace,
                                                                                 @Nullable final String tagName,
                                                                                 @Nullable final String version,
                                                                                 @Nullable Module module,
                                                                                 @NotNull Project project) {

    final List<IndexedRelevantResource<String, XsdNamespaceBuilder>>
      resources = getResourcesByNamespace(namespace, project, module);

    if (resources.isEmpty()) return null;

    return Collections
      .max(resources, new Comparator<IndexedRelevantResource<String, XsdNamespaceBuilder>>() {
        @Override
        public int compare(IndexedRelevantResource<String, XsdNamespaceBuilder> o1,
                           IndexedRelevantResource<String, XsdNamespaceBuilder> o2) {
          int i = o1.compareTo(o2);
          return i == 0 ? o1.getValue().getRating(tagName, version) - o2.getValue().getRating(tagName, version) : i;
        }
      });
  }

  @Nullable
  public static XmlFile guessSchema(String namespace,
                                    @Nullable final String tagName,
                                    @Nullable final String version,
                                    @NotNull PsiFile file) {

    if (DumbService.isDumb(file.getProject()) || XmlUtil.isStubBuilding()) return null;

    IndexedRelevantResource<String,XsdNamespaceBuilder> resource =
      guessSchema(namespace, tagName, version, ModuleUtilCore.findModuleForPsiElement(file), file.getProject());
    if (resource == null) return null;
    return findSchemaFile(resource.getFile(), file);
  }

  @Nullable
  private static XmlFile findSchemaFile(VirtualFile resourceFile, PsiFile baseFile) {
    PsiFile psiFile = baseFile.getManager().findFile(resourceFile);
    return psiFile instanceof XmlFile ? (XmlFile)psiFile : null;
  }

  @Nullable
  public static XmlFile guessDtd(String dtdUri, @NotNull PsiFile baseFile) {

    if (!dtdUri.endsWith(".dtd") ||
        DumbService.isDumb(baseFile.getProject()) ||
        XmlUtil.isStubBuilding()) return null;

    String dtdFileName = new File(dtdUri).getName();
    List<IndexedRelevantResource<String, XsdNamespaceBuilder>>
      list = getResourcesByNamespace(dtdFileName, baseFile.getProject(), ModuleUtilCore.findModuleForPsiElement(baseFile));
    if (list.isEmpty()) {
      return null;
    }
    IndexedRelevantResource<String, XsdNamespaceBuilder> resource;
    if (list.size() > 1) {
      final String[] split = dtdUri.split("/");
      resource = Collections.max(list, new Comparator<IndexedRelevantResource<String, XsdNamespaceBuilder>>() {
        @Override
        public int compare(IndexedRelevantResource<String, XsdNamespaceBuilder> o1,
                           IndexedRelevantResource<String, XsdNamespaceBuilder> o2) {

          return weight(o1) - weight(o2);
        }

        int weight(IndexedRelevantResource<String, XsdNamespaceBuilder> o1) {
          VirtualFile file = o1.getFile();
          for (int i = split.length - 1; i >= 0 && file != null; i--) {
            String s = split[i];
            if (!s.equals(file.getName())) {
              return split.length - i;
            }
            file = file.getParent();
          }
          return 0;
        }
      });
    }
    else {
      resource = list.get(0);
    }
    return findSchemaFile(resource.getFile(), baseFile);
  }
}
