/*
 * Copyright 2014-present Facebook, Inc.
 *
 * 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.facebook.buck.cxx;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;

import com.facebook.buck.cli.FakeBuckConfig;
import com.facebook.buck.io.ProjectFilesystem;
import com.facebook.buck.model.BuildTarget;
import com.facebook.buck.model.BuildTargetFactory;
import com.facebook.buck.rules.BuildRule;
import com.facebook.buck.rules.BuildRuleParams;
import com.facebook.buck.rules.BuildRuleParamsFactory;
import com.facebook.buck.rules.BuildRuleResolver;
import com.facebook.buck.rules.BuildTargetSourcePath;
import com.facebook.buck.rules.FakeBuildRule;
import com.facebook.buck.rules.FakeBuildRuleParamsBuilder;
import com.facebook.buck.rules.PathSourcePath;
import com.facebook.buck.rules.SourcePath;
import com.facebook.buck.rules.SourcePathResolver;
import com.facebook.buck.rules.SymlinkTree;
import com.facebook.buck.rules.TestSourcePath;
import com.facebook.buck.shell.Genrule;
import com.facebook.buck.shell.GenruleBuilder;
import com.facebook.buck.testutil.AllExistingProjectFilesystem;
import com.facebook.buck.testutil.FakeProjectFilesystem;
import com.google.common.base.Joiner;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSortedSet;

import org.hamcrest.Matchers;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;

import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Collections;
import java.util.List;
import java.util.Map;

public class CxxPreprocessablesTest {

  private static final ProjectFilesystem PROJECT_FILESYSTEM = new FakeProjectFilesystem();

  private static final CxxPlatform CXX_PLATFORM = DefaultCxxPlatforms.build(
      new FakeBuckConfig());

  private static <T> void assertContains(ImmutableList<T> container, Iterable<T> items) {
    for (T item : items) {
      assertThat(container, Matchers.hasItem(item));
    }
  }

  private static class FakeCxxPreprocessorDep extends FakeBuildRule
      implements CxxPreprocessorDep {

    private final CxxPreprocessorInput input;

    public FakeCxxPreprocessorDep(
        BuildRuleParams params,
        SourcePathResolver resolver,
        CxxPreprocessorInput input) {
      super(params, resolver);
      this.input = Preconditions.checkNotNull(input);
    }

    @Override
    public CxxPreprocessorInput getCxxPreprocessorInput(CxxPlatform cxxPlatform) {
      return input;
    }

  }

  private static FakeCxxPreprocessorDep createFakeCxxPreprocessorDep(
      BuildTarget target,
      SourcePathResolver resolver,
      CxxPreprocessorInput input,
      BuildRule... deps) {
    return new FakeCxxPreprocessorDep(
        new FakeBuildRuleParamsBuilder(target)
            .setDeps(ImmutableSortedSet.copyOf(deps))
            .build(),
        resolver, input);
  }

  private static FakeCxxPreprocessorDep createFakeCxxPreprocessorDep(
      String target,
      SourcePathResolver resolver,
      CxxPreprocessorInput input,
      BuildRule... deps) {
    return createFakeCxxPreprocessorDep(
        BuildTargetFactory.newInstance(target),
        resolver,
        input,
        deps);
  }

  private static FakeBuildRule createFakeBuildRule(
      BuildTarget target,
      SourcePathResolver resolver,
      BuildRule... deps) {
    return new FakeBuildRule(
        new FakeBuildRuleParamsBuilder(target)
            .setDeps(ImmutableSortedSet.copyOf(deps))
            .build(),
        resolver);
  }

  @Rule
  public ExpectedException exception = ExpectedException.none();

  @Test
  public void resolveHeaderMap() {
    BuildTarget target = BuildTargetFactory.newInstance("//hello/world:test");
    ImmutableMap<String, SourcePath> headerMap = ImmutableMap.<String, SourcePath>of(
        "foo/bar.h", new TestSourcePath("header1.h"),
        "foo/hello.h", new TestSourcePath("header2.h"));

    // Verify that the resolveHeaderMap returns sane results.
    ImmutableMap<Path, SourcePath> expected = ImmutableMap.<Path, SourcePath>of(
        target.getBasePath().resolve("foo/bar.h"), new TestSourcePath("header1.h"),
        target.getBasePath().resolve("foo/hello.h"), new TestSourcePath("header2.h"));
    ImmutableMap<Path, SourcePath> actual = CxxPreprocessables.resolveHeaderMap(
        target.getBasePath(), headerMap);
    assertEquals(expected, actual);
  }

  @Test
  public void getTransitiveCxxPreprocessorInput() throws Exception {
    SourcePathResolver pathResolver = new SourcePathResolver(new BuildRuleResolver());
    CxxPlatform cxxPlatform = DefaultCxxPlatforms.build(new FakeBuckConfig());

    // Setup a simple CxxPreprocessorDep which contributes components to preprocessing.
    BuildTarget cppDepTarget1 = BuildTargetFactory.newInstance("//:cpp1");
    CxxPreprocessorInput input1 = CxxPreprocessorInput.builder()
        .addRules(cppDepTarget1)
        .putPreprocessorFlags(CxxSource.Type.C, "-Dtest=yes")
        .putPreprocessorFlags(CxxSource.Type.CXX, "-Dtest=yes")
        .addIncludeRoots(Paths.get("foo/bar"), Paths.get("hello"))
        .addSystemIncludeRoots(Paths.get("/usr/include"))
        .build();
    BuildTarget depTarget1 = BuildTargetFactory.newInstance("//:dep1");
    FakeCxxPreprocessorDep dep1 = createFakeCxxPreprocessorDep(depTarget1, pathResolver, input1);

    // Setup another simple CxxPreprocessorDep which contributes components to preprocessing.
    BuildTarget cppDepTarget2 = BuildTargetFactory.newInstance("//:cpp2");
    CxxPreprocessorInput input2 = CxxPreprocessorInput.builder()
        .addRules(cppDepTarget2)
        .putPreprocessorFlags(CxxSource.Type.C, "-DBLAH")
        .putPreprocessorFlags(CxxSource.Type.CXX, "-DBLAH")
        .addIncludeRoots(Paths.get("goodbye"))
        .addSystemIncludeRoots(Paths.get("test"))
        .build();
    BuildTarget depTarget2 = BuildTargetFactory.newInstance("//:dep2");
    FakeCxxPreprocessorDep dep2 = createFakeCxxPreprocessorDep(depTarget2, pathResolver, input2);

    // Create a normal dep which depends on the two CxxPreprocessorDep rules above.
    BuildTarget depTarget3 = BuildTargetFactory.newInstance("//:dep3");
    CxxPreprocessorInput nothing = CxxPreprocessorInput.EMPTY;
    FakeCxxPreprocessorDep dep3 = createFakeCxxPreprocessorDep(depTarget3,
        pathResolver,
        nothing, dep1, dep2);

    // Verify that getTransitiveCxxPreprocessorInput gets all CxxPreprocessorInput objects
    // from the relevant rules above.
    CxxPreprocessorInput expected = CxxPreprocessorInput.concat(
        ImmutableList.of(input1, input2));
    CxxPreprocessorInput actual = CxxPreprocessables.getTransitiveCxxPreprocessorInput(
        cxxPlatform,
        ImmutableList.<BuildRule>of(dep3));
    assertEquals(expected, actual);
  }

  @Test
  public void createHeaderSymlinkTreeBuildRuleHasNoDeps() {
    BuildRuleResolver resolver = new BuildRuleResolver();
    SourcePathResolver pathResolver = new SourcePathResolver(resolver);
    // Setup up the main build target and build params, which some random dep.  We'll make
    // sure the dep doesn't get propagated to the symlink rule below.
    FakeBuildRule dep = createFakeBuildRule(
        BuildTargetFactory.newInstance("//random:dep"),
        pathResolver);
    BuildTarget target = BuildTargetFactory.newInstance("//foo:bar");
    BuildRuleParams params = new FakeBuildRuleParamsBuilder(target)
        .setDeps(ImmutableSortedSet.<BuildRule>of(dep))
        .build();
    Path root = Paths.get("root");

    // Setup a simple genrule we can wrap in a BuildTargetSourcePath to model a input source
    // that is built by another rule.
    Genrule genrule = (Genrule) GenruleBuilder
        .newGenruleBuilder(BuildTargetFactory.newInstance("//:genrule"))
        .setOut("foo/bar.o")
        .build(resolver);

    // Setup the link map with both a regular path-based source path and one provided by
    // another build rule.
    ImmutableMap<Path, SourcePath> links = ImmutableMap.<Path, SourcePath>of(
        Paths.get("link1"),
        new TestSourcePath("hello"),
        Paths.get("link2"),
        new BuildTargetSourcePath(PROJECT_FILESYSTEM, genrule.getBuildTarget()));

    // Build our symlink tree rule using the helper method.
    SymlinkTree symlinkTree = CxxPreprocessables.createHeaderSymlinkTreeBuildRule(
        pathResolver,
        target,
        params,
        root,
        links);

    // Verify that the symlink tree has no deps.  This is by design, since setting symlinks can
    // be done completely independently from building the source that the links point to and
    // independently from the original deps attached to the input build rule params.
    assertTrue(symlinkTree.getDeps().isEmpty());
  }

  @Test
  public void getTransitiveNativeLinkableInputDoesNotTraversePastNonNativeLinkables()
      throws Exception {
    SourcePathResolver pathResolver = new SourcePathResolver(new BuildRuleResolver());
    CxxPlatform cxxPlatform = DefaultCxxPlatforms.build(new FakeBuckConfig());

    // Create a native linkable that sits at the bottom of the dep chain.
    String sentinal = "bottom";
    CxxPreprocessorInput bottomInput = CxxPreprocessorInput.builder()
        .putPreprocessorFlags(CxxSource.Type.C, sentinal)
        .build();
    BuildRule bottom = createFakeCxxPreprocessorDep("//:bottom", pathResolver, bottomInput);

    // Create a non-native linkable that sits in the middle of the dep chain, preventing
    // traversals to the bottom native linkable.
    BuildRule middle = new FakeBuildRule("//:middle", pathResolver, bottom);

    // Create a native linkable that sits at the top of the dep chain.
    CxxPreprocessorInput topInput = CxxPreprocessorInput.EMPTY;
    BuildRule top = createFakeCxxPreprocessorDep("//:top", pathResolver, topInput, middle);

    // Now grab all input via traversing deps and verify that the middle rule prevents pulling
    // in the bottom input.
    CxxPreprocessorInput totalInput =
        CxxPreprocessables.getTransitiveCxxPreprocessorInput(
            cxxPlatform,
            ImmutableList.of(top));
    assertTrue(bottomInput.getPreprocessorFlags().get(CxxSource.Type.C).contains(sentinal));
    assertFalse(totalInput.getPreprocessorFlags().get(CxxSource.Type.C).contains(sentinal));
  }

  @Test
  public void createPreprocessBuildRulePropagatesCxxPreprocessorDeps() {
    BuildTarget target = BuildTargetFactory.newInstance("//foo:bar");
    BuildRuleParams params = BuildRuleParamsFactory.createTrivialBuildRuleParams(target);
    BuildRuleResolver resolver = new BuildRuleResolver();
    SourcePathResolver pathResolver = new SourcePathResolver(resolver);

    FakeBuildRule dep = resolver.addToIndex(
        new FakeBuildRule(
            "//:dep1",
            new SourcePathResolver(new BuildRuleResolver())));

    CxxPreprocessorInput cxxPreprocessorInput =
        CxxPreprocessorInput.builder()
            .addRules(dep.getBuildTarget())
            .build();

    String name = "foo/bar.cpp";
    SourcePath input = new PathSourcePath(PROJECT_FILESYSTEM, target.getBasePath().resolve(name));
    CxxSource cxxSource = ImmutableCxxSource.of(
        CxxSource.Type.CXX,
        input,
        ImmutableList.<String>of());

    Map.Entry<String, CxxSource> entry =
        CxxPreprocessables.createPreprocessBuildRule(
            params,
            resolver,
            CXX_PLATFORM,
            cxxPreprocessorInput,
            /* pic */ false,
            name,
            cxxSource);
    BuildRule cxxPreprocess = pathResolver.getRule(entry.getValue().getPath()).get();
    assertEquals(ImmutableSortedSet.<BuildRule>of(dep), cxxPreprocess.getDeps());
  }

  @Test
  public void preprocessFlagsFromPlatformArePropagated() {
    BuildTarget target = BuildTargetFactory.newInstance("//foo:bar");
    BuildRuleParams params = BuildRuleParamsFactory.createTrivialBuildRuleParams(target);
    BuildRuleResolver resolver = new BuildRuleResolver();
    SourcePathResolver pathResolver = new SourcePathResolver(resolver);

    CxxPreprocessorInput cxxPreprocessorInput = CxxPreprocessorInput.EMPTY;

    String name = "source.cpp";
    CxxSource cxxSource = ImmutableCxxSource.of(
        CxxSource.Type.CXX,
        new TestSourcePath(name),
        ImmutableList.<String>of());

    ImmutableList<String> platformFlags = ImmutableList.of("-some", "-flags");
    CxxPlatform platform = DefaultCxxPlatforms.build(
        new FakeBuckConfig(
            ImmutableMap.<String, Map<String, String>>of(
                "cxx", ImmutableMap.of("cxxppflags", Joiner.on(" ").join(platformFlags)))));

    // Verify that platform flags make it to the compile rule.
    Map.Entry<String, CxxSource> output =
        CxxPreprocessables.createPreprocessBuildRule(
            params,
            resolver,
            platform,
            cxxPreprocessorInput,
            /* pic */ false,
            name,
            cxxSource);
    CxxPreprocess cxxPreprocess =
        (CxxPreprocess) pathResolver.getRule(output.getValue().getPath()).get();
    assertNotEquals(
        -1,
        Collections.indexOfSubList(cxxPreprocess.getFlags(), platformFlags));
  }

  @Test
  public void checkCorrectFlagsAreUsed() {
    BuildRuleResolver buildRuleResolver = new BuildRuleResolver();
    SourcePathResolver sourcePathResolver = new SourcePathResolver(buildRuleResolver);
    BuildTarget target = BuildTargetFactory.newInstance("//:target");
    BuildRuleParams params = BuildRuleParamsFactory.createTrivialBuildRuleParams(target);
    ProjectFilesystem filesystem = new AllExistingProjectFilesystem();
    Joiner space = Joiner.on(" ");

    ImmutableList<String> explicitCppflags = ImmutableList.of("-explicit-cppflag");
    ImmutableList<String> explicitCxxppflags = ImmutableList.of("-explicit-cxxppflag");
    CxxPreprocessorInput cxxPreprocessorInput =
        CxxPreprocessorInput.builder()
            .putAllPreprocessorFlags(CxxSource.Type.C, explicitCppflags)
            .putAllPreprocessorFlags(CxxSource.Type.CXX, explicitCxxppflags)
            .build();

    ImmutableList<String> asppflags = ImmutableList.of("-asppflag", "-asppflag");

    SourcePath cpp = new TestSourcePath("cpp");
    ImmutableList<String> cppflags = ImmutableList.of("-cppflag", "-cppflag");

    SourcePath cxxpp = new TestSourcePath("cxxpp");
    ImmutableList<String> cxxppflags = ImmutableList.of("-cxxppflag", "-cxxppflag");

    FakeBuckConfig buckConfig = new FakeBuckConfig(
        ImmutableMap.<String, Map<String, String>>of(
            "cxx", ImmutableMap.<String, String>builder()
                .put("asppflags", space.join(asppflags))
                .put("cpp", sourcePathResolver.getPath(cpp).toString())
                .put("cppflags", space.join(cppflags))
                .put("cxxpp", sourcePathResolver.getPath(cxxpp).toString())
                .put("cxxppflags", space.join(cxxppflags))
                .build()),
        filesystem);
    CxxPlatform platform = DefaultCxxPlatforms.build(buckConfig);

    String cSourceName = "test.c";
    List<String> perFileFlagsForTestC =
        ImmutableList.of("-per-file-flag-for-c-file", "-and-another-one");
    CxxSource cSource = ImmutableCxxSource.of(
        CxxSource.Type.C,
        new TestSourcePath(cSourceName),
        perFileFlagsForTestC);
    Map.Entry<String, CxxSource> cPreprocessEntry =
        CxxPreprocessables.createPreprocessBuildRule(
            params,
            buildRuleResolver,
            platform,
            cxxPreprocessorInput,
            /* pic */ false,
            cSourceName,
            cSource);
    CxxPreprocess cPreprocess =
        (CxxPreprocess) sourcePathResolver.getRule(cPreprocessEntry.getValue().getPath()).get();
    assertContains(cPreprocess.getFlags(), explicitCppflags);
    assertContains(cPreprocess.getFlags(), cppflags);
    assertContains(cPreprocess.getFlags(), perFileFlagsForTestC);

    String cxxSourceName = "test.cpp";
    List<String> perFileFlagsForTestCpp =
        ImmutableList.of("-per-file-flag-for-cpp-file");
    CxxSource cxxSource = ImmutableCxxSource.of(
        CxxSource.Type.CXX,
        new TestSourcePath(cxxSourceName),
        perFileFlagsForTestCpp);
    Map.Entry<String, CxxSource> cxxPreprocessEntry =
        CxxPreprocessables.createPreprocessBuildRule(
            params,
            buildRuleResolver,
            platform,
            cxxPreprocessorInput,
            /* pic */ false,
            cxxSourceName,
            cxxSource);
    CxxPreprocess cxxPreprocess =
        (CxxPreprocess) sourcePathResolver.getRule(cxxPreprocessEntry.getValue().getPath()).get();
    assertContains(cxxPreprocess.getFlags(), explicitCxxppflags);
    assertContains(cxxPreprocess.getFlags(), cxxppflags);
    assertContains(cxxPreprocess.getFlags(), perFileFlagsForTestCpp);

    String assemblerWithCppSourceName = "test.S";
    List<String> perFileFlagsForTestS =
        ImmutableList.of("-a-flag-for-s-file", "-another-one", "-one-more");
    CxxSource assemblerWithCppSource = ImmutableCxxSource.of(
        CxxSource.Type.ASSEMBLER_WITH_CPP,
        new TestSourcePath(assemblerWithCppSourceName),
        perFileFlagsForTestS);
    Map.Entry<String, CxxSource> assemblerWithCppCompileEntry =
        CxxPreprocessables.createPreprocessBuildRule(
            params,
            buildRuleResolver,
            platform,
            cxxPreprocessorInput,
            /* pic */ false,
            assemblerWithCppSourceName,
            assemblerWithCppSource);
    CxxPreprocess assemblerWithCppPreprocess =
        (CxxPreprocess) sourcePathResolver.getRule(
            assemblerWithCppCompileEntry.getValue().getPath()).get();
    assertContains(assemblerWithCppPreprocess.getFlags(), asppflags);
    assertContains(assemblerWithCppPreprocess.getFlags(), perFileFlagsForTestS);
  }

  @Test
  public void languageFlagsArePassed() {
    BuildRuleResolver buildRuleResolver = new BuildRuleResolver();
    SourcePathResolver pathResolver = new SourcePathResolver(buildRuleResolver);
    BuildTarget target = BuildTargetFactory.newInstance("//:target");
    BuildRuleParams params = BuildRuleParamsFactory.createTrivialBuildRuleParams(target);

    String name = "foo/bar.cpp";
    SourcePath input = new PathSourcePath(PROJECT_FILESYSTEM, target.getBasePath().resolve(name));
    CxxSource cxxSource = ImmutableCxxSource.of(
        CxxSource.Type.CXX,
        input,
        ImmutableList.<String>of());

    Map.Entry<String, CxxSource> cxxPreprocessEntry =
        CxxPreprocessables.createPreprocessBuildRule(
            params,
            buildRuleResolver,
            CXX_PLATFORM,
            CxxPreprocessorInput.EMPTY,
            /* pic */ false,
            name,
            cxxSource);
    CxxPreprocess cxxPreprocess =
        (CxxPreprocess) pathResolver.getRule(
            cxxPreprocessEntry.getValue().getPath()).get();
    assertThat(cxxPreprocess.getFlags(), Matchers.contains("-x", "c++"));

    name = "foo/bar.m";
    input = new PathSourcePath(PROJECT_FILESYSTEM, target.getBasePath().resolve(name));
    cxxSource = ImmutableCxxSource.of(
        CxxSource.Type.OBJC,
        input,
        ImmutableList.<String>of());

    cxxPreprocessEntry =
        CxxPreprocessables.createPreprocessBuildRule(
            params,
            buildRuleResolver,
            CXX_PLATFORM,
            CxxPreprocessorInput.EMPTY,
            /* pic */ false,
            name,
            cxxSource);
    cxxPreprocess =
        (CxxPreprocess) pathResolver.getRule(
            cxxPreprocessEntry.getValue().getPath()).get();
    assertThat(cxxPreprocess.getFlags(), Matchers.contains("-x", "objective-c"));

    name = "foo/bar.mm";
    input = new PathSourcePath(PROJECT_FILESYSTEM, target.getBasePath().resolve(name));
    cxxSource = ImmutableCxxSource.of(
        CxxSource.Type.OBJCXX,
        input,
        ImmutableList.<String>of());

    cxxPreprocessEntry =
        CxxPreprocessables.createPreprocessBuildRule(
            params,
            buildRuleResolver,
            CXX_PLATFORM,
            CxxPreprocessorInput.EMPTY,
            /* pic */ false,
            name,
            cxxSource);
    cxxPreprocess =
        (CxxPreprocess) pathResolver.getRule(
            cxxPreprocessEntry.getValue().getPath()).get();
    assertThat(cxxPreprocess.getFlags(), Matchers.contains("-x", "objective-c++"));

    name = "foo/bar.c";
    input = new PathSourcePath(PROJECT_FILESYSTEM, target.getBasePath().resolve(name));
    cxxSource = ImmutableCxxSource.of(
        CxxSource.Type.C,
        input,
        ImmutableList.<String>of());

    cxxPreprocessEntry =
        CxxPreprocessables.createPreprocessBuildRule(
            params,
            buildRuleResolver,
            CXX_PLATFORM,
            CxxPreprocessorInput.EMPTY,
            /* pic */ false,
            name,
            cxxSource);
    cxxPreprocess =
        (CxxPreprocess) pathResolver.getRule(
            cxxPreprocessEntry.getValue().getPath()).get();
    assertThat(cxxPreprocess.getFlags(), Matchers.contains("-x", "c"));
  }

  @Test
  public void getTransitiveDependenciesThrowsForConflictingHeaders()
      throws Exception {
    SourcePathResolver pathResolver = new SourcePathResolver(new BuildRuleResolver());
    CxxPlatform cxxPlatform = DefaultCxxPlatforms.build(new FakeBuckConfig());

    CxxPreprocessorInput bottomInput = CxxPreprocessorInput.builder()
        .setIncludes(
            ImmutableCxxHeaders.builder()
                .putNameToPathMap(
                    Paths.get("prefix/file.h"),
                    new TestSourcePath("bottom/file.h"))
                .putFullNameToPathMap(
                    Paths.get("buck-out/something/prefix/file.h"),
                    new TestSourcePath("bottom/file.h"))
                .build())
        .build();
    BuildRule bottom = createFakeCxxPreprocessorDep("//:bottom", pathResolver, bottomInput);

    CxxPreprocessorInput topInput = CxxPreprocessorInput.builder()
        .setIncludes(
            ImmutableCxxHeaders.builder()
                .putNameToPathMap(
                    Paths.get("prefix/file.h"),
                    new TestSourcePath("top/file.h"))
                .putFullNameToPathMap(
                    Paths.get("buck-out/something-else/prefix/file.h"),
                    new TestSourcePath("top/file.h"))
                .build())
        .build();
    BuildRule top = createFakeCxxPreprocessorDep("//:top", pathResolver, topInput, bottom);

    exception.expect(CxxPreprocessorInput.ConflictingHeadersException.class);
    exception.expectMessage("'prefix/file.h' maps to both [bottom/file.h, top/file.h].");

    CxxPreprocessables.getTransitiveCxxPreprocessorInput(
        cxxPlatform,
        ImmutableList.of(top));
  }

  @Test
  public void getTransitiveDependenciesDoesNotThrowsForCompatibleHeaders()
      throws Exception {
    SourcePathResolver pathResolver = new SourcePathResolver(new BuildRuleResolver());
    CxxPlatform cxxPlatform = DefaultCxxPlatforms.build(new FakeBuckConfig());

    CxxPreprocessorInput bottomInput = CxxPreprocessorInput.builder()
        .setIncludes(
            ImmutableCxxHeaders.builder()
                .putNameToPathMap(
                    Paths.get("prefix/file.h"),
                    new TestSourcePath("common/file.h"))
                .putFullNameToPathMap(
                    Paths.get("buck-out/something/prefix/file.h"),
                    new TestSourcePath("common/file.h"))
                .build())
        .build();
    BuildRule bottom = createFakeCxxPreprocessorDep("//:bottom", pathResolver, bottomInput);

    CxxPreprocessorInput topInput = CxxPreprocessorInput.builder()
        .setIncludes(
            ImmutableCxxHeaders.builder()
                .putNameToPathMap(
                    Paths.get("prefix/file.h"),
                    new TestSourcePath("common/file.h"))
                .putFullNameToPathMap(
                    Paths.get("buck-out/something-else/prefix/file.h"),
                    new TestSourcePath("common/file.h"))
                .build())
        .build();
    BuildRule top = createFakeCxxPreprocessorDep("//:top", pathResolver, topInput, bottom);

    CxxPreprocessorInput expected = CxxPreprocessorInput.builder()
        .setIncludes(
            ImmutableCxxHeaders.builder()
                .putNameToPathMap(
                    Paths.get("prefix/file.h"),
                    new TestSourcePath("common/file.h"))
                .putFullNameToPathMap(
                    Paths.get("buck-out/something/prefix/file.h"),
                    new TestSourcePath("common/file.h"))
                .putFullNameToPathMap(
                    Paths.get("buck-out/something-else/prefix/file.h"),
                    new TestSourcePath("common/file.h"))
                .build())
        .build();

    assertEquals(
        expected,
        CxxPreprocessables.getTransitiveCxxPreprocessorInput(
            cxxPlatform,
            ImmutableList.of(top)));
  }

}
