// Copyright 2014 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.vfs;

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

import com.google.common.collect.Lists;
import com.google.common.testing.EqualsTester;
import com.google.common.testing.GcFinalization;
import com.google.devtools.build.lib.clock.BlazeClock;
import com.google.devtools.build.lib.vfs.inmemoryfs.InMemoryFileSystem;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.ref.WeakReference;
import java.net.URI;
import java.util.Collections;
import java.util.List;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

/**
 * A test for {@link Path}.
 */
@RunWith(JUnit4.class)
public class PathTest {
  private FileSystem filesystem;
  private Path root;

  @Before
  public final void initializeFileSystem() throws Exception  {
    filesystem = new InMemoryFileSystem(BlazeClock.instance());
    root = filesystem.getRootDirectory();
    Path first = root.getChild("first");
    first.createDirectory();
  }

  @Test
  public void testStartsWithWorksForSelf() {
    assertStartsWithReturns(true, "/first/child", "/first/child");
  }

  @Test
  public void testStartsWithWorksForChild() {
    assertStartsWithReturns(true,
        "/first/child", "/first/child/grandchild");
  }

  @Test
  public void testStartsWithWorksForDeepDescendant() {
    assertStartsWithReturns(true,
        "/first/child", "/first/child/grandchild/x/y/z");
  }

  @Test
  public void testStartsWithFailsForParent() {
    assertStartsWithReturns(false, "/first/child", "/first");
  }

  @Test
  public void testStartsWithFailsForSibling() {
    assertStartsWithReturns(false, "/first/child", "/first/child2");
  }

  @Test
  public void testStartsWithFailsForLinkToDescendant()
      throws Exception {
    Path linkTarget = filesystem.getPath("/first/linked_to");
    FileSystemUtils.createEmptyFile(linkTarget);
    Path second = filesystem.getPath("/second/");
    second.createDirectory();
    second.getChild("child_link").createSymbolicLink(linkTarget);
    assertStartsWithReturns(false, "/first", "/second/child_link");
  }

  @Test
  public void testStartsWithFailsForNullPrefix() {
    try {
      filesystem.getPath("/first").startsWith(null);
      fail();
    } catch (Exception e) {
    }
  }

  private void assertStartsWithReturns(boolean expected,
                                       String ancestor,
                                       String descendant) {
    Path parent = filesystem.getPath(ancestor);
    Path child = filesystem.getPath(descendant);
    assertThat(child.startsWith(parent)).isEqualTo(expected);
  }

  @Test
  public void testGetChildWorks() {
    assertGetChildWorks("second");
    assertGetChildWorks("...");
    assertGetChildWorks("....");
  }

  private void assertGetChildWorks(String childName) {
    assertThat(filesystem.getPath("/first").getChild(childName))
        .isEqualTo(filesystem.getPath("/first/" + childName));
  }

  @Test
  public void testGetChildFailsForChildWithSlashes() {
    assertGetChildFails("second/third");
    assertGetChildFails("./third");
    assertGetChildFails("../third");
    assertGetChildFails("second/..");
    assertGetChildFails("second/.");
    assertGetChildFails("/third");
    assertGetChildFails("third/");
  }

  private void assertGetChildFails(String childName) {
    try {
      filesystem.getPath("/first").getChild(childName);
      fail();
    } catch (IllegalArgumentException e) {
      // Expected.
    }
  }

  @Test
  public void testGetChildFailsForDotAndDotDot() {
    assertGetChildFails(".");
    assertGetChildFails("..");
  }

  @Test
  public void testGetChildFailsForEmptyString() {
    assertGetChildFails("");
  }

  @Test
  public void testRelativeToWorks() {
    assertRelativeToWorks("apple", "/fruit/apple", "/fruit");
    assertRelativeToWorks("apple/jonagold", "/fruit/apple/jonagold", "/fruit");
  }

  @Test
  public void testGetRelativeWithStringWorks() {
    assertGetRelativeWorks("/first/x/y", "y");
    assertGetRelativeWorks("/y", "/y");
    assertGetRelativeWorks("/first/x/x", "./x");
    assertGetRelativeWorks("/first/y", "../y");
    assertGetRelativeWorks("/", "../../../../..");
  }

  @Test
  public void testAsFragmentWorks() {
    assertAsFragmentWorks("/");
    assertAsFragmentWorks("//");
    assertAsFragmentWorks("/first");
    assertAsFragmentWorks("/first/x/y");
    assertAsFragmentWorks("/first/x/y.foo");
  }

  @Test
  public void testGetRelativeWithFragmentWorks() {
    Path dir = filesystem.getPath("/first/x");
    assertThat(dir.getRelative(PathFragment.create("y")).toString()).isEqualTo("/first/x/y");
    assertThat(dir.getRelative(PathFragment.create("./x")).toString()).isEqualTo("/first/x/x");
    assertThat(dir.getRelative(PathFragment.create("../y")).toString()).isEqualTo("/first/y");
  }

  @Test
  public void testGetRelativeWithAbsoluteFragmentWorks() {
    Path root = filesystem.getPath("/first/x");
    assertThat(root.getRelative(PathFragment.create("/x/y")).toString()).isEqualTo("/x/y");
  }

