// 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.devtools.build.lib.windows;

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

import com.google.common.base.Function;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Iterables;
import com.google.devtools.build.lib.testutil.TestSpec;
import com.google.devtools.build.lib.util.OS;
import com.google.devtools.build.lib.vfs.DigestHashFunction;
import com.google.devtools.build.lib.vfs.Path;
import com.google.devtools.build.lib.vfs.PathFragment;
import com.google.devtools.build.lib.vfs.Symlinks;
import com.google.devtools.build.lib.windows.jni.WindowsFileOperations;
import com.google.devtools.build.lib.windows.util.WindowsTestUtil;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.file.AccessDeniedException;
import java.nio.file.Files;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

/** Unit tests for {@link WindowsFileSystem}. */
@RunWith(JUnit4.class)
@TestSpec(localOnly = true, supportedOs = OS.WINDOWS)
public class WindowsFileSystemTest {

  private String scratchRoot;
  private WindowsTestUtil testUtil;
  private WindowsFileSystem fs;

  @Before
  public void loadJni() throws Exception {
    scratchRoot = new File(System.getenv("TEST_TMPDIR"), "x").getAbsolutePath();
    testUtil = new WindowsTestUtil(scratchRoot);
    fs = new WindowsFileSystem(DigestHashFunction.DEFAULT_HASH_FOR_TESTS);
    cleanupScratchDir();
  }

  @After
  public void cleanupScratchDir() throws Exception {
    testUtil.deleteAllUnder("");
  }

  @Test
  public void testCanWorkWithJunctionSymlinks() throws Exception {
    testUtil.scratchFile("dir\\hello.txt", "hello");
    testUtil.scratchDir("non_existent");
    testUtil.createJunctions(ImmutableMap.of("junc", "dir", "junc_bad", "non_existent"));

    Path juncPath = testUtil.createVfsPath(fs, "junc");
    Path dirPath = testUtil.createVfsPath(fs, "dir");
    Path juncBadPath = testUtil.createVfsPath(fs, "junc_bad");
    Path nonExistentPath = testUtil.createVfsPath(fs, "non_existent");

    // Test junction creation.
    assertThat(juncPath.exists(Symlinks.NOFOLLOW)).isTrue();
    assertThat(dirPath.exists(Symlinks.NOFOLLOW)).isTrue();
    assertThat(juncBadPath.exists(Symlinks.NOFOLLOW)).isTrue();
    assertThat(nonExistentPath.exists(Symlinks.NOFOLLOW)).isTrue();

    // Test recognizing and dereferencing a directory junction.
    assertThat(juncPath.isSymbolicLink()).isTrue();
    assertThat(juncPath.isDirectory(Symlinks.FOLLOW)).isTrue();
    assertThat(juncPath.isDirectory(Symlinks.NOFOLLOW)).isFalse();
    assertThat(juncPath.getDirectoryEntries())
        .containsExactly(testUtil.createVfsPath(fs, "junc\\hello.txt"));

    // Test deleting a directory junction.
    assertThat(juncPath.delete()).isTrue();
    assertThat(juncPath.exists(Symlinks.NOFOLLOW)).isFalse();

    // Test recognizing a dangling directory junction.
    assertThat(nonExistentPath.delete()).isTrue();
    assertThat(nonExistentPath.exists(Symlinks.NOFOLLOW)).isFalse();
    assertThat(juncBadPath.exists(Symlinks.NOFOLLOW)).isTrue();
    // TODO(bazel-team): fix https://github.com/bazelbuild/bazel/issues/1690 and uncomment the
    // assertion below.
    //assertThat(fs.isSymbolicLink(juncBadPath)).isTrue();
    assertThat(fs.isDirectory(juncBadPath, /* followSymlinks */ true)).isFalse();
    assertThat(fs.isDirectory(juncBadPath, /* followSymlinks */ false)).isFalse();

    // Test deleting a dangling junction.
    assertThat(juncBadPath.delete()).isTrue();
    assertThat(juncBadPath.exists(Symlinks.NOFOLLOW)).isFalse();
  }

  @Test
  public void testMockJunctionCreation() throws Exception {
    String root = testUtil.scratchDir("dir").getParent().toString();
    testUtil.scratchFile("dir/file.txt", "hello");
    testUtil.createJunctions(ImmutableMap.of("junc", "dir"));
    String[] children = new File(root + "/junc").list();
    assertThat(children).isNotNull();
    assertThat(children).hasLength(1);
    assertThat(Arrays.asList(children)).containsExactly("file.txt");
  }

