// Copyright 2015 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.devtools.build.lib.cmdline;

import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.fail;

import com.google.common.collect.ImmutableMap;
import com.google.common.testing.EqualsTester;
import com.google.devtools.build.lib.testutil.TestUtils;
import com.google.devtools.build.lib.vfs.PathFragment;
import java.util.regex.Pattern;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

/**
 * Tests for {@link Label}.
 */
@RunWith(JUnit4.class)
public class LabelTest {

  private static final String INVALID_TARGET_NAME = "invalid target name";
  private static final String INVALID_PACKAGE_NAME = "invalid package name";

  @Test
  public void testAbsolute() throws Exception {
    {
      Label l = Label.parseAbsolute("//foo/bar:baz", ImmutableMap.of());
      assertThat(l.getPackageName()).isEqualTo("foo/bar");
      assertThat(l.getName()).isEqualTo("baz");
    }
    {
      Label l = Label.parseAbsolute("//foo/bar", ImmutableMap.of());
      assertThat(l.getPackageName()).isEqualTo("foo/bar");
      assertThat(l.getName()).isEqualTo("bar");
    }
    {
      Label l = Label.parseAbsolute("//:bar", ImmutableMap.of());
      assertThat(l.getPackageName()).isEmpty();
      assertThat(l.getName()).isEqualTo("bar");
    }
    {
      Label l = Label.parseAbsolute("@foo", ImmutableMap.of());
      assertThat(l.getPackageIdentifier().getRepository().getName()).isEqualTo("@foo");
      assertThat(l.getPackageName()).isEmpty();
      assertThat(l.getName()).isEqualTo("foo");
    }
    {
      Label l = Label.parseAbsolute("//@foo", ImmutableMap.of());
      assertThat(l.getPackageIdentifier().getRepository().getName()).isEqualTo("@");
      assertThat(l.getPackageName()).isEqualTo("@foo");
      assertThat(l.getName()).isEqualTo("@foo");
    }
    {
      Label l = Label.parseAbsolute("//xyz/@foo:abc", ImmutableMap.of());
      assertThat(l.getPackageIdentifier().getRepository().getName()).isEqualTo("@");
      assertThat(l.getPackageName()).isEqualTo("xyz/@foo");
      assertThat(l.getName()).isEqualTo("abc");
    }
  }

  private static String parseCommandLine(String label, String prefix) throws LabelSyntaxException {
    return Label.parseCommandLineLabel(label, PathFragment.create(prefix)).toString();
  }

  @Test
  public void testLabelResolution() throws Exception {
    assertThat(parseCommandLine("//absolute:label", "")).isEqualTo("//absolute:label");
    assertThat(parseCommandLine("//absolute:label", "absolute")).isEqualTo("//absolute:label");
    assertThat(parseCommandLine(":label", "absolute")).isEqualTo("//absolute:label");
    assertThat(parseCommandLine("label", "absolute")).isEqualTo("//absolute:label");
    assertThat(parseCommandLine("absolute:label", "")).isEqualTo("//absolute:label");
    assertThat(parseCommandLine("path:label", "absolute")).isEqualTo("//absolute/path:label");
    assertThat(parseCommandLine("path:label/path", "absolute"))
        .isEqualTo("//absolute/path:label/path");
    assertThat(parseCommandLine("label/path", "absolute")).isEqualTo("//absolute:label/path");
  }

  @Test
  public void testLabelResolutionAbsolutePath() throws Exception {
    try {
      parseCommandLine("//absolute:label", "/absolute");
      fail();
    } catch (IllegalArgumentException e) {
      // Expected exception
    }
  }

  @Test
  public void testLabelResolutionBadSyntax() throws Exception {
    try {
      parseCommandLine("//absolute:A+bad:syntax", "");
      fail();
    } catch (LabelSyntaxException e) {
      // Expected exception
    }
  }

  @Test
  public void testGetRelativeWithAbsoluteLabel() throws Exception {
    Label base = Label.parseAbsolute("//foo/bar:baz", ImmutableMap.of());
    Label l = base.getRelativeWithRemapping("//p1/p2:target", ImmutableMap.of());
    assertThat(l.getPackageName()).isEqualTo("p1/p2");
    assertThat(l.getName()).isEqualTo("target");
  }

