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

import static com.google.common.truth.Truth.assertThat;

import com.google.idea.blaze.base.lang.buildfile.BuildFileIntegrationTestCase;
import com.google.idea.blaze.base.lang.buildfile.psi.BuildFile;
import com.google.idea.blaze.base.lang.buildfile.psi.FuncallExpression;
import com.google.idea.blaze.base.lang.buildfile.psi.FunctionStatement;
import com.google.idea.blaze.base.lang.buildfile.psi.Parameter;
import com.google.idea.blaze.base.lang.buildfile.psi.StringLiteral;
import com.google.idea.blaze.base.lang.buildfile.psi.TargetExpression;
import com.google.idea.blaze.base.lang.buildfile.psi.util.PsiUtils;
import com.google.idea.blaze.base.lang.buildfile.search.FindUsages;
import com.google.idea.blaze.base.model.primitives.WorkspacePath;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiDirectory;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiManager;
import com.intellij.psi.PsiReference;
import com.intellij.refactoring.move.moveClassesOrPackages.MoveDirectoryWithClassesProcessor;
import com.intellij.refactoring.rename.RenameDialog;
import com.intellij.refactoring.rename.RenamePsiElementProcessor;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

/** Tests that BUILD file references are correctly updated when performing rename refactors. */
@RunWith(JUnit4.class)
public class RenameRefactoringTest extends BuildFileIntegrationTestCase {

  @Test
  public void testRenameJavaClass() {
    PsiFile javaFile =
        workspace.createPsiFile(
            new WorkspacePath("com/google/foo/JavaClass.java"),
            "package com.google.foo;",
            "public class JavaClass {}");

    createBuildFile(
        new WorkspacePath("com/google/foo/BUILD"),
        "java_library(name = \"ref1\", srcs = [\"//com/google/foo:JavaClass.java\"])",
        "java_library(name = \"ref2\", srcs = [\"JavaClass.java\"])",
        "java_library(name = \"ref3\", srcs = [\":JavaClass.java\"])");

    List<StringLiteral> references =
        findAllReferencingElementsOfType(javaFile, StringLiteral.class);

    Set<String> oldStrings =
        references.stream().map(StringLiteral::getStringContents).collect(Collectors.toSet());

    assertThat(references).hasSize(3);

    testFixture.renameElement(javaFile, "NewName.java");

    Set<String> newStrings =
        references.stream().map(StringLiteral::getStringContents).collect(Collectors.toSet());

    Set<String> expectedNewStrings =
        oldStrings
            .stream()
            .map((s) -> s.replaceAll("JavaClass", "NewName"))
            .collect(Collectors.toSet());

    assertThat(expectedNewStrings).containsExactlyElementsIn(newStrings);
  }

  @Test
  public void testRenameRule() {
    BuildFile fooPackage =
        createBuildFile(
            new WorkspacePath("com/google/foo/BUILD"),
            "rule_type(name = \"target\")",
            "java_library(name = \"local_ref\", srcs = [\":target\"])");

    BuildFile barPackage =
        createBuildFile(
            new WorkspacePath("com/google/test/bar/BUILD"),
            "rule_type(name = \"ref\", arg = \"//com/google/foo:target\")",
            "top_level_ref = \"//com/google/foo:target\"");

    FuncallExpression targetRule =
        PsiUtils.findFirstChildOfClassRecursive(fooPackage, FuncallExpression.class);
    testFixture.renameElement(targetRule, "newTargetName");

    assertFileContents(
        fooPackage,
        "rule_type(name = \"newTargetName\")",
        "java_library(name = \"local_ref\", srcs = [\":newTargetName\"])");

    assertFileContents(
        barPackage,
        "rule_type(name = \"ref\", arg = \"//com/google/foo:newTargetName\")",
        "top_level_ref = \"//com/google/foo:newTargetName\"");
  }

  @Test
  public void testRenameSkylarkExtension() {
    BuildFile extFile =
        createBuildFile(
            new WorkspacePath("java/com/google/tools/build_defs.bzl"), "def function(name, deps)");

    BuildFile buildFile =
        createBuildFile(
            new WorkspacePath("java/com/google/BUILD"),
            "load(",
            "\"//java/com/google:tools/build_defs.bzl\",",
            "\"function\"",
            ")",
            "function(name = \"name\", deps = []");

    testFixture.renameElement(extFile, "skylark.bzl");

    assertFileContents(
        buildFile,
        "load(",
        "\"//java/com/google:tools/skylark.bzl\",",
        "\"function\"",
        ")",
        "function(name = \"name\", deps = []");
  }

