// 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 static org.junit.Assert.assertThrows;
import static org.junit.Assert.fail;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.Sets;
import com.google.devtools.build.lib.testutil.Scratch;
import com.google.devtools.build.lib.vfs.FileSystem;
import com.google.devtools.build.lib.vfs.FileSystemUtils;
import com.google.devtools.build.lib.vfs.Path;
import java.io.IOException;
import java.nio.charset.Charset;
import java.util.Collection;
import java.util.Set;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

@RunWith(JUnit4.class)
public class DependencySetTest {

  private Scratch scratch = new Scratch();
  private FileSystem fileSystem = scratch.getFileSystem();
  private Path root = scratch.resolve("/");

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

  @Test
  public void dotDParser_simple() throws Exception {
    Path file1 = fileSystem.getPath("/usr/local/blah/blah/genhello/hello.cc");
    Path file2 = fileSystem.getPath("/usr/local/blah/blah/genhello/hello.h");
    String filename = "hello.o";
    Path dotd = scratch.file("/tmp/foo.d",
        filename + ": \\",
        " " + file1 + " \\",
        " " + file2 + " ");
    DependencySet depset = newDependencySet().read(dotd);
    assertThat(depset.getDependencies()).containsExactlyElementsIn(Sets.newHashSet(file1, file2));
    assertThat(filename).isEqualTo(depset.getOutputFileName());
  }

  @Test
  public void dotDParser_simple_crlf() throws Exception {
    Path file1 = fileSystem.getPath("/usr/local/blah/blah/genhello/hello.cc");
    Path file2 = fileSystem.getPath("/usr/local/blah/blah/genhello/hello.h");
    String filename = "hello.o";
    Path dotd = scratch.file("/tmp/foo.d",
        filename + ": \\\r",
        " " + file1 + " \\\r",
        " " + file2 + " ");
    DependencySet depset = newDependencySet().read(dotd);
    assertThat(depset.getDependencies()).containsExactlyElementsIn(Sets.newHashSet(file1, file2));
    assertThat(filename).isEqualTo(depset.getOutputFileName());
  }

  @Test
  public void dotDParser_simple_cr() throws Exception {
    Path file1 = fileSystem.getPath("/usr/local/blah/blah/genhello/hello.cc");
    Path file2 = fileSystem.getPath("/usr/local/blah/blah/genhello/hello.h");
    String filename = "hello.o";
    Path dotd =
        scratch.file("/tmp/foo.d", filename + ": \\\r " + file1 + " \\\r " + file2 + " ");
    DependencySet depset = newDependencySet().read(dotd);
    assertThat(depset.getDependencies()).containsExactlyElementsIn(Sets.newHashSet(file1, file2));
    assertThat(filename).isEqualTo(depset.getOutputFileName());
  }

  @Test
  public void dotDParser_leading_crlf() throws Exception {
    Path file1 = fileSystem.getPath("/usr/local/blah/blah/genhello/hello.cc");
    Path file2 = fileSystem.getPath("/usr/local/blah/blah/genhello/hello.h");
    String filename = "hello.o";
    Path dotd =
        scratch.file(
            "/tmp/foo.d",
            "\r\n" + filename + ": \\\r\n " + file1 + " \\\r\n " + file2 + " ");
    DependencySet depset = newDependencySet().read(dotd);
    assertThat(depset.getDependencies()).containsExactlyElementsIn(Sets.newHashSet(file1, file2));
    assertThat(filename).isEqualTo(depset.getOutputFileName());
  }

  @Test
  public void dotDParser_oddFormatting() throws Exception {
    Path file1 = fileSystem.getPath("/usr/local/blah/blah/genhello/hello.cc");
    Path file2 = fileSystem.getPath("/usr/local/blah/blah/genhello/hello.h");
    Path file3 = fileSystem.getPath("/usr/local/blah/blah/genhello/other.h");
    Path file4 = fileSystem.getPath("/usr/local/blah/blah/genhello/onemore.h");
    String filename = "hello.o";
    Path dotd = scratch.file("/tmp/foo.d",
        filename + ": " + file1 + " \\",
        " " + file2 + "\\",
        " " + file3 + " " + file4);
    DependencySet depset = newDependencySet().read(dotd);
    assertThat(depset.getDependencies())
        .containsExactlyElementsIn(Sets.newHashSet(file1, file2, file3, file4));
    assertThat(filename).isEqualTo(depset.getOutputFileName());
  }