  @Test
  public void testGetRelativeWithRelativeLabel() throws Exception {
    Label base = Label.parseAbsolute("//foo/bar:baz", ImmutableMap.of());
    Label l = base.getRelativeWithRemapping(":quux", ImmutableMap.of());
    assertThat(l.getPackageName()).isEqualTo("foo/bar");
    assertThat(l.getName()).isEqualTo("quux");
  }

  @Test
  public void testGetRelativeWithIllegalLabel() throws Exception {
    Label base = Label.parseAbsolute("//foo/bar:baz", ImmutableMap.of());
    try {
      base.getRelativeWithRemapping("/p1/p2:target", ImmutableMap.of());
      fail();
    } catch (LabelSyntaxException e) {
      /* ok */
    }
    try {
      base.getRelativeWithRemapping("quux:", ImmutableMap.of());
      fail();
    } catch (LabelSyntaxException e) {
      /* ok */
    }
    try {
      base.getRelativeWithRemapping(":", ImmutableMap.of());
      fail();
    } catch (LabelSyntaxException e) {
      /* ok */
    }
    try {
      base.getRelativeWithRemapping("::", ImmutableMap.of());
      fail();
    } catch (LabelSyntaxException e) {
      /* ok */
    }
  }

  @Test
  public void testGetRelativeWithDifferentRepo() throws Exception {
    PackageIdentifier packageId = PackageIdentifier.create("@repo", PathFragment.create("foo"));
    Label base = Label.create(packageId, "bar");

    Label relative = base.getRelativeWithRemapping("@remote//x:y", ImmutableMap.of());

    assertThat(relative.getPackageIdentifier().getRepository())
        .isEqualTo(RepositoryName.create("@remote"));
    assertThat(relative.getPackageFragment()).isEqualTo(PathFragment.create("x"));
    assertThat(relative.getName()).isEqualTo("y");
  }

  @Test
  public void testGetRelativeWithoutRemappingBaseLabel() throws Exception {
    PackageIdentifier packageId = PackageIdentifier.create("@a", PathFragment.create("foo"));
    Label base = Label.create(packageId, "bar");
    ImmutableMap<RepositoryName, RepositoryName> repoMapping =
        ImmutableMap.of(RepositoryName.create("@a"), RepositoryName.create("@b"));
    Label relative = base.getRelativeWithRemapping(":y", repoMapping);

    // getRelative should only remap repositories passed in the string arg and not
    // make changes to existing Labels
    Label actual = Label.parseAbsoluteUnchecked("@a//foo:y");
    assertThat(relative).isEqualTo(actual);
  }

  @Test
  public void testGetRelativeWithDifferentRepoAndRemapping() throws Exception {
    PackageIdentifier packageId = PackageIdentifier.create("@repo", PathFragment.create("foo"));
    Label base = Label.create(packageId, "bar");
    ImmutableMap<RepositoryName, RepositoryName> repoMapping =
        ImmutableMap.of(RepositoryName.create("@a"), RepositoryName.create("@b"));
    Label relative = base.getRelativeWithRemapping("@a//x:y", repoMapping);

    Label actual = Label.parseAbsoluteUnchecked("@b//x:y");
    assertThat(relative).isEqualTo(actual);
  }

  @Test
  public void testGetRelativeWithRepoLocalAbsoluteLabel() throws Exception {
    PackageIdentifier packageId = PackageIdentifier.create("@repo", PathFragment.create("foo"));
    Label base = Label.create(packageId, "bar");

    Label relative = base.getRelativeWithRemapping("//x:y", ImmutableMap.of());

    assertThat(relative.getPackageIdentifier().getRepository())
        .isEqualTo(packageId.getRepository());
    assertThat(relative.getPackageFragment()).isEqualTo(PathFragment.create("x"));
    assertThat(relative.getName()).isEqualTo("y");
  }

  @Test
  public void testGetRelativeWithLocalRepoRelativeLabel() throws Exception {
    PackageIdentifier packageId = PackageIdentifier.create("@repo", PathFragment.create("foo"));
    Label base = Label.create(packageId, "bar");

    Label relative = base.getRelativeWithRemapping(":y", ImmutableMap.of());

    assertThat(relative.getPackageIdentifier().getRepository())
        .isEqualTo(packageId.getRepository());
    assertThat(relative.getPackageFragment()).isEqualTo(PathFragment.create("foo"));
    assertThat(relative.getName()).isEqualTo("y");
  }

