/*
 * Copyright 2016 The Bazel Authors. All rights reserved.
 *
 * 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.google.idea.blaze.base.lang.buildfile.references;

import com.google.idea.blaze.base.lang.buildfile.completion.BuildLookupElement;
import com.google.idea.blaze.base.lang.buildfile.completion.LabelRuleLookupElement;
import com.google.idea.blaze.base.lang.buildfile.psi.Argument;
import com.google.idea.blaze.base.lang.buildfile.psi.BuildFile;
import com.google.idea.blaze.base.lang.buildfile.psi.BuildFile.BlazeFileType;
import com.google.idea.blaze.base.lang.buildfile.psi.FuncallExpression;
import com.google.idea.blaze.base.lang.buildfile.psi.LoadStatement;
import com.google.idea.blaze.base.lang.buildfile.psi.StringLiteral;
import com.google.idea.blaze.base.lang.buildfile.psi.util.PsiUtils;
import com.google.idea.blaze.base.lang.buildfile.search.BlazePackage;
import com.google.idea.blaze.base.lang.buildfile.search.ResolveUtil;
import com.google.idea.blaze.base.model.primitives.Label;
import com.intellij.lang.ASTNode;
import com.intellij.openapi.util.TextRange;
import com.intellij.openapi.vfs.VirtualFileFilter;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiReferenceBase;
import com.intellij.util.ArrayUtil;
import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

/** Converts a blaze label into an absolute path, then resolves that path to a PsiElements */
public class LabelReference extends PsiReferenceBase<StringLiteral> {

  public LabelReference(StringLiteral element, boolean soft) {
    super(element, new TextRange(0, element.getTextLength()), soft);
  }

  @Nullable
  @Override
  public PsiElement resolve() {
    /* Possibilities:
     * - target
     * - data file (.java, .txt, etc.)
     * - glob contents (not yet handling globs)
     */
    return resolveTarget(myElement.getStringContents());
  }

  @Nullable
  private PsiElement resolveTarget(String labelString) {
    Label label = getLabel(labelString);
    if (label == null) {
      return null;
    }
    if (!validLabelLocation(myElement)) {
      return null;
    }
    if (!labelString.startsWith("//") && insideSkylarkExtension(myElement)) {
      return getReferenceManager().resolveLabel(label.blazePackage(), label.targetName(), true);
    }
    return getReferenceManager().resolveLabel(label);
  }

  /**
   * Hack: don't include 'name' keyword arguments -- they'll be a reference to the enclosing
   * function call / rule, and show up as unnecessary references to that rule.
   */
  private static boolean validLabelLocation(StringLiteral element) {
    PsiElement parent = element.getParent();
    if (parent instanceof Argument.Keyword) {
      String argName = ((Argument.Keyword) parent).getName();
      if ("name".equals(argName)) {
        return false;
      }
    }
    return true;
  }

  @NotNull
  @Override
  public Object[] getVariants() {
    if (!validLabelLocation(myElement)) {
      return EMPTY_ARRAY;
    }
    String labelString = LabelUtils.trimToDummyIdentifier(myElement.getStringContents());
    return ArrayUtil.mergeArrays(getRuleLookups(labelString), getFileLookups(labelString));
  }

  private BuildLookupElement[] getRuleLookups(String labelString) {
    if (labelString.endsWith("/")
        || (labelString.startsWith("/") && !labelString.contains(":"))
        || skylarkExtensionReference(myElement)) {
      return BuildLookupElement.EMPTY_ARRAY;
    }
    String packagePrefix = LabelUtils.getPackagePathComponent(labelString);
    BuildFile referencedBuildFile =
        LabelUtils.getReferencedBuildFile(myElement.getContainingFile(), packagePrefix);
    if (referencedBuildFile == null) {
      return BuildLookupElement.EMPTY_ARRAY;
    }
    String self = null;
    if (referencedBuildFile == myElement.getContainingFile()) {
      FuncallExpression funcall = PsiUtils.getParentOfType(myElement, FuncallExpression.class);
      if (funcall != null) {
        self = funcall.getName();
      }
    }
    return LabelRuleLookupElement.collectAllRules(
        referencedBuildFile, labelString, packagePrefix, self, myElement.getQuoteType());
  }

  private BuildLookupElement[] getFileLookups(String labelString) {
    if (labelString.startsWith("//") || labelString.equals("/")) {
      return getNonLocalFileLookups(labelString);
    }
    return getPackageLocalFileLookups(labelString);
  }

  private BuildLookupElement[] getNonLocalFileLookups(String labelString) {
    BuildLookupElement[] skylarkExtLookups = getSkylarkExtensionLookups(labelString);
    FileLookupData lookupData = FileLookupData.nonLocalFileLookup(labelString, myElement);
    BuildLookupElement[] packageLookups =
        lookupData != null
            ? getReferenceManager().resolvePackageLookupElements(lookupData)
            : BuildLookupElement.EMPTY_ARRAY;
    return ArrayUtil.mergeArrays(skylarkExtLookups, packageLookups);
  }

