// 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.util;

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

import com.google.common.collect.Sets;
import com.google.devtools.build.lib.testutil.Scratch;
import com.google.devtools.build.lib.vfs.DigestHashFunction;
import com.google.devtools.build.lib.vfs.FileSystem;
import com.google.devtools.build.lib.vfs.Path;
import com.google.devtools.build.lib.windows.WindowsFileSystem;
import java.util.Set;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

@RunWith(JUnit4.class)
public class DependencySetWindowsTest {

  private Scratch scratch = new Scratch();
  private final FileSystem fileSystem =
      new WindowsFileSystem(DigestHashFunction.SHA256, /*createSymbolicLinks=*/ false);
  private final Path root = fileSystem.getPath("C:/");

  private DependencySet newDependencySet() {
    return new DependencySet(root);
  }

  @Test
  public void dotDParser_windowsPaths() throws Exception {
    Path dotd =
        scratch.file(
            "/tmp/foo.d",
            "bazel-out/hello-lib/cpp/hello-lib.o: \\",
            " cpp/hello-lib.cc cpp/hello-lib.h c:\\mingw\\include\\stdio.h \\",
            " c:\\mingw\\include\\_mingw.h \\",
            " c:\\mingw\\lib\\gcc\\mingw32\\4.8.1\\include\\stdarg.h");

    Set<Path> expected =
        Sets.newHashSet(
            root.getRelative("cpp/hello-lib.cc"),
            root.getRelative("cpp/hello-lib.h"),
            fileSystem.getPath("C:/mingw/include/stdio.h"),
            fileSystem.getPath("C:/mingw/include/_mingw.h"),
            fileSystem.getPath("C:/mingw/lib/gcc/mingw32/4.8.1/include/stdarg.h"));

    assertThat(newDependencySet().read(dotd).getDependencies()).containsExactlyElementsIn(expected);
  }

  @Test
  public void dotDParser_windowsPathsWithSpaces() throws Exception {
    Path dotd =
        scratch.file(
            "/tmp/foo.d",
            "bazel-out/hello-lib/cpp/hello-lib.o: \\",
            "C:\\Program\\ Files\\ (x86)\\LLVM\\stddef.h");
    assertThat(newDependencySet().read(dotd).getDependencies())
        .containsExactlyElementsIn(
            Sets.newHashSet(fileSystem.getPath("C:/Program Files (x86)/LLVM/stddef.h")));
  }

  @Test
  public void dotDParser_mixedWindowsPaths() throws Exception {
    // This is (slightly simplified) actual output from clang. Yes, clang will happily mix
    // forward slashes and backslashes in a single path, not to mention using backslashes as
    // separators next to backslashes as escape characters.
    Path dotd =
        scratch.file(
            "/tmp/foo.d",
            "bazel-out/hello-lib/cpp/hello-lib.o: \\",
            "cpp/hello-lib.cc cpp/hello-lib.h /mingw/include\\stdio.h \\",
            "/mingw/include\\_mingw.h \\",
            "C:\\Program\\ Files\\ (x86)\\LLVM\\bin\\..\\lib\\clang\\3.5.0\\include\\stddef.h \\",
            "C:\\Program\\ Files\\ (x86)\\LLVM\\bin\\..\\lib\\clang\\3.5.0\\include\\stdarg.h");

    Set<Path> expected =
        Sets.newHashSet(
            root.getRelative("cpp/hello-lib.cc"),
            root.getRelative("cpp/hello-lib.h"),
            fileSystem.getPath("C:/fake/msys/mingw/include/stdio.h"),
            fileSystem.getPath("C:/fake/msys/mingw/include/_mingw.h"),
            fileSystem.getPath("C:/Program Files (x86)/LLVM/lib/clang/3.5.0/include/stddef.h"),
            fileSystem.getPath("C:/Program Files (x86)/LLVM/lib/clang/3.5.0/include/stdarg.h"));

    assertThat(newDependencySet().read(dotd).getDependencies()).containsExactlyElementsIn(expected);
  }

  @Test
  public void dotDParser_caseInsensitive() throws Exception {
    Path file1 = fileSystem.getPath("C:/blah/blah/genhello/hello.cc");
    Path file2 = fileSystem.getPath("C:/blah/blah/genhello/hello.h");
    Path file2DiffCase = fileSystem.getPath("C:/Blah/blah/Genhello/hello.h");
    String filename = "hello.o";
    Path dotd =
        scratch.file("/tmp/foo.d", filename + ": \\", " " + file1 + " \\", " " + file2 + " ");
    assertThat(newDependencySet().read(dotd).getDependencies())
        .containsExactly(file1, file2DiffCase);
  }
}