  @Test
  public void testGetRelativeWithRepoAndReservedPackage() throws Exception {
    PackageIdentifier packageId = PackageIdentifier.create("@repo", PathFragment.create("foo"));
    Label base = Label.create(packageId, "bar");

    Label relative = base.getRelativeWithRemapping("//conditions:default", ImmutableMap.of());

    PackageIdentifier expected = PackageIdentifier.createInMainRepo("conditions");
    assertThat(relative.getPackageIdentifier().getRepository()).isEqualTo(expected.getRepository());
    assertThat(relative.getPackageFragment()).isEqualTo(expected.getPackageFragment());
    assertThat(relative.getName()).isEqualTo("default");
  }

  @Test
  public void testGetRelativeWithRemoteRepoToDefaultRepo() throws Exception {
    PackageIdentifier packageId = PackageIdentifier.create("@repo", PathFragment.create("foo"));
    Label base = Label.create(packageId, "bar");

    Label relative = base.getRelativeWithRemapping("@//x:y", ImmutableMap.of());

    assertThat(relative.getPackageIdentifier().getRepository())
        .isEqualTo(RepositoryName.create("@"));
    assertThat(relative.getPackageFragment()).isEqualTo(PathFragment.create("x"));
    assertThat(relative.getName()).isEqualTo("y");
  }

  @Test
  public void testGetRepositoryRelative() throws Exception {
    Label defaultBase = Label.parseAbsolute("//foo/bar:baz", ImmutableMap.of());
    Label repoBase = Label.parseAbsolute("@repo//foo/bar:baz", ImmutableMap.of());
    Label mainBase = Label.parseAbsolute("@//foo/bar:baz", ImmutableMap.of());
    Label externalTarget = Label.parseAbsolute("//external:target", ImmutableMap.of());
    Label l = defaultBase.resolveRepositoryRelative(externalTarget);
    assertThat(l.getPackageIdentifier().getRepository().isMain()).isTrue();
    assertThat(l.getPackageName()).isEqualTo("external");
    assertThat(l.getName()).isEqualTo("target");
    assertThat(repoBase.resolveRepositoryRelative(externalTarget)).isEqualTo(l);
    assertThat(mainBase.resolveRepositoryRelative(externalTarget)).isEqualTo(l);
  }

  @Test
  public void testFactory() throws Exception {
    Label l = Label.create("foo/bar", "quux");
    assertThat(l.getPackageName()).isEqualTo("foo/bar");
    assertThat(l.getName()).isEqualTo("quux");
  }

  @Test
  public void testIdentities() throws Exception {

    Label l1 = Label.parseAbsolute("//foo/bar:baz", ImmutableMap.of());
    Label l2 = Label.parseAbsolute("//foo/bar:baz", ImmutableMap.of());
    Label l3 = Label.parseAbsolute("//foo/bar:quux", ImmutableMap.of());

    new EqualsTester()
        .addEqualityGroup(l1, l2)
        .addEqualityGroup(l3)
        .testEquals();
  }

  @Test
  public void testToString() throws Exception {
    {
      String s = "@//foo/bar:baz";
      Label l = Label.parseAbsolute(s, ImmutableMap.of());
      assertThat(l.toString()).isEqualTo("//foo/bar:baz");
    }
    {
      Label l = Label.parseAbsolute("//foo/bar", ImmutableMap.of());
      assertThat(l.toString()).isEqualTo("//foo/bar:bar");
    }
    {
      Label l = Label.parseAbsolute("@foo", ImmutableMap.of());
      assertThat(l.toString()).isEqualTo("@foo//:foo");
    }
  }

  @Test
  public void testToShorthandString() throws Exception {
    {
      Label l = Label.parseAbsolute("//bar/baz:baz", ImmutableMap.of());
      assertThat(l.toShorthandString()).isEqualTo("//bar/baz");
    }
    {
      Label l = Label.parseAbsolute("//bar/baz:bat", ImmutableMap.of());
      assertThat(l.toShorthandString()).isEqualTo("//bar/baz:bat");
    }
    {
      Label l = Label.parseAbsolute("@foo//bar/baz:baz", ImmutableMap.of());
      assertThat(l.toShorthandString()).isEqualTo("@foo//bar/baz");
    }
    {
      Label l = Label.parseAbsolute("@foo//bar/baz:bat", ImmutableMap.of());
      assertThat(l.toShorthandString()).isEqualTo("@foo//bar/baz:bat");
    }
  }