  @Test
  public void testRenameLoadedFunction() {
    BuildFile extFile =
        createBuildFile(
            new WorkspacePath("java/com/google/tools/build_defs.bzl"), "def function(name, deps)");

    BuildFile buildFile =
        createBuildFile(
            new WorkspacePath("java/com/google/BUILD"),
            "load(",
            "\"//java/com/google/tools:build_defs.bzl\",",
            "\"function\"",
            ")",
            "function(name = \"name\", deps = []");

    FunctionStatement fn = extFile.findChildByClass(FunctionStatement.class);
    testFixture.renameElement(fn, "action");

    assertFileContents(extFile, "def action(name, deps)");

    assertFileContents(
        buildFile,
        "load(",
        "\"//java/com/google/tools:build_defs.bzl\",",
        "\"action\"",
        ")",
        "action(name = \"name\", deps = []");
  }

  @Test
  public void testRenameLocalVariable() {
    BuildFile file = createBuildFile(new WorkspacePath("java/com/google/BUILD"), "a = 1", "c = a");

    TargetExpression target = PsiUtils.findFirstChildOfClassRecursive(file, TargetExpression.class);
    assertThat(target.getText()).isEqualTo("a");

    testFixture.renameElement(target, "b");

    assertFileContents(file, "b = 1", "c = b");
  }

  // all references, including path fragments in labels, should be renamed.
  @Test
  public void testRenameDirectory() {
    createBuildFile(new WorkspacePath("java/com/baz/BUILD"));
    createBuildFile(new WorkspacePath("java/com/google/tools/BUILD"));
    BuildFile buildFile =
        createBuildFile(
            new WorkspacePath("java/com/google/BUILD"),
            "load(",
            "\"//java/com/google/tools:build_defs.bzl\",",
            "\"function\"",
            ")",
            "function(name = \"name\", deps = [\"//java/com/baz:target\"]");

    renameDirectory(new WorkspacePath("java/com"), new WorkspacePath("java/alt"));

    assertFileContents(
        buildFile,
        "load(",
        "\"//java/alt/google/tools:build_defs.bzl\",",
        "\"function\"",
        ")",
        "function(name = \"name\", deps = [\"//java/alt/baz:target\"]");
  }

  @Test
  public void testRenameFunctionParameter() {
    BuildFile extFile =
        createBuildFile(
            new WorkspacePath("java/com/google/tools/build_defs.bzl"), "def function(name, deps)");

    BuildFile buildFile =
        createBuildFile(
            new WorkspacePath("java/com/google/BUILD"),
            "load(",
            "\"//java/com/google/tools:build_defs.bzl\",",
            "\"function\"",
            ")",
            "function(name = \"name\", deps = []");

    FunctionStatement fn = extFile.findChildByClass(FunctionStatement.class);
    Parameter param = fn.getParameterList().findParameterByName("deps");
    testFixture.renameElement(param, "exports");

    assertFileContents(extFile, "def function(name, exports)");

    assertFileContents(
        buildFile,
        "load(",
        "\"//java/com/google/tools:build_defs.bzl\",",
        "\"function\"",
        ")",
        "function(name = \"name\", exports = []");
  }

  @Test
  public void testRenameSuggestionForBuildFile() {
    BuildFile buildFile = createBuildFile(new WorkspacePath("java/com/google/BUILD"));
    RenamePsiElementProcessor processor = RenamePsiElementProcessor.forElement(buildFile);
    RenameDialog dialog = processor.createRenameDialog(getProject(), buildFile, buildFile, null);
    String[] suggestions = dialog.getSuggestedNames();
    assertThat(suggestions[0]).isEqualTo("BUILD");
  }

  @Test
  public void testRenameSuggestionForSkylarkFile() {
    BuildFile buildFile =
        createBuildFile(new WorkspacePath("java/com/google/tools/build_defs.bzl"));
    RenamePsiElementProcessor processor = RenamePsiElementProcessor.forElement(buildFile);
    RenameDialog dialog = processor.createRenameDialog(getProject(), buildFile, buildFile, null);
    String[] suggestions = dialog.getSuggestedNames();
    assertThat(suggestions[0]).isEqualTo("build_defs.bzl");
  }

  private static <T> List<T> findAllReferencingElementsOfType(
      PsiElement target, Class<T> referenceType) {
    return Arrays.stream(FindUsages.findAllReferences(target))
        .map(PsiReference::getElement)
        .filter(referenceType::isInstance)
        .map(e -> (T) e)
        .collect(Collectors.toList());
  }

  private PsiDirectory renameDirectory(WorkspacePath oldPath, WorkspacePath newPath) {
    try {
      VirtualFile original = fileSystem.findFile(workspaceRoot.fileForPath(oldPath).getPath());
      PsiDirectory originalPsi = PsiManager.getInstance(getProject()).findDirectory(original);
      assertThat(originalPsi).isNotNull();

      VirtualFile destination =
          fileSystem.findOrCreateDirectory(workspaceRoot.fileForPath(newPath).getPath());
      PsiDirectory destPsi = PsiManager.getInstance(getProject()).findDirectory(destination);
      assertThat(destPsi).isNotNull();

      new MoveDirectoryWithClassesProcessor(
              getProject(), new PsiDirectory[] {originalPsi}, destPsi, true, true, false, null)
          .run();
      return destPsi;

    } catch (IOException e) {
      throw new RuntimeException(e);
    }
  }
}
