// 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.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 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_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")));
    try {
      newDependencySet().read(dotd);
      fail();
    } catch (IOException e) {
      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());
  }

}