  @Test
  public void testDotDot() throws Exception {
    Label.parseAbsolute("//foo/bar:baz..gif", ImmutableMap.of());
  }

  /**
   * Asserts that creating a label throws a SyntaxException.
   * @param label the label to create.
   */
  private static void assertSyntaxError(String expectedError, String label) {
    try {
      Label.parseAbsolute(label, ImmutableMap.of());
      fail("Label '" + label + "' did not contain a syntax error");
    } catch (LabelSyntaxException e) {
      assertThat(e).hasMessageThat().containsMatch(Pattern.quote(expectedError));
    }
  }

  @Test
  public void testBadCharacters() throws Exception {
    assertSyntaxError("target names may not contain ':'",
                      "//foo:bar:baz");
    assertSyntaxError("target names may not contain ':'",
                      "//foo:bar:");
    assertSyntaxError("target names may not contain ':'",
                      "//foo/bar::");
  }

  @Test
  public void testUplevelReferences() throws Exception {
    assertSyntaxError(INVALID_PACKAGE_NAME, "//foo/bar/..:baz");
    assertSyntaxError(INVALID_PACKAGE_NAME, "//foo/../baz:baz");
    assertSyntaxError(INVALID_PACKAGE_NAME, "//../bar/baz:baz");
    assertSyntaxError(INVALID_PACKAGE_NAME, "//..:foo");
    assertSyntaxError(INVALID_TARGET_NAME, "//foo:bar/../baz");
    assertSyntaxError(INVALID_TARGET_NAME, "//foo:../bar/baz");
    assertSyntaxError(INVALID_TARGET_NAME, "//foo:bar/baz/..");
    assertSyntaxError(INVALID_TARGET_NAME, "//foo:..");
  }

  @Test
  public void testDotAsAPathSegment() throws Exception {
    assertSyntaxError(INVALID_PACKAGE_NAME, "//foo/bar/.:baz");
    assertSyntaxError(INVALID_PACKAGE_NAME, "//foo/./baz:baz");
    assertSyntaxError(INVALID_PACKAGE_NAME, "//./bar/baz:baz");
    assertSyntaxError(INVALID_TARGET_NAME, "//foo:bar/./baz");
    assertSyntaxError(INVALID_TARGET_NAME, "//foo:./bar/baz");
    // TODO(bazel-team): enable when we have removed the "Workaround" in Label
    // that rewrites broken Labels by removing the trailing '.'
    //assertSyntaxError(INVALID_PACKAGE_NAME,
    //                  "//foo:bar/baz/.");
    //assertSyntaxError(INVALID_PACKAGE_NAME,
    //                  "//foo:.");
  }

  @Test
  public void testTrailingDotSegment() throws Exception {
    assertThat(Label.parseAbsolute("//foo:dir", ImmutableMap.of()))
        .isEqualTo(Label.parseAbsolute("//foo:dir/.", ImmutableMap.of()));
  }

  @Test
  public void testSomeOtherBadLabels() throws Exception {
    assertSyntaxError("package names may not end with '/'",
                      "//foo/:bar");
    assertSyntaxError("package names may not start with '/'", "///p:foo");
    assertSyntaxError("package names may not contain '//' path separators",
                      "//a//b:foo");
  }

  @Test
  public void testSomeGoodLabels() throws Exception {
    Label.parseAbsolute("//foo:..bar", ImmutableMap.of());
    Label.parseAbsolute("//Foo:..bar", ImmutableMap.of());
    Label.parseAbsolute("//-Foo:..bar", ImmutableMap.of());
    Label.parseAbsolute("//00:..bar", ImmutableMap.of());
    Label.parseAbsolute("//package:foo+bar", ImmutableMap.of());
    Label.parseAbsolute("//package:foo_bar", ImmutableMap.of());
    Label.parseAbsolute("//package:foo=bar", ImmutableMap.of());
    Label.parseAbsolute("//package:foo-bar", ImmutableMap.of());
    Label.parseAbsolute("//package:foo.bar", ImmutableMap.of());
    Label.parseAbsolute("//package:foo@bar", ImmutableMap.of());
    Label.parseAbsolute("//package:foo~bar", ImmutableMap.of());
    Label.parseAbsolute("//$( ):$( )", ImmutableMap.of());
  }

