/*
 * 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 org.jetbrains.idea.devkit.dom;

import com.intellij.ide.highlighter.XmlFileType;
import com.intellij.openapi.fileTypes.FileType;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleUtilCore;
import com.intellij.openapi.paths.PathReference;
import com.intellij.openapi.paths.PathReferenceManager;
import com.intellij.openapi.paths.PathReferenceProvider;
import com.intellij.openapi.paths.StaticPathReferenceProvider;
import com.intellij.openapi.roots.ModuleRootManager;
import com.intellij.openapi.util.Condition;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiFileSystemItem;
import com.intellij.psi.PsiReference;
import com.intellij.psi.impl.source.resolve.reference.impl.providers.FileReferenceSet;
import com.intellij.psi.xml.XmlElement;
import com.intellij.psi.xml.XmlFile;
import com.intellij.util.Processor;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.xml.ConvertContext;
import com.intellij.util.xml.DomFileElement;
import com.intellij.util.xml.DomUtil;
import com.intellij.util.xml.GenericAttributeValue;
import com.intellij.util.xml.converters.PathReferenceConverter;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.idea.devkit.util.DescriptorUtil;
import org.jetbrains.jps.model.java.JavaModuleSourceRootTypes;

import java.util.*;

public class DependencyConfigFileConverter extends PathReferenceConverter {

  private static final PathReferenceProvider ourProvider = new StaticPathReferenceProvider(null) {

    @Override
    public boolean createReferences(@NotNull final PsiElement psiElement,
                                    int offset,
                                    String text,
                                    @NotNull List<PsiReference> references,
                                    boolean soft) {
      FileReferenceSet set = new FileReferenceSet(text, psiElement, offset, null,
                                                  true, true,
                                                  new FileType[]{XmlFileType.INSTANCE}) {

        private final Condition<PsiFileSystemItem> PLUGIN_XML_CONDITION = new Condition<PsiFileSystemItem>() {
          @Override
          public boolean value(PsiFileSystemItem item) {
            return !item.isDirectory() &&
                   !item.equals(getContainingFile()) &&
                   (item instanceof XmlFile && DescriptorUtil.isPluginXml((PsiFile)item)) &&
                   !isAlreadyUsed((XmlFile)item);
          }
        };

        private boolean isAlreadyUsed(final XmlFile xmlFile) {
          final PsiFile file = getContainingFile();
          if (!(file instanceof XmlFile)) return false;
          final DomFileElement<IdeaPlugin> ideaPlugin = DescriptorUtil.getIdeaPlugin((XmlFile)file);
          if (ideaPlugin == null) return false;
          return !ContainerUtil.process(ideaPlugin.getRootElement().getDependencies(), new Processor<Dependency>() {
            @Override
            public boolean process(Dependency dependency) {
              final GenericAttributeValue<PathReference> configFileAttribute = dependency.getConfigFile();
              if (!DomUtil.hasXml(configFileAttribute)) return true;
              final PathReference pathReference = configFileAttribute.getValue();
              if (pathReference == null) return true;
              return !xmlFile.equals(pathReference.resolve());
            }
          });
        }

        @NotNull
        @Override
        public Collection<PsiFileSystemItem> computeDefaultContexts() {
          final PsiFile containingFile = getContainingFile();
          if (containingFile == null) {
            return Collections.emptyList();
          }

          final Module module = ModuleUtilCore.findModuleForPsiElement(getElement());
          if (module == null) {
            return Collections.emptyList();
          }

          final Set<VirtualFile> roots = new HashSet<VirtualFile>();
          final VirtualFile parent = containingFile.getVirtualFile().getParent();
          roots.add(parent);

          for (VirtualFile sourceRoot : ModuleRootManager.getInstance(module).getSourceRoots(JavaModuleSourceRootTypes.PRODUCTION)) {
            roots.add(sourceRoot.findChild("META-INF"));
          }
          return toFileSystemItems(roots);
        }

        @Override
        protected boolean isSoft() {
          return true;
        }

        @Override
        protected Condition<PsiFileSystemItem> getReferenceCompletionFilter() {
          return PLUGIN_XML_CONDITION;
        }
      };
      Collections.addAll(references, set.getAllReferences());
      return true;
    }
  };

  @Override
  public PathReference fromString(@Nullable String s, ConvertContext context) {
    final XmlElement element = context.getXmlElement();
    final Module module = context.getModule();
    if (s == null || element == null || module == null) {
      return null;
    }
    return PathReferenceManager.getInstance().getCustomPathReference(s, module, element, ourProvider);
  }

  @NotNull
  @Override
  public PsiReference[] createReferences(@NotNull PsiElement psiElement, boolean soft) {
    return PathReferenceManager.getInstance().createCustomReferences(psiElement,
                                                                     soft,
                                                                     ourProvider);
  }
}
