/*
 * 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.projectview.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.BuildFile;
import com.google.idea.blaze.base.lang.buildfile.references.BuildReferenceManager;
import com.google.idea.blaze.base.lang.buildfile.references.FileLookupData;
import com.google.idea.blaze.base.lang.buildfile.references.FileLookupData.PathFormat;
import com.google.idea.blaze.base.lang.buildfile.references.LabelUtils;
import com.google.idea.blaze.base.lang.buildfile.references.QuoteType;
import com.google.idea.blaze.base.lang.projectview.psi.ProjectViewPsiSectionItem;
import com.google.idea.blaze.base.lang.projectview.psi.util.ProjectViewElementGenerator;
import com.google.idea.blaze.base.model.primitives.Label;
import com.intellij.lang.ASTNode;
import com.intellij.openapi.util.TextRange;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiReferenceBase;
import com.intellij.util.ArrayUtil;
import com.intellij.util.IncorrectOperationException;
import javax.annotation.Nullable;

/** A blaze label reference. */
public class ProjectViewLabelReference extends PsiReferenceBase<ProjectViewPsiSectionItem> {

  private final PathFormat pathFormat;

  public ProjectViewLabelReference(ProjectViewPsiSectionItem element, PathFormat pathFormat) {
    super(element, new TextRange(0, element.getTextLength()));
    this.pathFormat = pathFormat;
  }

  @Nullable
  @Override
  public PsiElement resolve() {
    Label label = getLabel(myElement.getText());
    if (label == null) {
      return null;
    }
    return BuildReferenceManager.getInstance(myElement.getProject()).resolveLabel(label);
  }

  @Nullable
  private static Label getLabel(@Nullable String labelString) {
    if (labelString == null || !labelString.startsWith("//") || labelString.indexOf('*') != -1) {
      return null;
    }
    return LabelUtils.createLabelFromString(null, labelString);
  }

  @Override
  public Object[] getVariants() {
    String labelString = LabelUtils.trimToDummyIdentifier(myElement.getText());
    return ArrayUtil.mergeArrays(getRuleLookups(labelString), getFileLookups(labelString));
  }

  private BuildLookupElement[] getRuleLookups(String labelString) {
    if (!labelString.startsWith("//") || !labelString.contains(":")) {
      return BuildLookupElement.EMPTY_ARRAY;
    }
    String packagePrefix = LabelUtils.getPackagePathComponent(labelString);
    BuildFile referencedBuildFile =
        BuildReferenceManager.getInstance(myElement.getProject())
            .resolveBlazePackage(packagePrefix);
    if (referencedBuildFile == null) {
      return BuildLookupElement.EMPTY_ARRAY;
    }
    return LabelRuleLookupElement.collectAllRules(
        referencedBuildFile, labelString, packagePrefix, null, QuoteType.NoQuotes);
  }

  private BuildLookupElement[] getFileLookups(String labelString) {
    if (pathFormat == PathFormat.NonLocalWithoutInitialBackslashes) {
      labelString = StringUtil.trimStart(labelString, "-");
    }
    FileLookupData lookupData =
        FileLookupData.nonLocalFileLookup(labelString, null, QuoteType.NoQuotes, pathFormat);
    if (lookupData == null) {
      return BuildLookupElement.EMPTY_ARRAY;
    }
    return BuildReferenceManager.getInstance(myElement.getProject())
        .resolvePackageLookupElements(lookupData);
  }

  @Override
  public PsiElement bindToElement(PsiElement element) throws IncorrectOperationException {
    return myElement;
  }

  @Override
  public PsiElement handleElementRename(String newElementName) throws IncorrectOperationException {
    String currentString = myElement.getText();
    Label label = getLabel(currentString);
    if (label == null) {
      return myElement;
    }
    String ruleName = label.ruleName().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 replacement =
        ProjectViewElementGenerator.createReplacementItemNode(myElement, newStringContents);
    if (replacement != null) {
      myElement.getNode().replaceAllChildrenToChildrenOf(replacement);
    }
    return myElement;
  }
}