  @Test
  public void testIsJunction() throws Exception {
    final Map<String, String> junctions = new HashMap<>();
    junctions.put("shrtpath/a", "shrttrgt");
    junctions.put("shrtpath/b", "longtargetpath");
    junctions.put("shrtpath/c", "longta~1");
    junctions.put("longlinkpath/a", "shrttrgt");
    junctions.put("longlinkpath/b", "longtargetpath");
    junctions.put("longlinkpath/c", "longta~1");
    junctions.put("abbrev~1/a", "shrttrgt");
    junctions.put("abbrev~1/b", "longtargetpath");
    junctions.put("abbrev~1/c", "longta~1");

    String root = testUtil.scratchDir("shrtpath").getParent().toAbsolutePath().toString();
    testUtil.scratchDir("longlinkpath");
    testUtil.scratchDir("abbreviated");
    testUtil.scratchDir("control/a");
    testUtil.scratchDir("control/b");
    testUtil.scratchDir("control/c");

    testUtil.scratchFile("shrttrgt/file1.txt", "hello");
    testUtil.scratchFile("longtargetpath/file2.txt", "hello");

    testUtil.createJunctions(junctions);

    assertThat(WindowsFileSystem.isJunction(new File(root, "shrtpath/a"))).isTrue();
    assertThat(WindowsFileSystem.isJunction(new File(root, "shrtpath/b"))).isTrue();
    assertThat(WindowsFileSystem.isJunction(new File(root, "shrtpath/c"))).isTrue();
    assertThat(WindowsFileSystem.isJunction(new File(root, "longlinkpath/a"))).isTrue();
    assertThat(WindowsFileSystem.isJunction(new File(root, "longlinkpath/b"))).isTrue();
    assertThat(WindowsFileSystem.isJunction(new File(root, "longlinkpath/c"))).isTrue();
    assertThat(WindowsFileSystem.isJunction(new File(root, "longli~1/a"))).isTrue();
    assertThat(WindowsFileSystem.isJunction(new File(root, "longli~1/b"))).isTrue();
    assertThat(WindowsFileSystem.isJunction(new File(root, "longli~1/c"))).isTrue();
    assertThat(WindowsFileSystem.isJunction(new File(root, "abbreviated/a"))).isTrue();
    assertThat(WindowsFileSystem.isJunction(new File(root, "abbreviated/b"))).isTrue();
    assertThat(WindowsFileSystem.isJunction(new File(root, "abbreviated/c"))).isTrue();
    assertThat(WindowsFileSystem.isJunction(new File(root, "abbrev~1/a"))).isTrue();
    assertThat(WindowsFileSystem.isJunction(new File(root, "abbrev~1/b"))).isTrue();
    assertThat(WindowsFileSystem.isJunction(new File(root, "abbrev~1/c"))).isTrue();
    assertThat(WindowsFileSystem.isJunction(new File(root, "control/a"))).isFalse();
    assertThat(WindowsFileSystem.isJunction(new File(root, "control/b"))).isFalse();
    assertThat(WindowsFileSystem.isJunction(new File(root, "control/c"))).isFalse();
    assertThat(WindowsFileSystem.isJunction(new File(root, "shrttrgt/file1.txt")))
        .isFalse();
    assertThat(WindowsFileSystem.isJunction(new File(root, "longtargetpath/file2.txt")))
        .isFalse();
    assertThat(WindowsFileSystem.isJunction(new File(root, "longta~1/file2.txt")))
        .isFalse();
    try {
      WindowsFileSystem.isJunction(new File(root, "non-existent"));
      fail("expected failure");
    } catch (IOException e) {
      assertThat(e.getMessage()).contains("cannot find");
    }

    assertThat(Arrays.asList(new File(root + "/shrtpath/a").list())).containsExactly("file1.txt");
    assertThat(Arrays.asList(new File(root + "/shrtpath/b").list())).containsExactly("file2.txt");
    assertThat(Arrays.asList(new File(root + "/shrtpath/c").list())).containsExactly("file2.txt");
    assertThat(Arrays.asList(new File(root + "/longlinkpath/a").list()))
        .containsExactly("file1.txt");
    assertThat(Arrays.asList(new File(root + "/longlinkpath/b").list()))
        .containsExactly("file2.txt");
    assertThat(Arrays.asList(new File(root + "/longlinkpath/c").list()))
        .containsExactly("file2.txt");
    assertThat(Arrays.asList(new File(root + "/abbreviated/a").list()))
        .containsExactly("file1.txt");
    assertThat(Arrays.asList(new File(root + "/abbreviated/b").list()))
        .containsExactly("file2.txt");
    assertThat(Arrays.asList(new File(root + "/abbreviated/c").list()))
        .containsExactly("file2.txt");
  }

