/*
 * 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.rules;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

import com.facebook.buck.io.ProjectFilesystem;
import com.facebook.buck.model.BuildTarget;
import com.facebook.buck.model.BuildTargetFactory;
import com.facebook.buck.shell.Genrule;
import com.facebook.buck.shell.GenruleBuilder;
import com.facebook.buck.testutil.FakeProjectFilesystem;
import com.facebook.buck.testutil.MoreAsserts;
import com.facebook.buck.util.HumanReadableException;
import com.google.common.base.Optional;
import com.google.common.collect.ImmutableList;

import org.junit.Test;

import java.nio.file.Path;
import java.nio.file.Paths;

public class SourcePathResolverTest {

  @Test
  public void resolvePathSourcePath() {
    ProjectFilesystem projectFilesystem = new FakeProjectFilesystem();
    SourcePathResolver pathResolver = new SourcePathResolver(new BuildRuleResolver());
    Path expectedPath = Paths.get("foo");
    SourcePath sourcePath = new PathSourcePath(projectFilesystem, expectedPath);

    assertEquals(expectedPath, pathResolver.getPath(sourcePath));
  }

  @Test
  public void resolveBuildTargetSourcePath() {
    ProjectFilesystem projectFilesystem = new FakeProjectFilesystem();
    BuildRuleResolver resolver = new BuildRuleResolver();
    SourcePathResolver pathResolver = new SourcePathResolver(resolver);
    Path expectedPath = Paths.get("foo");
    BuildRule rule = new OutputOnlyBuildRule(
        new FakeBuildRuleParamsBuilder(BuildTargetFactory.newInstance("//:foo")).build(),
        pathResolver,
        expectedPath);
    resolver.addToIndex(rule);
    SourcePath sourcePath = new BuildTargetSourcePath(projectFilesystem, rule.getBuildTarget());

    assertEquals(expectedPath, pathResolver.getPath(sourcePath));
  }

  @Test
  public void resolveBuildTargetSourcePathWithOverriddenOutputPath() {
    ProjectFilesystem projectFilesystem = new FakeProjectFilesystem();
    BuildRuleResolver resolver = new BuildRuleResolver();
    SourcePathResolver pathResolver = new SourcePathResolver(resolver);
    Path expectedPath = Paths.get("foo");
    BuildRule rule = new OutputOnlyBuildRule(
        new FakeBuildRuleParamsBuilder(BuildTargetFactory.newInstance("//:foo")).build(),
        pathResolver,
        Paths.get("notfoo"));
    resolver.addToIndex(rule);
    SourcePath sourcePath = new BuildTargetSourcePath(
        projectFilesystem,
        rule.getBuildTarget(),
        expectedPath);

    assertEquals(expectedPath, pathResolver.getPath(sourcePath));
  }

  @Test
  public void resolveMixedPaths() {
    ProjectFilesystem projectFilesystem = new FakeProjectFilesystem();
    BuildRuleResolver resolver = new BuildRuleResolver();
    SourcePathResolver pathResolver = new SourcePathResolver(resolver);
    Path pathSourcePathExpectedPath = Paths.get("foo");
    Path buildTargetSourcePathExpectedPath = Paths.get("bar");
    Path buildRuleWithOverriddenOutputPathExpectedPath = Paths.get("baz");
    SourcePath pathSourcePath = new PathSourcePath(projectFilesystem, pathSourcePathExpectedPath);
    BuildRule rule = new OutputOnlyBuildRule(
        new FakeBuildRuleParamsBuilder(BuildTargetFactory.newInstance("//:bar")).build(),
        pathResolver,
        buildTargetSourcePathExpectedPath);
    resolver.addToIndex(rule);
    SourcePath buildTargetSourcePath = new BuildTargetSourcePath(
        projectFilesystem,
        rule.getBuildTarget());
    BuildRule ruleWithOverriddenOutputPath = new OutputOnlyBuildRule(
        new FakeBuildRuleParamsBuilder(BuildTargetFactory.newInstance("//:baz")).build(),
        pathResolver,
        Paths.get("notbaz"));
    resolver.addToIndex(ruleWithOverriddenOutputPath);
    SourcePath buildTargetSourcePathWithOverriddenOutputPath = new BuildTargetSourcePath(
        projectFilesystem,
        ruleWithOverriddenOutputPath.getBuildTarget(),
        buildRuleWithOverriddenOutputPathExpectedPath);

    assertEquals(
        ImmutableList.of(
            pathSourcePathExpectedPath,
            buildTargetSourcePathExpectedPath,
            buildRuleWithOverriddenOutputPathExpectedPath),
        pathResolver.getAllPaths(
            ImmutableList.of(
                pathSourcePath,
                buildTargetSourcePath,
                buildTargetSourcePathWithOverriddenOutputPath)));
  }

  @Test
  public void getRuleCanGetRuleOfBuildRuleSoucePath() {
    ProjectFilesystem projectFilesystem = new FakeProjectFilesystem();
    BuildRuleResolver resolver = new BuildRuleResolver();
    SourcePathResolver pathResolver = new SourcePathResolver(resolver);
    BuildRule rule = new OutputOnlyBuildRule(
        new FakeBuildRuleParamsBuilder(BuildTargetFactory.newInstance("//:foo")).build(),
        pathResolver,
        Paths.get("foo"));
    resolver.addToIndex(rule);
    SourcePath sourcePath = new BuildTargetSourcePath(projectFilesystem, rule.getBuildTarget());

    assertEquals(Optional.of(rule), pathResolver.getRule(sourcePath));
  }

  @Test
  public void getRuleCannotGetRuleOfPathSoucePath() {
    ProjectFilesystem projectFilesystem = new FakeProjectFilesystem();
    SourcePathResolver pathResolver = new SourcePathResolver(new BuildRuleResolver());
    SourcePath sourcePath = new PathSourcePath(projectFilesystem, Paths.get("foo"));

    assertEquals(Optional.<BuildRule>absent(), pathResolver.getRule(sourcePath));
  }

  @Test
  public void getRelativePathCanGetRelativePathOfPathSourcePath() {
    ProjectFilesystem projectFilesystem = new FakeProjectFilesystem();
    SourcePathResolver pathResolver = new SourcePathResolver(new BuildRuleResolver());
    Path expectedPath = Paths.get("foo");
    SourcePath sourcePath = new PathSourcePath(projectFilesystem, expectedPath);

    assertEquals(Optional.of(expectedPath), pathResolver.getRelativePath(sourcePath));
  }

  @Test
  public void getRelativePathCannotGetRelativePathOfBuildTargetSourcePath() {
    ProjectFilesystem projectFilesystem = new FakeProjectFilesystem();
    BuildRuleResolver resolver = new BuildRuleResolver();
    SourcePathResolver pathResolver = new SourcePathResolver(resolver);
    BuildRule rule = new OutputOnlyBuildRule(
        new FakeBuildRuleParamsBuilder(BuildTargetFactory.newInstance("//:foo")).build(),
        pathResolver,
        Paths.get("foo"));
    resolver.addToIndex(rule);
    SourcePath sourcePath = new BuildTargetSourcePath(projectFilesystem, rule.getBuildTarget());

    assertEquals(Optional.<Path>absent(), pathResolver.getRelativePath(sourcePath));
  }

  @Test
  public void testEmptyListAsInputToFilterInputsToCompareToOutput() {
    Iterable<SourcePath> sourcePaths = ImmutableList.of();
    Iterable<Path> inputs = new SourcePathResolver(
        new BuildRuleResolver()).filterInputsToCompareToOutput(sourcePaths);
    MoreAsserts.assertIterablesEquals(ImmutableList.<String>of(), inputs);
  }

  @Test
  public void testFilterInputsToCompareToOutputExcludesBuildTargetSourcePaths() {
    ProjectFilesystem projectFilesystem = new FakeProjectFilesystem();
    BuildRuleResolver resolver = new BuildRuleResolver();
    SourcePathResolver pathResolver = new SourcePathResolver(resolver);
    FakeBuildRule rule = new FakeBuildRule(
        ImmutableBuildRuleType.of("example"),
        BuildTargetFactory.newInstance("//java/com/facebook:facebook"),
        pathResolver);
    resolver.addToIndex(rule);

    Iterable<? extends SourcePath> sourcePaths = ImmutableList.of(
        new TestSourcePath("java/com/facebook/Main.java"),
        new TestSourcePath("java/com/facebook/BuckConfig.java"),
        new BuildTargetSourcePath(projectFilesystem, rule.getBuildTarget()));
    Iterable<Path> inputs = pathResolver.filterInputsToCompareToOutput(sourcePaths);
    MoreAsserts.assertIterablesEquals(
        "Iteration order should be preserved: results should not be alpha-sorted.",
        ImmutableList.of(
            Paths.get("java/com/facebook/Main.java"),
            Paths.get("java/com/facebook/BuckConfig.java")),
        inputs);
  }

  @Test
  public void testFilterBuildRuleInputsExcludesPathSourcePaths() {
    ProjectFilesystem projectFilesystem = new FakeProjectFilesystem();
    BuildRuleResolver resolver = new BuildRuleResolver();
    SourcePathResolver pathResolver = new SourcePathResolver(resolver);
    FakeBuildRule rule = new FakeBuildRule(
        ImmutableBuildRuleType.of("example"),
        BuildTargetFactory.newInstance("//java/com/facebook:facebook"),
        pathResolver);
    resolver.addToIndex(rule);
    FakeBuildRule rule2 = new FakeBuildRule(
        ImmutableBuildRuleType.of("foo"),
        BuildTargetFactory.newInstance("//bar:foo"),
        pathResolver);
    resolver.addToIndex(rule2);

    Iterable<? extends SourcePath> sourcePaths = ImmutableList.of(
        new TestSourcePath("java/com/facebook/Main.java"),
        new BuildTargetSourcePath(projectFilesystem, rule.getBuildTarget()),
        new TestSourcePath("java/com/facebook/BuckConfig.java"),
        new BuildTargetSourcePath(projectFilesystem, rule2.getBuildTarget()));
    Iterable<BuildRule> inputs = pathResolver.filterBuildRuleInputs(sourcePaths);
    MoreAsserts.assertIterablesEquals(
        "Iteration order should be preserved: results should not be alpha-sorted.",
        ImmutableList.of(
            rule,
            rule2),
        inputs);
  }

  @Test
  public void getSourcePathNameOnPathSourcePath() {
    ProjectFilesystem projectFilesystem = new FakeProjectFilesystem();
    Path path = Paths.get("hello/world.txt");

    // Test that constructing a PathSourcePath without an explicit name resolves to the
    // string representation of the path.
    PathSourcePath pathSourcePath1 = new PathSourcePath(projectFilesystem, path);
    String actual1 = new SourcePathResolver(new BuildRuleResolver()).getSourcePathName(
        BuildTargetFactory.newInstance("//:test"),
        pathSourcePath1);
    assertEquals(path.toString(), actual1);
  }

  @Test
  public void getSourcePathNameOnBuildTargetSourcePath() {
    ProjectFilesystem projectFilesystem = new FakeProjectFilesystem();
    BuildRuleResolver resolver = new BuildRuleResolver();
    SourcePathResolver pathResolver = new SourcePathResolver(resolver);

    // Verify that wrapping a genrule in a BuildTargetSourcePath resolves to the output name of
    // that genrule.
    String out = "test/blah.txt";
    Genrule genrule = (Genrule) GenruleBuilder
        .newGenruleBuilder(BuildTargetFactory.newInstance("//:genrule"))
        .setOut(out)
        .build(resolver);
    BuildTargetSourcePath buildTargetSourcePath1 = new BuildTargetSourcePath(
        projectFilesystem,
        genrule.getBuildTarget());
    String actual1 = pathResolver.getSourcePathName(
        BuildTargetFactory.newInstance("//:test"),
        buildTargetSourcePath1);
    assertEquals(out, actual1);

    // Test that using other BuildRule types resolves to the short name.
    BuildTarget fakeBuildTarget = BuildTargetFactory.newInstance("//:fake");
    FakeBuildRule fakeBuildRule = new FakeBuildRule(
        new FakeBuildRuleParamsBuilder(fakeBuildTarget).build(),
        pathResolver);
    resolver.addToIndex(fakeBuildRule);
    BuildTargetSourcePath buildTargetSourcePath2 = new BuildTargetSourcePath(
        projectFilesystem,
        fakeBuildRule.getBuildTarget());
    String actual2 = pathResolver.getSourcePathName(
        BuildTargetFactory.newInstance("//:test"),
        buildTargetSourcePath2);
    assertEquals(fakeBuildTarget.getShortName(), actual2);
  }

  @Test
  public void getSourcePathNamesThrowsOnDuplicates() {
    ProjectFilesystem projectFilesystem = new FakeProjectFilesystem();
    BuildTarget target = BuildTargetFactory.newInstance("//:test");
    String parameter = "srcs";
    PathSourcePath pathSourcePath1 = new PathSourcePath(projectFilesystem, Paths.get("same_name"));
    PathSourcePath pathSourcePath2 = new PathSourcePath(projectFilesystem, Paths.get("same_name"));

    // Try to resolve these source paths, with the same name, together and verify that an
    // exception is thrown.
    try {
      new SourcePathResolver(new BuildRuleResolver()).getSourcePathNames(
          target,
          parameter,
          ImmutableList.<SourcePath>of(pathSourcePath1, pathSourcePath2));
      fail("expected to throw");
    } catch (HumanReadableException e) {
      assertTrue(e.getMessage().contains("duplicate entries"));
    }
  }

}