  @Test
  public void testDoubleSlashPathSeparator() throws Exception {
    assertSyntaxError("package names may not contain '//' path separators",
                      "//foo//bar:baz");
    assertSyntaxError("target names may not contain '//' path separator",
                      "//foo:bar//baz");
  }

  @Test
  public void testNonPrintableCharacters() throws Exception {
    assertSyntaxError(
      "target names may not contain non-printable characters: '\\x02'",
      "//foo:..\002bar");
  }

  /** Make sure that control characters - such as CR - are escaped on output. */
  @Test
  public void testInvalidLineEndings() throws Exception {
    assertSyntaxError("invalid target name '..bar\\r': "
        + "target names may not end with carriage returns", "//foo:..bar\r");
  }

  @Test
  public void testEmptyName() throws Exception {
    assertSyntaxError("invalid target name '': empty target name", "//foo/bar:");
  }

  @Test
  public void testSerializationSimple() throws Exception {
    checkSerialization("//a", 93);
  }

  @Test
  public void testSerializationNested() throws Exception {
    checkSerialization("//foo/bar:baz", 101);
  }

  @Test
  public void testSerializationWithoutTargetName() throws Exception {
    checkSerialization("//foo/bar", 101);
  }

  private void checkSerialization(String labelString, int expectedSize) throws Exception {
    Label a = Label.parseAbsolute(labelString, ImmutableMap.of());
    byte[] sa = TestUtils.serializeObject(a);
    assertThat(sa).hasLength(expectedSize);

    Label a2 = (Label) TestUtils.deserializeObject(sa);
    assertThat(a2).isEqualTo(a);
  }

  @Test
  public void testRepoLabel() throws Exception {
    Label label = Label.parseAbsolute("@foo//bar/baz:bat/boo", ImmutableMap.of());
    assertThat(label.toString()).isEqualTo("@foo//bar/baz:bat/boo");
  }

  @Test
  public void testNoRepo() throws Exception {
    Label label = Label.parseAbsolute("//bar/baz:bat/boo", ImmutableMap.of());
    assertThat(label.toString()).isEqualTo("//bar/baz:bat/boo");
  }

  @Test
  public void testInvalidRepo() throws Exception {
    try {
      Label.parseAbsolute("foo//bar/baz:bat/boo", ImmutableMap.of());
      fail();
    } catch (LabelSyntaxException e) {
      assertThat(e)
          .hasMessageThat()
          .isEqualTo("invalid repository name 'foo': workspace names must start with '@'");
    }
  }

  @Test
  public void testInvalidRepoWithColon() throws Exception {
    try {
      Label.parseAbsolute("@foo:xyz", ImmutableMap.of());
      fail();
    } catch (LabelSyntaxException e) {
      assertThat(e)
          .hasMessageThat()
          .containsMatch("invalid repository name '@foo:xyz': workspace names may contain only");
    }
  }

  @Test
  public void testGetWorkspaceRoot() throws Exception {
    Label label = Label.parseAbsolute("//bar/baz", ImmutableMap.of());
    assertThat(label.getWorkspaceRoot()).isEmpty();
    label = Label.parseAbsolute("@repo//bar/baz", ImmutableMap.of());
    assertThat(label.getWorkspaceRoot()).isEqualTo("external/repo");
  }

  @Test
  public void testGetContainingDirectory() {
    assertThat(Label.getContainingDirectory(Label.parseAbsoluteUnchecked("//a:b")))
        .isEqualTo(PathFragment.create("a"));
    assertThat(Label.getContainingDirectory(Label.parseAbsoluteUnchecked("//a/b:c")))
        .isEqualTo(PathFragment.create("a/b"));
    assertThat(Label.getContainingDirectory(Label.parseAbsoluteUnchecked("//a:b/c")))
        .isEqualTo(PathFragment.create("a/b"));
    assertThat(Label.getContainingDirectory(Label.parseAbsoluteUnchecked("//a/b/c")))
        .isEqualTo(PathFragment.create("a/b/c"));
  }

  @Test
  public void testWorkspaceName() throws Exception {
    assertThat(Label.parseAbsolute("@foo//bar:baz", ImmutableMap.of()).getWorkspaceName())
        .isEqualTo("foo");
    assertThat(Label.parseAbsolute("//bar:baz", ImmutableMap.of()).getWorkspaceName()).isEmpty();
    assertThat(Label.parseAbsolute("@//bar:baz", ImmutableMap.of()).getWorkspaceName()).isEmpty();
  }
}
