/*
 * 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.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.vfs.VfsUtilCore;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.util.PairConvertor;
import com.intellij.util.containers.EncoderDecoder;
import com.intellij.util.containers.MultiMap;
import com.intellij.util.containers.hash.HashMap;
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 org.jetbrains.annotations.NotNull;

import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * Created with IntelliJ IDEA.
 * User: Irina.Chernushina
 * Date: 7/4/12
 * Time: 6:29 PM
 *
 * map: tag name->file url
 */
public class SchemaTypeInheritanceIndex extends XmlIndex<Set<SchemaTypeInfo>> {
  private static final ID<String, Set<SchemaTypeInfo>> NAME = ID.create("SchemaTypeInheritance");
  private static final Logger LOG = Logger.getInstance("#com.intellij.xml.index.SchemaTypeInheritanceIndex");

  private static List<Set<SchemaTypeInfo>> getDirectChildrenOfType(final Project project,
                                                                  final String ns,
                                                                  final String name) {
    GlobalSearchScope filter = createFilter(project);
    final List<Set<SchemaTypeInfo>>
      list = FileBasedIndex.getInstance().getValues(NAME, NsPlusTag.INSTANCE.encode(Pair.create(ns, name)), filter);
    return list;
  }

  public static PairConvertor<String, String, List<Set<SchemaTypeInfo>>> getWorker(final Project project, final VirtualFile currentFile) {
    return new MyWorker(currentFile, project);
  }

  private static class MyWorker implements PairConvertor<String, String, List<Set<SchemaTypeInfo>>> {
    private final Project myProject;
    private final VirtualFile myCurrentFile;
    private final GlobalSearchScope myFilter;
    private final boolean myShouldParseCurrent;
    private MultiMap<SchemaTypeInfo,SchemaTypeInfo> myMap;

    private MyWorker(VirtualFile currentFile, Project project) {
      myCurrentFile = currentFile;
      myProject = project;

      myFilter = createFilter(project);
      myShouldParseCurrent = (myCurrentFile != null && ! myFilter.contains(myCurrentFile));
    }

    @Override
    public List<Set<SchemaTypeInfo>> convert(String ns, String name) {
      List<Set<SchemaTypeInfo>> type = getDirectChildrenOfType(myProject, ns, name);
      if (myShouldParseCurrent) {
        if (myMap == null) {
          try {
            myMap = XsdComplexTypeInfoBuilder.parse(CharArrayUtil.readerFromCharSequence(VfsUtilCore.loadText(myCurrentFile)));
            type.add(new HashSet<SchemaTypeInfo>(myMap.get(new SchemaTypeInfo(name, true, ns))));
          }
          catch (IOException e) {
            LOG.info(e);
          }
        }
      }
      return type;
    }
  }

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

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

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

  @NotNull
  @Override
  public DataIndexer<String, Set<SchemaTypeInfo>, FileContent> getIndexer() {
    return new DataIndexer<String, Set<SchemaTypeInfo>, FileContent>() {
      @NotNull
      @Override
      public Map<String, Set<SchemaTypeInfo>> map(@NotNull FileContent inputData) {
        final Map<String, Set<SchemaTypeInfo>> map = new HashMap<String, Set<SchemaTypeInfo>>();
        final MultiMap<SchemaTypeInfo,SchemaTypeInfo> multiMap =
          XsdComplexTypeInfoBuilder.parse(CharArrayUtil.readerFromCharSequence(inputData.getContentAsText()));
        for (SchemaTypeInfo key : multiMap.keySet()) {
          map.put(NsPlusTag.INSTANCE.encode(Pair.create(key.getNamespaceUri(), key.getTagName())), new HashSet<SchemaTypeInfo>(multiMap.get(key)));
        }
        return map;
      }
    };
  }

  @NotNull
  @Override
  public DataExternalizer<Set<SchemaTypeInfo>> getValueExternalizer() {
    return new DataExternalizer<Set<SchemaTypeInfo>>() {
      @Override
      public void save(@NotNull DataOutput out, Set<SchemaTypeInfo> value) throws IOException {
        out.writeInt(value.size());
        for (SchemaTypeInfo key : value) {
          out.writeUTF(key.getNamespaceUri());
          out.writeUTF(key.getTagName());
          out.writeBoolean(key.isIsTypeName());
        }
      }

      @Override
      public Set<SchemaTypeInfo> read(@NotNull DataInput in) throws IOException {
        final Set<SchemaTypeInfo> set = new HashSet<SchemaTypeInfo>();
        final int size = in.readInt();
        for (int i = 0; i < size; i++) {
          final String nsUri = in.readUTF();
          final String tagName = in.readUTF();
          final boolean isType = in.readBoolean();
          set.add(new SchemaTypeInfo(tagName, isType, nsUri));
        }
        return set;
      }
    };
  }

  private static class NsPlusTag implements EncoderDecoder<Pair<String, String>, String> {
    private final static NsPlusTag INSTANCE = new NsPlusTag();
    private final static char ourSeparator = ':';

    @Override
    public String encode(Pair<String, String> pair) {
      return pair.getFirst() + ourSeparator + pair.getSecond();
    }

    @Override
    public Pair<String, String> decode(String s) {
      final int i = s.indexOf(ourSeparator);
      return i <= 0 ? Pair.create("", s) : Pair.create(s.substring(0, i), s.substring(i + 1));
    }
  }
}
