/*
 * Copyright 2012-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.cli;

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

import com.facebook.buck.cli.TargetsCommand.TargetsCommandPredicate;
import com.facebook.buck.event.BuckEventBus;
import com.facebook.buck.event.BuckEventBusFactory;
import com.facebook.buck.java.DefaultJavaLibraryRule;
import com.facebook.buck.java.JavaTestRule;
import com.facebook.buck.java.PrebuiltJarRule;
import com.facebook.buck.json.BuildFileParseException;
import com.facebook.buck.model.BuildTarget;
import com.facebook.buck.model.BuildTargetFactory;
import com.facebook.buck.model.BuildTargetPattern;
import com.facebook.buck.parser.BuildTargetParseException;
import com.facebook.buck.parser.BuildTargetParser;
import com.facebook.buck.parser.NoSuchBuildTargetException;
import com.facebook.buck.parser.ParseContext;
import com.facebook.buck.parser.PartialGraph;
import com.facebook.buck.parser.PartialGraphFactory;
import com.facebook.buck.rules.ArtifactCache;
import com.facebook.buck.rules.BuildRule;
import com.facebook.buck.rules.BuildRuleResolver;
import com.facebook.buck.rules.BuildRuleType;
import com.facebook.buck.rules.DependencyGraph;
import com.facebook.buck.rules.FakeAbstractBuildRuleBuilderParams;
import com.facebook.buck.rules.FakeBuildRule;
import com.facebook.buck.rules.KnownBuildRuleTypes;
import com.facebook.buck.rules.NoopArtifactCache;
import com.facebook.buck.testutil.BuckTestConstant;
import com.facebook.buck.testutil.RuleMap;
import com.facebook.buck.testutil.TestConsole;
import com.facebook.buck.util.ProjectFilesystem;
import com.facebook.buck.util.environment.Platform;
import com.fasterxml.jackson.core.JsonFactory;
import com.fasterxml.jackson.core.JsonParser.Feature;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.base.Charsets;
import com.google.common.base.Function;
import com.google.common.base.Functions;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableSortedSet;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.io.Files;

import org.easymock.EasyMock;
import org.junit.Before;
import org.junit.Test;
import org.kohsuke.args4j.CmdLineException;

import java.io.File;
import java.io.IOException;
import java.io.Reader;
import java.io.StringReader;
import java.util.List;
import java.util.SortedMap;

public class TargetsCommandTest {

  private static final Function<String, String> PATH_RELATIVIZER = Functions.identity();
  private final String projectRootPath = ".";
  private final File projectRoot = new File(projectRootPath);
  private TestConsole console;
  private TargetsCommand targetsCommand;

  private SortedMap<String, BuildRule> buildBuildTargets(String outputFile, String name) {
    return buildBuildTargets(outputFile, name, "//");
  }

  private SortedMap<String, BuildRule> buildBuildTargets(String outputFile,
      String name,
      String baseName) {
    SortedMap<String, BuildRule> buildRules = Maps.newTreeMap();
    BuildTarget buildTarget = new BuildTarget(baseName, name);
    FakeBuildRule buildRule = new FakeBuildRule(BuildRuleType.JAVA_LIBRARY,
        buildTarget,
        ImmutableSortedSet.<BuildRule>of(),
        ImmutableSet.<BuildTargetPattern>of());
    buildRule.setOutputFile(outputFile);

    buildRules.put(buildTarget.getFullyQualifiedName(), buildRule);
    return buildRules;
  }

  private String testDataPath(String fileName) {
    return "testdata/com/facebook/buck/cli/" + fileName;
  }

  @Before
  public void setUp() {
    console = new TestConsole();
    ProjectFilesystem projectFilesystem = new ProjectFilesystem(projectRoot);
    KnownBuildRuleTypes buildRuleTypes = new KnownBuildRuleTypes();
    ArtifactCache artifactCache = new NoopArtifactCache();
    BuckEventBus eventBus = BuckEventBusFactory.newInstance();
    targetsCommand =
        new TargetsCommand(new CommandRunnerParams(
            console,
            projectFilesystem,
            buildRuleTypes,
            new InstanceArtifactCacheFactory(artifactCache),
            eventBus,
            BuckTestConstant.PYTHON_INTERPRETER,
            Platform.detect()));
  }

  @Test
  public void testJsonOutputForBuildTarget() throws IOException, BuildFileParseException {
    final String testBuckFileJson1 = testDataPath("TargetsCommandTestBuckJson1.js");
    final String outputFile = "buck-out/gen/test/outputFile";
    JsonFactory jsonFactory = new JsonFactory();
    ObjectMapper mapper = new ObjectMapper();

    // run `buck targets` on the build file and parse the observed JSON.
    SortedMap<String, BuildRule> buildRules = buildBuildTargets(
        outputFile, "test-library", "//testdata/com/facebook/buck/cli");

    targetsCommand.printJsonForTargets(buildRules, /* includes */ ImmutableList.<String>of());
    String observedOutput = console.getTextWrittenToStdOut();
    JsonNode observed = mapper.readTree(jsonFactory.createJsonParser(observedOutput));

    // parse the expected JSON.
    String expectedJson = Files.toString(new File(testBuckFileJson1), Charsets.UTF_8)
        .replace("{$OUTPUT_FILE}", outputFile);
    JsonNode expected = mapper.readTree(jsonFactory.createJsonParser(expectedJson)
        .enable(Feature.ALLOW_COMMENTS));

    assertEquals("Output from targets command should match expected JSON.", expected, observed);
    assertEquals("Nothing should be printed to stderr.",
        "",
        console.getTextWrittenToStdErr());
  }

  @Test
  public void testNormalOutputForBuildTarget() throws IOException {
    final String outputFile = "buck-out/gen/test/outputFile";

    // run `buck targets` on the build file and parse the observed JSON.
    SortedMap<String, BuildRule> buildRules = buildBuildTargets(outputFile, "test-library");

    targetsCommand.printTargetsList(buildRules, /* showOutput */ false);
    String observedOutput = console.getTextWrittenToStdOut();

    assertEquals("Output from targets command should match expected output.",
        "//:test-library",
        observedOutput.trim());
    assertEquals("Nothing should be printed to stderr.",
        "",
        console.getTextWrittenToStdErr());
  }

  @Test
  public void testNormalOutputForBuildTargetWithOutput() throws IOException {
    final String outputFile = "buck-out/gen/test/outputFile";

    // run `buck targets` on the build file and parse the observed JSON.
    SortedMap<String, BuildRule> buildRules = buildBuildTargets(
        outputFile,
        "test-library");

    targetsCommand.printTargetsList(buildRules, /* showOutput */ true);
    String observedOutput = console.getTextWrittenToStdOut();

    assertEquals("Output from targets command should match expected output.",
        "//:test-library " + outputFile,
        observedOutput.trim());
    assertEquals("Nothing should be printed to stderr.",
        "",
        console.getTextWrittenToStdErr());
  }

  @Test
  public void testJsonOutputForMissingBuildTarget() throws BuildFileParseException, IOException {
    // nonexistent target should not exist.
    final String outputFile = "buck-out/gen/test/outputFile";
    SortedMap<String, BuildRule> buildRules = buildBuildTargets(outputFile, "nonexistent");
    targetsCommand.printJsonForTargets(buildRules, /* includes */ ImmutableList.<String>of());

    String output = console.getTextWrittenToStdOut();
    assertEquals("[\n]\n", output);
    assertEquals("unable to find rule for target //:nonexistent\n",
        console.getTextWrittenToStdErr());
  }

  @Test
  public void testValidateBuildTargetForNonAliasTarget()
      throws IOException, NoSuchBuildTargetException {
    // Set up the test buck file, parser, config, options.
    BuildTargetParser parser = EasyMock.createMock(BuildTargetParser.class);
    EasyMock.expect(parser.parse("//:test-library", ParseContext.fullyQualified()))
        .andReturn(new BuildTarget(
            "//testdata/com/facebook/buck/cli", "test-library"))
        .anyTimes();
    EasyMock.expect(parser.parse("//:", ParseContext.fullyQualified()))
        .andThrow(new BuildTargetParseException(
            String.format("%s cannot end with a colon.", "//:")))
        .anyTimes();
    EasyMock.expect(parser.parse("//blah/foo:bar", ParseContext.fullyQualified()))
        .andThrow(EasyMock.createMock(NoSuchBuildTargetException.class))
        .anyTimes();
    EasyMock.expect(parser.parse("//:test-libarry", ParseContext.fullyQualified()))
        .andReturn(new BuildTarget(
            "//testdata/com/facebook/buck/cli", "test-libarry"))
        .anyTimes();
    EasyMock.replay(parser);
    Reader reader = new StringReader("");
    BuckConfig config = BuckConfig.createFromReader(
        reader, new ProjectFilesystem(new File(".")), parser, Platform.detect());
    TargetsCommandOptions options = new TargetsCommandOptions(config);

    // Test a valid target.
    assertEquals(
        "//testdata/com/facebook/buck/cli:test-library",
        targetsCommand.validateBuildTargetForFullyQualifiedTarget("//:test-library", options));

    // Targets that will be rejected by BuildTargetParser with an exception.
    try {
      targetsCommand.validateBuildTargetForFullyQualifiedTarget("//:", options);
      fail("Should have thrown BuildTargetParseException.");
    } catch (BuildTargetParseException e) {
      assertEquals("//: cannot end with a colon.", e.getHumanReadableErrorMessage());
    }
    assertNull(targetsCommand.validateBuildTargetForFullyQualifiedTarget(
        "//blah/foo:bar", options));

    // Should pass BuildTargetParser but validateBuildTargetForNonAliasTarget will return null.
    assertNull(targetsCommand.validateBuildTargetForFullyQualifiedTarget(
        "//:test-libarry", options));
  }

  private PartialGraph createGraphFromBuildRules(BuildRuleResolver ruleResolver,
      List<String> targets) {
    List<BuildTarget> buildTargets = Lists.transform(targets, new Function<String, BuildTarget>() {
      @Override
      public BuildTarget apply(String target) {
        return BuildTargetFactory.newInstance(target);
      }
    });

    DependencyGraph dependencyGraph = RuleMap.createGraphFromBuildRules(ruleResolver);
    return PartialGraphFactory.newInstance(dependencyGraph, buildTargets);
  }

  @Test
  public void testGetMachingBuildTargets() throws CmdLineException, IOException {
    BuildRuleResolver ruleResolver = new BuildRuleResolver();
    ruleResolver.buildAndAddToIndex(
        PrebuiltJarRule.newPrebuiltJarRuleBuilder(new FakeAbstractBuildRuleBuilderParams())
        .setBuildTarget(BuildTargetFactory.newInstance("//empty:empty"))
        .setBinaryJar("")
        .addVisibilityPattern(BuildTargetPattern.MATCH_ALL));
    ruleResolver.buildAndAddToIndex(
        DefaultJavaLibraryRule.newJavaLibraryRuleBuilder(new FakeAbstractBuildRuleBuilderParams())
        .setBuildTarget(BuildTargetFactory.newInstance("//javasrc:java-library"))
        .addSrc("javasrc/JavaLibrary.java")
        .addVisibilityPattern(BuildTargetPattern.MATCH_ALL)
        .addDep(BuildTargetFactory.newInstance("//empty:empty")));
    ruleResolver.buildAndAddToIndex(
        JavaTestRule.newJavaTestRuleBuilder(new FakeAbstractBuildRuleBuilderParams())
        .setBuildTarget(BuildTargetFactory.newInstance("//javatest:test-java-library"))
        .addSrc("javatest/TestJavaLibrary.java")
        .addDep(BuildTargetFactory.newInstance("//javasrc:java-library")));

    List<String> targets = Lists.newArrayList();
    targets.add("//empty:empty");
    targets.add("//javasrc:java-library");
    targets.add("//javatest:test-java-library");

    PartialGraph graph = createGraphFromBuildRules(ruleResolver, targets);
    ImmutableSet<BuildRuleType> buildRuleTypes = ImmutableSet.of();

    ImmutableSet<String> referencedFiles;
    ImmutableSet<BuildTarget> targetBuildRules = ImmutableSet.of();

    // No target depends on the referenced file.
    referencedFiles = ImmutableSet.of("excludesrc/CannotFind.java");
    SortedMap<String, BuildRule> matchingBuildRules =
        targetsCommand.getMatchingBuildRules(
            graph.getDependencyGraph(),
            new TargetsCommandPredicate(graph, PATH_RELATIVIZER, buildRuleTypes, referencedFiles, targetBuildRules));
    assertTrue(matchingBuildRules.isEmpty());

    // Only test-android-library target depends on the referenced file.
    referencedFiles = ImmutableSet.of("javatest/TestJavaLibrary.java");
    matchingBuildRules =
        targetsCommand.getMatchingBuildRules(
            graph.getDependencyGraph(),
            new TargetsCommandPredicate(graph, PATH_RELATIVIZER, buildRuleTypes, referencedFiles, targetBuildRules));
    assertEquals(
        ImmutableSet.of("//javatest:test-java-library"),
        matchingBuildRules.keySet());

    // The test-android-library target indirectly depend on the referenced file,
    // while test-java-library target directly depend on the referenced file.
    referencedFiles = ImmutableSet.of("javasrc/JavaLibrary.java");
    matchingBuildRules =
        targetsCommand.getMatchingBuildRules(
            graph.getDependencyGraph(),
            new TargetsCommandPredicate(graph, PATH_RELATIVIZER, buildRuleTypes, referencedFiles, targetBuildRules));
    assertEquals(
        ImmutableSet.of("//javatest:test-java-library", "//javasrc:java-library"),
        matchingBuildRules.keySet());

    // Output target only need to depend on one referenced file.
    referencedFiles = ImmutableSet.of(
        "javatest/TestJavaLibrary.java", "othersrc/CannotFind.java");
    matchingBuildRules =
        targetsCommand.getMatchingBuildRules(
            graph.getDependencyGraph(),
            new TargetsCommandPredicate(graph, PATH_RELATIVIZER, buildRuleTypes, referencedFiles, targetBuildRules));
    assertEquals(
        ImmutableSet.of("//javatest:test-java-library"),
        matchingBuildRules.keySet());

    // If no referenced file, means this filter is disabled, we can find all targets.
    referencedFiles = null;
    matchingBuildRules =
        targetsCommand.getMatchingBuildRules(
            graph.getDependencyGraph(),
            new TargetsCommandPredicate(graph,
                PATH_RELATIVIZER,
                buildRuleTypes,
                ImmutableSet.<String>of(),
                targetBuildRules));
    assertEquals(
        ImmutableSet.of(
            "//javatest:test-java-library",
            "//javasrc:java-library",
            "//empty:empty"),
        matchingBuildRules.keySet());

    // Specify java_test, java_library as type filters.
    matchingBuildRules =
        targetsCommand.getMatchingBuildRules(
            graph.getDependencyGraph(),
            new TargetsCommandPredicate(
                graph,
                PATH_RELATIVIZER,
                ImmutableSet.of(BuildRuleType.JAVA_TEST, BuildRuleType.JAVA_LIBRARY),
                ImmutableSet.<String>of(),
                targetBuildRules));
    assertEquals(
        ImmutableSet.of(
            "//javatest:test-java-library",
            "//javasrc:java-library"),
        matchingBuildRules.keySet());


    // Specify java_test, java_library, and a rule name as type filters.
    matchingBuildRules =
        targetsCommand.getMatchingBuildRules(
            graph.getDependencyGraph(),
            new TargetsCommandPredicate(
                graph,
                PATH_RELATIVIZER,
                ImmutableSet.of(BuildRuleType.JAVA_TEST, BuildRuleType.JAVA_LIBRARY),
                ImmutableSet.<String>of(),
                ImmutableSet.of(BuildTargetFactory.newInstance("//javasrc:java-library"))));
    assertEquals(
        ImmutableSet.of("//javasrc:java-library"), matchingBuildRules.keySet());

    // Only filter by BuildTarget
    matchingBuildRules =
        targetsCommand.getMatchingBuildRules(
            graph.getDependencyGraph(),
            new TargetsCommandPredicate(
                graph,
                PATH_RELATIVIZER,
                ImmutableSet.<BuildRuleType>of(),
                ImmutableSet.<String>of(),
                ImmutableSet.of(BuildTargetFactory.newInstance("//javasrc:java-library"))));
    assertEquals(
        ImmutableSet.of("//javasrc:java-library"), matchingBuildRules.keySet());


    // Filter by BuildTarget and Referenced Files
    matchingBuildRules =
        targetsCommand.getMatchingBuildRules(
            graph.getDependencyGraph(),
            new TargetsCommandPredicate(
                graph,
                PATH_RELATIVIZER,
                ImmutableSet.<BuildRuleType>of(),
                ImmutableSet.of("javatest/TestJavaLibrary.java"),
                ImmutableSet.of(BuildTargetFactory.newInstance("//javasrc:java-library"))));
    assertEquals(
        ImmutableSet.<String>of(), matchingBuildRules.keySet());

  }
}
