/*
 * 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.testAssistant;

import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.ProjectFileIndex;
import com.intellij.openapi.roots.ProjectRootManager;
import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.TextRange;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.newvfs.ManagingFS;
import com.intellij.psi.*;
import com.intellij.psi.impl.source.resolve.reference.impl.providers.FileInfoManager;
import com.intellij.psi.impl.source.resolve.reference.impl.providers.FileReference;
import com.intellij.psi.impl.source.resolve.reference.impl.providers.FileReferenceSet;
import com.intellij.util.ArrayUtil;
import com.intellij.util.ProcessingContext;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.Collection;

import static com.intellij.patterns.PsiJavaPatterns.literalExpression;
import static org.jetbrains.idea.devkit.testAssistant.TestDataLineMarkerProvider.*;

/**
 * @author zolotov
 * @since 9/20/13
 */
public class TestDataReferenceContributor extends PsiReferenceContributor {
  @Override
  public void registerReferenceProviders(@NotNull PsiReferenceRegistrar registrar) {
    registrar.registerReferenceProvider(literalExpression().annotationParam(TEST_DATA_PATH_ANNOTATION_QUALIFIED_NAME),
                                        new TestDataReferenceProvider());
  }

  private static class TestDataReferenceProvider extends PsiReferenceProvider {
    @NotNull
    @Override
    public PsiReference[] getReferencesByElement(@NotNull final PsiElement element, @NotNull final ProcessingContext context) {
      final TestDataReferenceSet referenceSet = new TestDataReferenceSet(element);
      referenceSet.addCustomization(FileReferenceSet.DEFAULT_PATH_EVALUATOR_OPTION, FileReferenceSet.ABSOLUTE_TOP_LEVEL);
      return referenceSet.getAllReferences();
    }
  }

  private static class TestDataReferenceSet extends FileReferenceSet {
    public TestDataReferenceSet(@NotNull PsiElement element) {
      super(element);
    }

    @Override
    public boolean isEmptyPathAllowed() {
      return false;
    }

    @Override
    public boolean isAbsolutePathReference() {
      return super.isAbsolutePathReference() || StringUtil.startsWithChar(getPathString(), '$');
    }

    @Override
    public FileReference createFileReference(TextRange range, int index, String text) {
      return new TestDataReference(this, range, index, text);
    }

    @NotNull
    @Override
    public Collection<PsiFileSystemItem> computeDefaultContexts() {
      return toFileSystemItems(ManagingFS.getInstance().getLocalRoots());
    }

    @Override
    protected Condition<PsiFileSystemItem> getReferenceCompletionFilter() {
      return DIRECTORY_FILTER;
    }
  }

  public static class TestDataReference extends FileReference {
    public TestDataReference(@NotNull FileReferenceSet fileReferenceSet, TextRange range, int index, String text) {
      super(fileReferenceSet, range, index, text);
    }

    @NotNull
    @Override
    public Object[] getVariants() {
      if (getIndex() == 0 && !StringUtil.startsWithChar(getFileReferenceSet().getPathString(), '/')) {
        Collection<Object> variants = ContainerUtil.newHashSet(super.getVariants());
        final PsiDirectory projectPsiRoot = getProjectPsiRoot();
        if (projectPsiRoot != null) {
          variants.add(FileInfoManager.getFileLookupItem(projectPsiRoot, PROJECT_ROOT_VARIABLE, projectPsiRoot.getIcon(0))
                         .withTypeText(projectPsiRoot.getVirtualFile().getPath(), true));
        }

        final PsiDirectory contentPsiRoot = getContentPsiRoot();
        if (contentPsiRoot != null) {
          variants.add(FileInfoManager.getFileLookupItem(contentPsiRoot, CONTENT_ROOT_VARIABLE, contentPsiRoot.getIcon(0))
                         .withTypeText(contentPsiRoot.getVirtualFile().getPath(), true));
        }
        return ArrayUtil.toObjectArray(variants);
      }

      return super.getVariants();
    }

    @NotNull
    @Override
    protected ResolveResult[] innerResolve(boolean caseSensitive, @NotNull PsiFile containingFile) {
      if (getIndex() == 0 && StringUtil.startsWithChar(getText(), '$')) {
        if (PROJECT_ROOT_VARIABLE.equals(getText())) {
          final PsiDirectory projectPsiRoot = getProjectPsiRoot();
          if (projectPsiRoot != null) {
            return new ResolveResult[]{new PsiElementResolveResult(projectPsiRoot)};
          }
        }
        else if (CONTENT_ROOT_VARIABLE.equals(getText())) {
          final PsiDirectory contentPsiRoot = getContentPsiRoot();
          if (contentPsiRoot != null) {
            return new ResolveResult[]{new PsiElementResolveResult(contentPsiRoot)};
          }
        }
      }
      return super.innerResolve(caseSensitive, containingFile);
    }

    @Nullable
    private PsiDirectory getProjectPsiRoot() {
      final Project project = getElement().getProject();
      final VirtualFile projectDir = project.getBaseDir();
      if (projectDir != null) {
        final PsiManager psiManager = PsiManager.getInstance(project);
        return psiManager.findDirectory(projectDir);
      }
      return null;
    }

    @Nullable
    private PsiDirectory getContentPsiRoot() {
      final Project project = getElement().getProject();
      final ProjectFileIndex fileIndex = ProjectRootManager.getInstance(project).getFileIndex();
      final VirtualFile file = getElement().getContainingFile().getOriginalFile().getVirtualFile();
      if (file != null) {
        final VirtualFile contentRoot = fileIndex.getContentRootForFile(file);
        if (contentRoot != null) {
          final PsiManager psiManager = PsiManager.getInstance(project);
          return psiManager.findDirectory(contentRoot);
        }
      }
      return null;
    }
  }
}