  @Test
  public void dotDParser_relativeFilenames() throws Exception {
    Path file1 = root.getRelative("hello.cc");
    Path file2 = root.getRelative("hello.h");
    String filename = "hello.o";
    Path dotd = scratch.file("/tmp/foo.d",
        filename + ": \\",
        " " + file1.relativeTo(root) + " \\",
        " " + file2.relativeTo(root) + " ");
    DependencySet depset = newDependencySet().read(dotd);
    assertThat(depset.getDependencies()).containsExactlyElementsIn(Sets.newHashSet(file1, file2));
    assertThat(filename).isEqualTo(depset.getOutputFileName());
  }

  @Test
  public void dotDParser_escapeDollar() throws Exception {
    Path dotd =
        scratch.file(
            "/tmp/foo.d",
            "hello.o: \\",
            " /usr/local/blah/$$blah/$$hello.cc \\",
            " /usr/local/blah/blah/hel$$$$lo.h \\",
            " /usr/local/blah/$$blah/hello.h");

    Set<Path> expected =
        Sets.newHashSet(
            fileSystem.getPath("/usr/local/blah/$blah/$hello.cc"),
            fileSystem.getPath("/usr/local/blah/blah/hel$$lo.h"),
            fileSystem.getPath("/usr/local/blah/$blah/hello.h"));

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

  @Test
  public void dotDParser_emptyFile() throws Exception {
    Path dotd = scratch.file("/tmp/empty.d");
    DependencySet depset = newDependencySet().read(dotd);
    Collection<Path> headers = depset.getDependencies();
    if (!headers.isEmpty()) {
      fail("Not empty: " + headers.size() + " " + headers);
    }
    assertThat(depset.getOutputFileName()).isNull();
  }

  @Test
  public void dotDParser_multipleTargets() throws Exception {
    Path file1 = fileSystem.getPath("/usr/local/blah/blah/genhello/hello.cc");
    Path file2 = fileSystem.getPath("/usr/local/blah/blah/genhello/hello.h");
    Path dotd = scratch.file("/tmp/foo.d",
        "hello.o: \\",
        " " + file1,
        "hello2.o: \\",
        " " + file2);
    assertThat(newDependencySet().read(dotd).getDependencies())
        .containsExactlyElementsIn(Sets.newHashSet(file1, file2));
  }

  /*
   * Regression test: if gcc fails to execute remotely, and we retry locally, then the behavior
   * of gcc's DEPENDENCIES_OUTPUT option is to append, not overwrite, the .d file. As a result,
   * during retry, a second stanza is written to the file.
   *
   * We handle this by merging all of the stanzas.
   */
  @Test
  public void dotDParser_duplicateStanza() throws Exception {
    Path file1 = fileSystem.getPath("/usr/local/blah/blah/genhello/hello.cc");
    Path file2 = fileSystem.getPath("/usr/local/blah/blah/genhello/hello.h");
    Path file3 = fileSystem.getPath("/usr/local/blah/blah/genhello/other.h");
    Path dotd = scratch.file("/tmp/foo.d",
        "hello.o: \\",
        " " + file1 + " \\",
        " " + file2 + " ",
        "hello.o: \\",
        " " + file1 + " \\",
        " " + file3 + " ");
    assertThat(newDependencySet().read(dotd).getDependencies())
        .containsExactly(file1, file1, file2, file3);
  }

  @Test
  public void dotDParser_errorOnNoTrailingNewline() throws Exception {
    Path file1 = fileSystem.getPath("/usr/local/blah/blah/genhello/hello.cc");
    Path dotd = scratch.file("/tmp/foo.d");
    FileSystemUtils.writeContent(
        dotd, ("hello.o: \\\n " + file1).getBytes(Charset.forName("UTF-8")));
    IOException e = assertThrows(IOException.class, () -> newDependencySet().read(dotd));
    assertThat(e).hasMessageThat().contains("File does not end in a newline");
  }

  /*
   * Test compatibility with --config=nvcc, which writes an extra space before the colon.
   */
  @Test
  public void dotDParser_spaceBeforeColon() throws Exception {
    Path file1 = fileSystem.getPath("/usr/local/blah/blah/genhello/hello.cc");
    Path file2 = fileSystem.getPath("/usr/local/blah/blah/genhello/hello.h");
    String filename = "hello.o";
    Path dotd = scratch.file("/tmp/foo.d",
        filename + " : \\",
        " " + file1 + " \\",
        " " + file2 + " ");
    DependencySet depset = newDependencySet().read(dotd);
    assertThat(depset.getDependencies()).containsExactlyElementsIn(Sets.newHashSet(file1, file2));
    assertThat(filename).isEqualTo(depset.getOutputFileName());
  }

  /*
   * Bug-for-bug compatibility with --config=msvc, which writes malformed .d files.
   */
  @Test
  public void dotDParser_missingBackslash() throws Exception {
    Path file1 = fileSystem.getPath("/usr/local/blah/blah/genhello/hello.cc");
    Path file2 = fileSystem.getPath("/usr/local/blah/blah/genhello/hello.h");
    String filename = "hello.o";
    Path dotd = scratch.file("/tmp/foo.d",
        filename + ": ",
        " " + file1 + " \\",
        " " + file2 + " ");
    DependencySet depset = newDependencySet().read(dotd);
    assertThat(depset.getDependencies()).isEmpty();
  }

  @Test
  public void writeSet() throws Exception {
    Path file1 = fileSystem.getPath("/usr/local/blah/blah/genhello/hello.cc");
    Path file2 = fileSystem.getPath("/usr/local/blah/blah/genhello/hello.h");
    Path file3 = fileSystem.getPath("/usr/local/blah/blah/genhello/other.h");
    String filename = "/usr/local/blah/blah/genhello/hello.o";

    DependencySet depSet1 = newDependencySet();
    depSet1.addDependencies(ImmutableList.of(file1, file2, file3));
    depSet1.setOutputFileName(filename);

    Path outfile = scratch.resolve(filename);
    Path dotd = scratch.resolve("/usr/local/blah/blah/genhello/hello.d");
    FileSystemUtils.createDirectoryAndParents(dotd.getParentDirectory());
    depSet1.write(outfile, ".d");

    String dotdContents = new String(FileSystemUtils.readContentAsLatin1(dotd));
    String expected =
        "usr/local/blah/blah/genhello/hello.o:  \\\n"
            + "  /usr/local/blah/blah/genhello/hello.cc \\\n"
            + "  /usr/local/blah/blah/genhello/hello.h \\\n"
            + "  /usr/local/blah/blah/genhello/other.h\n";
    assertThat(dotdContents).isEqualTo(expected);
    assertThat(depSet1.getOutputFileName()).isEqualTo(filename);
  }

  @Test
  public void writeReadSet() throws Exception {
    String filename = "/usr/local/blah/blah/genhello/hello.d";
    Path file1 = fileSystem.getPath("/usr/local/blah/blah/genhello/hello.cc");
    Path file2 = fileSystem.getPath("/usr/local/blah/blah/genhello/hello.h");
    Path file3 = fileSystem.getPath("/usr/local/blah/blah/genhello/other.h");
    DependencySet depSet1 = newDependencySet();
    depSet1.addDependencies(ImmutableList.of(file1, file2, file3));
    depSet1.setOutputFileName(filename);

    Path dotd = scratch.resolve(filename);
    FileSystemUtils.createDirectoryAndParents(dotd.getParentDirectory());
    depSet1.write(dotd, ".d");

    DependencySet depSet2 = newDependencySet().read(dotd);
    assertThat(depSet2).isEqualTo(depSet1);
    // due to how pic.d files are written, absolute paths are changed into relatives
    assertThat("/" + depSet2.getOutputFileName()).isEqualTo(depSet1.getOutputFileName());
  }

}