  @Test
  public void testGetRelativeWithAbsoluteStringWorks() {
    Path root = filesystem.getPath("/first/x");
    assertThat(root.getRelative("/x/y").toString()).isEqualTo("/x/y");
  }

  @Test
  public void testComparableSortOrder() {
    Path zzz = filesystem.getPath("/zzz");
    Path ZZZ = filesystem.getPath("/ZZZ");
    Path abc = filesystem.getPath("/abc");
    Path aBc = filesystem.getPath("/aBc");
    Path AbC = filesystem.getPath("/AbC");
    Path ABC = filesystem.getPath("/ABC");
    List<Path> list = Lists.newArrayList(zzz, ZZZ, ABC, aBc, AbC, abc);
    Collections.sort(list);
    assertThat(list).containsExactly(ABC, AbC, ZZZ, aBc, abc, zzz).inOrder();
  }

  @Test
  public void testParentOfRootIsRoot() {
    assertThat(root.getRelative("..")).isSameAs(root);

    assertThat(root.getRelative("broken/../../dots")).isSameAs(root.getRelative("dots"));
  }

  @Test
  public void testSingleSegmentEquivalence() {
    assertThat(root.getRelative("aSingleSegment")).isSameAs(root.getRelative("aSingleSegment"));
  }

  @Test
  public void testSiblingNonEquivalenceString() {
    assertThat(root.getRelative("aDifferentSegment"))
        .isNotSameAs(root.getRelative("aSingleSegment"));
  }

  @Test
  public void testSiblingNonEquivalenceFragment() {
    assertThat(root.getRelative(PathFragment.create("aDifferentSegment")))
        .isNotSameAs(root.getRelative(PathFragment.create("aSingleSegment")));
  }

  @Test
  public void testHashCodeStableAcrossGarbageCollections() {
    Path parent = filesystem.getPath("/a");
    PathFragment childFragment = PathFragment.create("b");
    Path child = parent.getRelative(childFragment);
    WeakReference<Path> childRef = new WeakReference<>(child);
    int childHashCode1 = childRef.get().hashCode();
    assertThat(parent.getRelative(childFragment).hashCode()).isEqualTo(childHashCode1);
    child = null;
    GcFinalization.awaitClear(childRef);
    int childHashCode2 = parent.getRelative(childFragment).hashCode();
    assertThat(childHashCode2).isEqualTo(childHashCode1);
  }

  @Test
  public void testSerialization() throws Exception {
    FileSystem oldFileSystem = Path.getFileSystemForSerialization();
    try {
      Path.setFileSystemForSerialization(filesystem);
      Path root = filesystem.getPath("/");
      Path p1 = filesystem.getPath("/foo");
      Path p2 = filesystem.getPath("/foo/bar");

      ByteArrayOutputStream bos = new ByteArrayOutputStream();
      ObjectOutputStream oos = new ObjectOutputStream(bos);

      oos.writeObject(root);
      oos.writeObject(p1);
      oos.writeObject(p2);

      ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
      ObjectInputStream ois = new ObjectInputStream(bis);

      Path dsRoot = (Path) ois.readObject();
      Path dsP1 = (Path) ois.readObject();
      Path dsP2 = (Path) ois.readObject();

      new EqualsTester()
          .addEqualityGroup(root, dsRoot)
          .addEqualityGroup(p1, dsP1)
          .addEqualityGroup(p2, dsP2)
          .testEquals();

      assertThat(p2.startsWith(p1)).isTrue();
      assertThat(p2.startsWith(dsP1)).isTrue();
      assertThat(dsP2.startsWith(p1)).isTrue();
      assertThat(dsP2.startsWith(dsP1)).isTrue();

      // Regression test for a very specific bug in compareTo involving our incorrect usage of
      // reference equality rather than logical equality.
      String relativePathStringA = "child/grandchildA";
      String relativePathStringB = "child/grandchildB";
      assertThat(
              p1.getRelative(relativePathStringA).compareTo(dsP1.getRelative(relativePathStringB)))
          .isEqualTo(
              p1.getRelative(relativePathStringA).compareTo(p1.getRelative(relativePathStringB)));
    } finally {
      Path.setFileSystemForSerialization(oldFileSystem);
    }
  }

  @Test
  public void testAbsolutePathRoot() {
    assertThat(new Path(null).toString()).isEqualTo("/");
  }

  @Test
  public void testAbsolutePath() {
    Path segment = new Path(null, "bar.txt",
      new Path(null, "foo", new Path(null)));
    assertThat(segment.toString()).isEqualTo("/foo/bar.txt");
  }

  @Test
  public void testToURI() throws Exception {
    Path p = root.getRelative("/tmp/foo bar.txt");
    URI uri = p.toURI();
    assertThat(uri.toString()).isEqualTo("file:///tmp/foo%20bar.txt");
  }

  private void assertAsFragmentWorks(String expected) {
    assertThat(filesystem.getPath(expected).asFragment()).isEqualTo(PathFragment.create(expected));
  }

  private void assertGetRelativeWorks(String expected, String relative) {
    assertThat(filesystem.getPath("/first/x").getRelative(relative))
        .isEqualTo(filesystem.getPath(expected));
  }

  private void assertRelativeToWorks(String expected, String relative, String original) {
    assertThat(filesystem.getPath(relative).relativeTo(filesystem.getPath(original)))
        .isEqualTo(PathFragment.create(expected));
  }
}