  @Test
  public void testIsJunctionIsTrueForDanglingJunction() throws Exception {
    java.nio.file.Path helloPath = testUtil.scratchFile("target\\hello.txt", "hello");
    testUtil.createJunctions(ImmutableMap.of("link", "target"));

    File linkPath = new File(helloPath.getParent().getParent().toFile(), "link");
    assertThat(Arrays.asList(linkPath.list())).containsExactly("hello.txt");
    assertThat(WindowsFileSystem.isJunction(linkPath)).isTrue();

    assertThat(helloPath.toFile().delete()).isTrue();
    assertThat(helloPath.getParent().toFile().delete()).isTrue();
    assertThat(helloPath.getParent().toFile().exists()).isFalse();
    assertThat(Arrays.asList(linkPath.getParentFile().list())).containsExactly("link");

    assertThat(WindowsFileSystem.isJunction(linkPath)).isTrue();
    assertThat(
            Files.exists(
                linkPath.toPath(), WindowsFileSystem.symlinkOpts(/* followSymlinks */ false)))
        .isTrue();
    assertThat(
            Files.exists(
                linkPath.toPath(), WindowsFileSystem.symlinkOpts(/* followSymlinks */ true)))
        .isFalse();
  }

  @Test
  public void testIsJunctionHandlesFilesystemChangesCorrectly() throws Exception {
    File longPath =
        testUtil.scratchFile("target\\helloworld.txt", "hello").toAbsolutePath().toFile();
    File shortPath = new File(longPath.getParentFile(), "hellow~1.txt");
    assertThat(WindowsFileSystem.isJunction(longPath)).isFalse();
    assertThat(WindowsFileSystem.isJunction(shortPath)).isFalse();

    assertThat(longPath.delete()).isTrue();
    testUtil.createJunctions(ImmutableMap.of("target\\helloworld.txt", "target"));
    assertThat(WindowsFileSystem.isJunction(longPath)).isTrue();
    assertThat(WindowsFileSystem.isJunction(shortPath)).isTrue();

    assertThat(longPath.delete()).isTrue();
    assertThat(longPath.mkdir()).isTrue();
    assertThat(WindowsFileSystem.isJunction(longPath)).isFalse();
    assertThat(WindowsFileSystem.isJunction(shortPath)).isFalse();
  }

  @Test
  public void testShortPathResolution() throws Exception {
    String shortPath = "shortp~1.res/foo/withsp~1/bar/~witht~1/hello.txt";
    String longPath = "shortpath.resolution/foo/with spaces/bar/~with tilde/hello.txt";
    testUtil.scratchFile(longPath, "hello");
    Path p = fs.getPath(scratchRoot).getRelative(shortPath);
    assertThat(p.getPathString()).endsWith(longPath);
    assertThat(p).isEqualTo(fs.getPath(scratchRoot).getRelative(shortPath));
    assertThat(p).isEqualTo(fs.getPath(scratchRoot).getRelative(longPath));
    assertThat(fs.getPath(scratchRoot).getRelative(shortPath)).isEqualTo(p);
    assertThat(fs.getPath(scratchRoot).getRelative(longPath)).isEqualTo(p);
  }

  @Test
  public void testUnresolvableShortPathWhichIsThenCreated() throws Exception {
    String shortPath = "unreso~1.sho/foo/will~1.exi/bar/hello.txt";
    String longPath = "unresolvable.shortpath/foo/will.exist/bar/hello.txt";
    // Assert that we can create an unresolvable path.
    Path p = fs.getPath(scratchRoot).getRelative(shortPath);
    assertThat(p.getPathString()).endsWith(shortPath);
    // Assert that we can then create the whole path, and can now resolve the short form.
    testUtil.scratchFile(longPath, "hello");
    Path q = fs.getPath(scratchRoot).getRelative(shortPath);
    assertThat(q.getPathString()).endsWith(longPath);
    assertThat(p).isNotEqualTo(q);
  }

  /**
   * Test the scenario when a short path resolves to different long ones over time.
   *
   * <p>This can happen if the user deletes a directory during the bazel server's lifetime, then
   * recreates it with the same name prefix such that the resulting directory's 8dot3 name is the
   * same as the old one's.
   */
  @Test
  public void testShortPathResolvesToDifferentPathsOverTime() throws Exception {
    Path p1 = fs.getPath(scratchRoot).getRelative("longpa~1");
    Path p2 = fs.getPath(scratchRoot).getRelative("longpa~1");
    assertThat(p1.exists()).isFalse();
    assertThat(p1).isEqualTo(p2);

    testUtil.scratchDir("longpathnow");
    Path q1 = fs.getPath(scratchRoot).getRelative("longpa~1");
    assertThat(q1.exists()).isTrue();
    assertThat(q1).isEqualTo(fs.getPath(scratchRoot).getRelative("longpathnow"));

    // Delete the original resolution of "longpa~1" ("longpathnow").
    assertThat(q1.delete()).isTrue();
    assertThat(q1.exists()).isFalse();

    // Create a directory whose 8dot3 name is also "longpa~1" but its long name is different.
    testUtil.scratchDir("longpaththen");
    Path r1 = fs.getPath(scratchRoot).getRelative("longpa~1");
    assertThat(r1.exists()).isTrue();
    assertThat(r1).isEqualTo(fs.getPath(scratchRoot).getRelative("longpaththen"));
  }