  private BuildLookupElement[] getPackageLocalFileLookups(String labelString) {
    if (skylarkExtensionReference(myElement)) {
      return getSkylarkExtensionLookups(labelString);
    }
    FileLookupData lookupData = FileLookupData.packageLocalFileLookup(labelString, myElement);
    return lookupData != null
        ? getReferenceManager().resolvePackageLookupElements(lookupData)
        : BuildLookupElement.EMPTY_ARRAY;
  }

  private BuildLookupElement[] getSkylarkExtensionLookups(String labelString) {
    if (!skylarkExtensionReference(myElement)) {
      return BuildLookupElement.EMPTY_ARRAY;
    }
    String packagePrefix = LabelUtils.getPackagePathComponent(labelString);
    BuildFile parentFile = myElement.getContainingFile();
    if (parentFile == null) {
      return BuildLookupElement.EMPTY_ARRAY;
    }
    BlazePackage containingPackage = BlazePackage.getContainingPackage(parentFile);
    if (containingPackage == null) {
      return BuildLookupElement.EMPTY_ARRAY;
    }
    BuildFile referencedBuildFile =
        LabelUtils.getReferencedBuildFile(containingPackage.buildFile, packagePrefix);

    // Directories before the colon are already covered.
    // We're only concerned with package-local directories.
    boolean hasColon = labelString.indexOf(':') != -1;
    VirtualFileFilter filter =
        file ->
            ("bzl".equals(file.getExtension()) && !file.getPath().equals(parentFile.getFilePath()))
                || (hasColon && file.isDirectory());
    FileLookupData lookupData =
        FileLookupData.packageLocalFileLookup(labelString, myElement, referencedBuildFile, filter);

    return lookupData != null
        ? getReferenceManager().resolvePackageLookupElements(lookupData)
        : BuildLookupElement.EMPTY_ARRAY;
  }

  private BuildReferenceManager getReferenceManager() {
    return BuildReferenceManager.getInstance(myElement.getProject());
  }

  @Override
  public PsiElement bindToElement(PsiElement element) throws IncorrectOperationException {
    PsiFile file = ResolveUtil.asFileSearch(element);
    if (file == null) {
      return super.bindToElement(element);
    }
    if (file.equals(resolve())) {
      return myElement;
    }
    BlazePackage currentPackageDir = myElement.getBlazePackage();
    if (currentPackageDir == null) {
      return myElement;
    }
    BlazePackage newPackageDir = BlazePackage.getContainingPackage(file);
    if (!currentPackageDir.equals(newPackageDir)) {
      return myElement;
    }

    String newRuleName =
        newPackageDir.getPackageRelativePath(file.getViewProvider().getVirtualFile().getPath());
    return handleRename(newRuleName);
  }

  @Override
  public PsiElement handleElementRename(String newElementName) throws IncorrectOperationException {
    String currentString = myElement.getStringContents();
    Label label = getLabel(currentString);
    if (label == null) {
      return myElement;
    }
    String ruleName = label.targetName().toString();
    String newRuleName = newElementName;

    // handle subdirectories
    int lastSlashIndex = ruleName.lastIndexOf('/');
    if (lastSlashIndex != -1) {
      newRuleName = ruleName.substring(0, lastSlashIndex + 1) + newElementName;
    }

    String packageString = LabelUtils.getPackagePathComponent(currentString);
    if (packageString.isEmpty() && !currentString.contains(":")) {
      return handleRename(newRuleName);
    }
    return handleRename(packageString + ":" + newRuleName);
  }

  private PsiElement handleRename(String newStringContents) {
    ASTNode node = myElement.getNode();
    node.replaceChild(
        node.getFirstChildNode(),
        PsiUtils.createNewLabel(myElement.getProject(), newStringContents));
    return myElement;
  }

  @Nullable
  private Label getLabel(String labelString) {
    if (labelString.indexOf('*') != -1) {
      // don't even try to handle globs, yet.
      return null;
    }
    BlazePackage blazePackage = myElement.getBlazePackage();
    return LabelUtils.createLabelFromString(
        blazePackage != null ? blazePackage.buildFile : null, labelString);
  }

  private static boolean skylarkExtensionReference(StringLiteral element) {
    PsiElement parent = element.getParent();
    if (!(parent instanceof LoadStatement)) {
      return false;
    }
    return ((LoadStatement) parent).getImportPsiElement() == element;
  }

  private static boolean insideSkylarkExtension(StringLiteral element) {
    BuildFile containingFile = element.getContainingFile();
    return containingFile != null
        && containingFile.getBlazeFileType() == BlazeFileType.SkylarkExtension;
  }
}