  @Test
  public void testCreateSymbolicLink() throws Exception {
    // Create the `scratchRoot` directory.
    assertThat(fs.getPath(scratchRoot).createDirectory()).isTrue();
    // Create symlink with directory target, relative path.
    Path link1 = fs.getPath(scratchRoot).getRelative("link1");
    fs.createSymbolicLink(link1, PathFragment.create(".."));
    // Create symlink with directory target, absolute path.
    Path link2 = fs.getPath(scratchRoot).getRelative("link2");
    fs.createSymbolicLink(link2, fs.getPath(scratchRoot).getRelative("link1").asFragment());
    // Create scratch files that'll be symlink targets.
    testUtil.scratchFile("foo.txt", "hello");
    testUtil.scratchFile("bar.txt", "hello");
    // Create symlink with file target, relative path.
    Path link3 = fs.getPath(scratchRoot).getRelative("link3");
    fs.createSymbolicLink(link3, PathFragment.create("foo.txt"));
    // Create symlink with file target, absolute path.
    Path link4 = fs.getPath(scratchRoot).getRelative("link4");
    fs.createSymbolicLink(link4, fs.getPath(scratchRoot).getRelative("bar.txt").asFragment());
    // Assert that link1 and link2 are true junctions and have the right contents.
    for (Path p : ImmutableList.of(link1, link2)) {
      assertThat(WindowsFileOperations.isJunction(p.getPathString())).isTrue();
      assertThat(p.isSymbolicLink()).isTrue();
      assertThat(
              Iterables.transform(
                  Arrays.asList(new File(p.getPathString()).listFiles()),
                  new Function<File, String>() {
                    @Override
                    public String apply(File input) {
                      return input.getName();
                    }
                  }))
          .containsExactly("x");
    }
    // Assert that link3 and link4 are copies of files.
    for (Path p : ImmutableList.of(link3, link4)) {
      assertThat(WindowsFileOperations.isJunction(p.getPathString())).isFalse();
      assertThat(p.isSymbolicLink()).isFalse();
      assertThat(p.isFile()).isTrue();
    }
  }

  @Test
  public void testDeleteFileOpenForReading() throws Exception {
    testUtil.scratchFile("foo.txt", "foo");
    Path path = testUtil.createVfsPath(fs, "foo.txt");
    // Sanity check: attempt reading from the file.
    try (InputStream is = path.getInputStream()) {
      byte[] contents = new byte[3];
      assertThat(is.read(contents)).isEqualTo(3);
      assertThat(contents).isEqualTo(new byte[] {'f', 'o', 'o'});
    }
    // Actual test: attempt deleting the file while open, then reading from it.
    try (InputStream is = path.getInputStream()) {
      assertThat(path.delete()).isTrue();
      assertThat(path.exists()).isFalse();

      byte[] contents = new byte[3];
      assertThat(is.read(contents)).isEqualTo(3);
      assertThat(contents).isEqualTo(new byte[] {'f', 'o', 'o'});
    }
  }

  @Test
  public void testDeleteFileOpenForWriting() throws Exception {
    testUtil.scratchFile("bar.txt", "bar");
    Path path = testUtil.createVfsPath(fs, "bar.txt");
    // Sanity check: attempt writing to the file.
    try (InputStream is = path.getInputStream()) {
      byte[] contents = new byte[3];
      assertThat(is.read(contents)).isEqualTo(3);
      assertThat(contents).isEqualTo(new byte[] {'b', 'a', 'r'});
    }
    // Actual test: attempt deleting the file while open, then writing to it.
    try (OutputStream os = path.getOutputStream(/* append */ false)) {
      assertThat(path.delete()).isTrue();
      assertThat(path.exists()).isFalse();
      os.write(new byte[] {'b', 'a', 'r'});
    }
  }

  @Test
  public void testCannotOpenDirectoryAsFile() throws Exception {
    testUtil.scratchFile("foo/bar.txt", "bar");
    Path file = testUtil.createVfsPath(fs, "foo/bar.txt");
    Path dir = file.getParentDirectory();
    // Sanity check: we can open the file.
    try (InputStream is = file.getInputStream()) {}
    assertThat(dir.isDirectory()).isTrue();
    try (InputStream is = dir.getInputStream()) {
      fail("Expected failure");
    } catch (IOException e) {
      assertThat(e).isInstanceOf(AccessDeniedException.class);
    }
  }
}
