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

import static com.facebook.buck.testutil.MoreAsserts.assertListEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.fail;

import com.facebook.buck.android.AndroidBinaryRule;
import com.facebook.buck.android.AndroidLibraryRule;
import com.facebook.buck.android.AndroidResourceRule;
import com.facebook.buck.android.NdkLibraryRule;
import com.facebook.buck.command.Project.SourceFolder;
import com.facebook.buck.java.DefaultJavaLibraryRule;
import com.facebook.buck.java.JavaLibraryRule;
import com.facebook.buck.java.JavaTestRule;
import com.facebook.buck.java.KeystoreRule;
import com.facebook.buck.java.PrebuiltJarRule;
import com.facebook.buck.model.BuildTarget;
import com.facebook.buck.model.BuildTargetFactory;
import com.facebook.buck.model.BuildTargetPattern;
import com.facebook.buck.model.SingletonBuildTargetPattern;
import com.facebook.buck.parser.PartialGraph;
import com.facebook.buck.parser.PartialGraphFactory;
import com.facebook.buck.rules.BuildRule;
import com.facebook.buck.rules.BuildRuleResolver;
import com.facebook.buck.rules.DependencyGraph;
import com.facebook.buck.rules.FakeAbstractBuildRuleBuilderParams;
import com.facebook.buck.rules.JavaPackageFinder;
import com.facebook.buck.rules.ProjectConfigRule;
import com.facebook.buck.step.ExecutionContext;
import com.facebook.buck.testutil.RuleMap;
import com.facebook.buck.testutil.BuckTestConstant;
import com.facebook.buck.util.HumanReadableException;
import com.facebook.buck.util.Paths;
import com.facebook.buck.util.ProjectFilesystem;
import com.google.common.base.Function;
import com.google.common.base.Optional;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Iterables;

import org.easymock.EasyMock;
import org.junit.Test;

import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.Properties;

import javax.annotation.Nullable;

public class ProjectTest {

  private static final String PATH_TO_GUAVA_JAR = "third_party/guava/guava-10.0.1.jar";

  @SuppressWarnings("PMD.UnusedPrivateField")
  private PrebuiltJarRule guava;

  /**
   * Creates a PartialGraph with two android_binary rules, each of which depends on the same
   * android_library. The difference between the two is that one lists Guava in its no_dx list and
   * the other does not.
   * <p>
   * The PartialGraph also includes three project_config rules: one for the android_library, and one
   * for each of the android_binary rules.
   */
  public ProjectWithModules createPartialGraphForTesting(
      @Nullable JavaPackageFinder javaPackageFinder) throws IOException {
    BuildRuleResolver ruleResolver = new BuildRuleResolver();

    // java_library //buck-out/android/com/facebook:R
    ruleResolver.buildAndAddToIndex(
        DefaultJavaLibraryRule.newJavaLibraryRuleBuilder(new FakeAbstractBuildRuleBuilderParams())
        .setBuildTarget(BuildTargetFactory.newInstance("//buck-out/android/com/facebook:R"))
        .addSrc("buck-out/android/com/facebook/R.java")
        .addVisibilityPattern(BuildTargetPattern.MATCH_ALL));

    // prebuilt_jar //third_party/guava:guava
    guava = ruleResolver.buildAndAddToIndex(
        PrebuiltJarRule.newPrebuiltJarRuleBuilder(new FakeAbstractBuildRuleBuilderParams())
        .setBuildTarget(BuildTargetFactory.newInstance("//third_party/guava:guava"))
        .setBinaryJar(PATH_TO_GUAVA_JAR)
        .addVisibilityPattern(BuildTargetPattern.MATCH_ALL));

    // android_resouce android_res/base:res
    ruleResolver.buildAndAddToIndex(
        AndroidResourceRule.newAndroidResourceRuleBuilder(new FakeAbstractBuildRuleBuilderParams())
        .setBuildTarget(BuildTargetFactory.newInstance("//android_res/base:res"))
        .setRes("android_res/base/res")
        .setRDotJavaPackage("com.facebook")
        .addVisibilityPattern(BuildTargetPattern.MATCH_ALL));

    // project_config android_res/base:res
    ProjectConfigRule projectConfigRuleForResource = ruleResolver.buildAndAddToIndex(
        ProjectConfigRule.newProjectConfigRuleBuilder(new FakeAbstractBuildRuleBuilderParams())
        .setBuildTarget(BuildTargetFactory.newInstance("//android_res/base:project_config"))
        .setSrcTarget(Optional.of(BuildTargetFactory.newInstance("//android_res/base:res")))
        .setSrcRoots(ImmutableList.of("res")));

    // java_library //java/src/com/facebook/grandchild:grandchild
    BuildTarget grandchild = BuildTargetFactory.newInstance(
        "//java/src/com/facebook/grandchild:grandchild");
    ruleResolver.buildAndAddToIndex(
        DefaultJavaLibraryRule.newJavaLibraryRuleBuilder(new FakeAbstractBuildRuleBuilderParams())
        .setBuildTarget(grandchild)
        .addSrc("Grandchild.java")
        .addVisibilityPattern(BuildTargetPattern.MATCH_ALL));

    // java_library //java/src/com/facebook/child:child
    ruleResolver.buildAndAddToIndex(
        DefaultJavaLibraryRule.newJavaLibraryRuleBuilder(new FakeAbstractBuildRuleBuilderParams())
        .setBuildTarget(BuildTargetFactory.newInstance(
            "//java/src/com/facebook/child:child"))
        .addSrc("Child.java")
        .addDep(grandchild)
        .addVisibilityPattern(BuildTargetPattern.MATCH_ALL));

    // java_library //java/src/com/facebook/exportlib:exportlib
    ruleResolver.buildAndAddToIndex(
        DefaultJavaLibraryRule.newJavaLibraryRuleBuilder(new FakeAbstractBuildRuleBuilderParams())
        .setBuildTarget(BuildTargetFactory.newInstance(
            "//java/src/com/facebook/exportlib:exportlib"))
        .addSrc("ExportLib.java")
        .addDep(BuildTargetFactory.newInstance("//third_party/guava:guava"))
        .setExportDeps(true)
        .addVisibilityPattern(BuildTargetPattern.MATCH_ALL));

    // android_library //java/src/com/facebook/base:base
    ruleResolver.buildAndAddToIndex(
        AndroidLibraryRule.newAndroidLibraryRuleBuilder(new FakeAbstractBuildRuleBuilderParams())
        .setBuildTarget(BuildTargetFactory.newInstance("//java/src/com/facebook/base:base"))
        .addSrc("Base.java")
        .addDep(BuildTargetFactory.newInstance("//buck-out/android/com/facebook:R"))
        .addDep(BuildTargetFactory.newInstance("//java/src/com/facebook/exportlib:exportlib"))
        .addDep(BuildTargetFactory.newInstance("//java/src/com/facebook/child:child"))
        .addDep(BuildTargetFactory.newInstance("//android_res/base:res"))
        .addVisibilityPattern(BuildTargetPattern.MATCH_ALL));

    // project_config //java/src/com/facebook/base:project_config
    ProjectConfigRule projectConfigRuleForLibrary = ruleResolver.buildAndAddToIndex(
        ProjectConfigRule.newProjectConfigRuleBuilder(new FakeAbstractBuildRuleBuilderParams())
        .setBuildTarget(BuildTargetFactory.newInstance(
            "//java/src/com/facebook/base:project_config"))
        .setSrcTarget(Optional.of(BuildTargetFactory.newInstance(
            "//java/src/com/facebook/base:base")))
        .setSrcRoots(ImmutableList.of("src", "src-gen")));

    ProjectConfigRule projectConfigRuleForExportLibrary = ruleResolver.buildAndAddToIndex(
          ProjectConfigRule.newProjectConfigRuleBuilder(new FakeAbstractBuildRuleBuilderParams())
        .setBuildTarget(BuildTargetFactory.newInstance(
            "//java/src/com/facebook/exportlib:project_config"))
        .setSrcTarget(Optional.of(BuildTargetFactory.newInstance(
            "//java/src/com/facebook/exportlib:exportlib")))
        .setSrcRoots(ImmutableList.of("src")));

    // keystore //keystore:debug
    BuildTarget keystoreTarget = BuildTargetFactory.newInstance("//keystore:debug");
    ruleResolver.buildAndAddToIndex(
        KeystoreRule.newKeystoreBuilder(new FakeAbstractBuildRuleBuilderParams())
        .setBuildTarget(keystoreTarget)
        .setStore("keystore/debug.keystore")
        .setProperties("keystore/debug.keystore.properties"));

    // android_binary //foo:app
    ruleResolver.buildAndAddToIndex(
        AndroidBinaryRule.newAndroidBinaryRuleBuilder(new FakeAbstractBuildRuleBuilderParams())
        .setBuildTarget(BuildTargetFactory.newInstance("//foo:app"))
        .addDep(BuildTargetFactory.newInstance("//java/src/com/facebook/base:base"))
        .setManifest("foo/AndroidManifest.xml")
        .setTarget("Google Inc.:Google APIs:16")
        .setKeystore(keystoreTarget)
        .addBuildRuleToExcludeFromDex(BuildTargetFactory.newInstance("//third_party/guava:guava")));

    // project_config //foo:project_config
    ProjectConfigRule projectConfigRuleUsingNoDx = ruleResolver.buildAndAddToIndex(
        ProjectConfigRule.newProjectConfigRuleBuilder(new FakeAbstractBuildRuleBuilderParams())
        .setBuildTarget(BuildTargetFactory.newInstance("//foo:project_config"))
        .setSrcTarget(Optional.of(BuildTargetFactory.newInstance("//foo:app"))));

    // android_binary //bar:app
    ruleResolver.buildAndAddToIndex(
        AndroidBinaryRule.newAndroidBinaryRuleBuilder(new FakeAbstractBuildRuleBuilderParams())
        .setBuildTarget(BuildTargetFactory.newInstance("//bar:app"))
        .addDep(BuildTargetFactory.newInstance("//java/src/com/facebook/base:base"))
            .setManifest("foo/AndroidManifest.xml")
            .setTarget("Google Inc.:Google APIs:16")
            .setKeystore(keystoreTarget));

    // project_config //bar:project_config
    ProjectConfigRule projectConfigRule = ruleResolver.buildAndAddToIndex(
        ProjectConfigRule.newProjectConfigRuleBuilder(new FakeAbstractBuildRuleBuilderParams())
        .setBuildTarget(BuildTargetFactory.newInstance("//bar:project_config"))
        .setSrcTarget(Optional.of(BuildTargetFactory.newInstance("//bar:app"))));

    return getModulesForPartialGraph(ruleResolver,
        ImmutableList.of(
            projectConfigRuleForExportLibrary,
            projectConfigRuleForLibrary,
            projectConfigRuleForResource,
            projectConfigRuleUsingNoDx,
            projectConfigRule),
        javaPackageFinder);
  }

  @Test
  public void testGenerateRelativeGenPath() {
    String basePathOfModuleWithSlash = "android_res/com/facebook/gifts/";
    String expectedRelativePathToGen =
        "/../../../../buck-out/android/android_res/com/facebook/gifts/gen";
    assertEquals(
        expectedRelativePathToGen, Project.generateRelativeGenPath(basePathOfModuleWithSlash));
  }

  /**
   * This is an important test that verifies that the {@code no_dx} argument for an
   * {@code android_binary} is handled appropriately when generating an IntelliJ project.
   */
  @Test
  public void testProject() throws IOException {
    JavaPackageFinder javaPackageFinder = EasyMock.createMock(JavaPackageFinder.class);
    EasyMock.expect(javaPackageFinder.findJavaPackageForPath("foo/module_foo.iml")).andReturn("");
    EasyMock.expect(javaPackageFinder.findJavaPackageForPath("bar/module_bar.iml")).andReturn("");
    EasyMock.replay(javaPackageFinder);

    ProjectWithModules projectWithModules = createPartialGraphForTesting(javaPackageFinder);
    Project project = projectWithModules.project;
    PartialGraph partialGraph = project.getPartialGraph();
    List<Module> modules = projectWithModules.modules;

    assertEquals("Should be one module for the java_library, one for the android_library, " +
                 "one module for the android_resource, and one for each android_binary",
        5,
        modules.size());

    // Check the values of the module that corresponds to the android_library.
    Module javaLibraryModule = modules.get(0);
    assertSame(getRuleById("//java/src/com/facebook/exportlib:exportlib", partialGraph),
        javaLibraryModule.srcRule);
    assertEquals("module_java_src_com_facebook_exportlib", javaLibraryModule.name);
    assertEquals("java/src/com/facebook/exportlib/module_java_src_com_facebook_exportlib.iml",
        javaLibraryModule.pathToImlFile);
    assertListEquals(
        ImmutableList.of(SourceFolder.SRC),
        javaLibraryModule.sourceFolders);

    // Check the dependencies.
    DependentModule inheritedJdk = DependentModule.newInheritedJdk();
    DependentModule guavaAsProvidedDep = DependentModule.newLibrary(
        guava.getBuildTarget(), "third_party_guava_guava_10_0_1_jar");
    guavaAsProvidedDep.scope = "PROVIDED";

    assertListEquals(
        ImmutableList.of(
            DependentModule.newSourceFolder(),
            guavaAsProvidedDep,
            DependentModule.newStandardJdk()),
        javaLibraryModule.dependencies);

    // Check the values of the module that corresponds to the android_library.
    Module androidLibraryModule = modules.get(1);
    assertSame(getRuleById("//java/src/com/facebook/base:base", partialGraph),
        androidLibraryModule.srcRule);
    assertEquals("module_java_src_com_facebook_base", androidLibraryModule.name);
    assertEquals("java/src/com/facebook/base/module_java_src_com_facebook_base.iml",
        androidLibraryModule.pathToImlFile);
    assertListEquals(
        ImmutableList.of(
            SourceFolder.SRC,
            new SourceFolder("file://$MODULE_DIR$/src-gen", false /* isTestSource */),
            SourceFolder.GEN),
        androidLibraryModule.sourceFolders);
    assertEquals(Boolean.TRUE, androidLibraryModule.hasAndroidFacet);
    assertEquals(Boolean.TRUE, androidLibraryModule.isAndroidLibraryProject);
    assertEquals(null, androidLibraryModule.proguardConfigPath);
    assertEquals(null, androidLibraryModule.resFolder);

    // Check the dependencies.
    DependentModule androidResourceAsProvidedDep = DependentModule.newModule(
        BuildTargetFactory.newInstance("//android_res/base:res"),
        "module_android_res_base");

    DependentModule childAsProvidedDep = DependentModule.newModule(
        BuildTargetFactory.newInstance("//java/src/com/facebook/child:child"),
        "module_java_src_com_facebook_child");

    DependentModule exportDepsAsProvidedDep = DependentModule.newModule(
        BuildTargetFactory.newInstance("//java/src/com/facebook/exportlib:exportlib"),
        "module_java_src_com_facebook_exportlib");

    assertListEquals(
        ImmutableList.of(
            DependentModule.newSourceFolder(),
            guavaAsProvidedDep,
            androidResourceAsProvidedDep,
            childAsProvidedDep,
            exportDepsAsProvidedDep,
            inheritedJdk),
        androidLibraryModule.dependencies);

    // Check the values of the module that corresponds to the android_binary that uses no_dx.
    Module androidResourceModule = modules.get(2);
    assertSame(getRuleById("//android_res/base:res", partialGraph), androidResourceModule.srcRule);

    assertEquals("/res", androidResourceModule.resFolder);

    // Check the values of the module that corresponds to the android_binary that uses no_dx.
    Module androidBinaryModuleNoDx = modules.get(3);
    assertSame(getRuleById("//foo:app", partialGraph), androidBinaryModuleNoDx.srcRule);
    assertEquals("module_foo", androidBinaryModuleNoDx.name);
    assertEquals("foo/module_foo.iml", androidBinaryModuleNoDx.pathToImlFile);

    assertListEquals(ImmutableList.of(SourceFolder.GEN), androidBinaryModuleNoDx.sourceFolders);
    assertEquals(Boolean.TRUE, androidBinaryModuleNoDx.hasAndroidFacet);
    assertEquals(Boolean.FALSE, androidBinaryModuleNoDx.isAndroidLibraryProject);
    assertEquals(null, androidBinaryModuleNoDx.proguardConfigPath);
    assertEquals(null, androidBinaryModuleNoDx.resFolder);
    assertEquals("../keystore/debug.keystore", androidBinaryModuleNoDx.keystorePath);

    // Check the dependencies.
    DependentModule grandchildAsProvidedDep = DependentModule.newModule(
        BuildTargetFactory.newInstance("//java/src/com/facebook/grandchild:grandchild"),
        "module_java_src_com_facebook_grandchild"
    );

    DependentModule androidLibraryDep = DependentModule.newModule(
        androidLibraryModule.srcRule.getBuildTarget(), "module_java_src_com_facebook_base");
    assertEquals(
        ImmutableList.of(
            DependentModule.newSourceFolder(),
            guavaAsProvidedDep,
            androidLibraryDep,
            androidResourceAsProvidedDep,
            childAsProvidedDep,
            exportDepsAsProvidedDep,
            grandchildAsProvidedDep,
            inheritedJdk),
        androidBinaryModuleNoDx.dependencies);

    // Check the values of the module that corresponds to the android_binary with an empty no_dx.
    Module androidBinaryModuleEmptyNoDx = modules.get(4);
    assertSame(getRuleById("//bar:app", partialGraph), androidBinaryModuleEmptyNoDx.srcRule);
    assertEquals("module_bar", androidBinaryModuleEmptyNoDx.name);
    assertEquals("bar/module_bar.iml", androidBinaryModuleEmptyNoDx.pathToImlFile);
    assertListEquals(
        ImmutableList.of(SourceFolder.GEN), androidBinaryModuleEmptyNoDx.sourceFolders);
    assertEquals(Boolean.TRUE, androidBinaryModuleEmptyNoDx.hasAndroidFacet);
    assertEquals(Boolean.FALSE, androidBinaryModuleEmptyNoDx.isAndroidLibraryProject);
    assertEquals(null, androidBinaryModuleEmptyNoDx.proguardConfigPath);
    assertEquals(null, androidBinaryModuleEmptyNoDx.resFolder);
    assertEquals("../keystore/debug.keystore", androidBinaryModuleEmptyNoDx.keystorePath);

    // Check the dependencies.
    DependentModule guavaAsCompiledDep = DependentModule.newLibrary(
        guava.getBuildTarget(), "third_party_guava_guava_10_0_1_jar");
    assertEquals("Important that Guava is listed as a 'COMPILED' dependency here because it is "
        + "only listed as a 'PROVIDED' dependency earlier.",
        ImmutableList.of(
            DependentModule.newSourceFolder(),
            guavaAsCompiledDep,
            androidLibraryDep,
            androidResourceAsProvidedDep,
            childAsProvidedDep,
            exportDepsAsProvidedDep,
            grandchildAsProvidedDep,
            inheritedJdk),
        androidBinaryModuleEmptyNoDx.dependencies);

    // Check that the correct data was extracted to populate the .idea/libraries directory.
    BuildRule guava = getRuleById("//third_party/guava:guava", partialGraph);
    assertSame(guava, Iterables.getOnlyElement(project.getLibraryJars()));
  }

  @Test
  public void testPrebuiltJarIncludesDeps() throws IOException {
    BuildRuleResolver ruleResolver = new BuildRuleResolver();

    // Build up a the graph that corresponds to:
    //
    // android_library(
    //   name = 'example',
    //   deps = [
    //     ':easymock',
    //   ],
    // )
    //
    // prebuilt_jar(
    //   name = 'easymock',
    //   binary_jar = 'easymock.jar',
    //   deps = [
    //     ':cglib',
    //     ':objenesis',
    //   ],
    // )
    //
    // prebuilt_jar(
    //   name = 'cglib',
    //   binary_jar = 'cglib.jar',
    // )
    //
    // prebuilt_jar(
    //   name = 'objenesis',
    //   binary_jar = 'objenesis.jar',
    // )
    //
    // project_config(
    //   src_target = ':example',
    // )
    PrebuiltJarRule cglib = ruleResolver.buildAndAddToIndex(
        PrebuiltJarRule.newPrebuiltJarRuleBuilder(new FakeAbstractBuildRuleBuilderParams())
            .setBuildTarget(BuildTargetFactory.newInstance("//third_party/java/easymock:cglib"))
            .setBinaryJar("third_party/java/easymock/cglib.jar"));

    PrebuiltJarRule objenesis = ruleResolver.buildAndAddToIndex(
        PrebuiltJarRule.newPrebuiltJarRuleBuilder(new FakeAbstractBuildRuleBuilderParams())
        .setBuildTarget(BuildTargetFactory.newInstance("//third_party/java/easymock:objenesis"))
        .setBinaryJar("third_party/java/easymock/objenesis.jar"));

    PrebuiltJarRule easymock = ruleResolver.buildAndAddToIndex(
        PrebuiltJarRule.newPrebuiltJarRuleBuilder(new FakeAbstractBuildRuleBuilderParams())
            .setBuildTarget(BuildTargetFactory.newInstance("//third_party/java/easymock:easymock"))
            .setBinaryJar("third_party/java/easymock/easymock.jar")
            .addDep(BuildTargetFactory.newInstance("//third_party/java/easymock:cglib"))
            .addDep(BuildTargetFactory.newInstance("//third_party/java/easymock:objenesis")));

    BuildTarget easyMockExampleTarget = BuildTargetFactory.newInstance(
        "//third_party/java/easymock:example");
    ruleResolver.buildAndAddToIndex(
        AndroidLibraryRule.newAndroidLibraryRuleBuilder(new FakeAbstractBuildRuleBuilderParams())
        .setBuildTarget(easyMockExampleTarget)
        .addDep(BuildTargetFactory.newInstance("//third_party/java/easymock:easymock")));

    ProjectConfigRule projectConfig = ruleResolver.buildAndAddToIndex(
        ProjectConfigRule.newProjectConfigRuleBuilder(new FakeAbstractBuildRuleBuilderParams())
        .setBuildTarget(
            BuildTargetFactory.newInstance("//third_party/java/easymock:project_config"))
        .setSrcTarget(Optional.of(easyMockExampleTarget)));

    ProjectWithModules projectWithModules = getModulesForPartialGraph(ruleResolver,
        ImmutableList.of(projectConfig),
        null /* javaPackageFinder */);
    List<Module> modules = projectWithModules.modules;

    // Verify that the single Module that is created transitively includes all JAR files.
    assertEquals("Should be one module for the android_library", 1, modules.size());
    Module androidLibraryModule = Iterables.getOnlyElement(modules);
    assertListEquals(ImmutableList.of(
            DependentModule.newSourceFolder(),
            DependentModule.newLibrary(
                easymock.getBuildTarget(),
                "third_party_java_easymock_easymock_jar"),
            DependentModule.newLibrary(
                cglib.getBuildTarget(),
                "third_party_java_easymock_cglib_jar"),
            DependentModule.newLibrary(
                objenesis.getBuildTarget(),
                "third_party_java_easymock_objenesis_jar"),
            DependentModule.newInheritedJdk()),
        androidLibraryModule.dependencies);
  }

  @Test
  public void testIfModuleIsBothTestAndCompileDepThenTreatAsCompileDep() throws IOException {
    BuildRuleResolver ruleResolver = new BuildRuleResolver();

    // Create a java_library() and a java_test() that both depend on Guava.
    // When they are part of the same project_config() rule, then the resulting module should
    // include Guava as scope="COMPILE" in IntelliJ.
    PrebuiltJarRule guava = ruleResolver.buildAndAddToIndex(
        PrebuiltJarRule.newPrebuiltJarRuleBuilder(new FakeAbstractBuildRuleBuilderParams())
            .setBuildTarget(BuildTargetFactory.newInstance("//third_party/java/guava:guava"))
            .setBinaryJar("third_party/java/guava.jar")
            .addVisibilityPattern(BuildTargetPattern.MATCH_ALL));

    ruleResolver.buildAndAddToIndex(
        DefaultJavaLibraryRule.newJavaLibraryRuleBuilder(new FakeAbstractBuildRuleBuilderParams())
        .setBuildTarget(BuildTargetFactory.newInstance("//java/com/example/base:base"))
        .addDep(BuildTargetFactory.newInstance("//third_party/java/guava:guava")));

    ruleResolver.buildAndAddToIndex(
        JavaTestRule.newJavaTestRuleBuilder(new FakeAbstractBuildRuleBuilderParams())
        .setBuildTarget(BuildTargetFactory.newInstance("//java/com/example/base:tests"))
        .addDep(BuildTargetFactory.newInstance("//third_party/java/guava:guava")));

    ProjectConfigRule projectConfig = ruleResolver.buildAndAddToIndex(
        ProjectConfigRule.newProjectConfigRuleBuilder(new FakeAbstractBuildRuleBuilderParams())
        .setBuildTarget(BuildTargetFactory.newInstance("//java/com/example/base:project_config"))
        .setSrcTarget(Optional.of(BuildTargetFactory.newInstance("//java/com/example/base:base")))
        .setTestTarget(Optional.of(BuildTargetFactory.newInstance("//java/com/example/base:tests")))
        .setTestRoots(ImmutableList.of("tests")));

    ProjectWithModules projectWithModules = getModulesForPartialGraph(ruleResolver,
        ImmutableList.of(projectConfig),
        null /* javaPackageFinder */);
    List<Module> modules = projectWithModules.modules;
    assertEquals(1, modules.size());
    Module comExampleBaseModule = Iterables.getOnlyElement(modules);

    assertListEquals(ImmutableList.of(
            DependentModule.newSourceFolder(),
            DependentModule.newLibrary(guava.getBuildTarget(), "third_party_java_guava_jar"),
            DependentModule.newStandardJdk()),
        comExampleBaseModule.dependencies);
  }

  /**
   * In the context of Robolectric, httpcore-4.0.1.jar needs to be loaded before the android.jar
   * associated with the Android SDK. Both httpcore-4.0.1.jar and android.jar define
   * org.apache.http.params.BasicHttpParams; however, only httpcore-4.0.1.jar contains a real
   * implementation of BasicHttpParams whereas android.jar contains a stub implementation of
   * BasicHttpParams.
   * <p>
   * One way to fix this problem would be to "tag" httpcore-4.0.1.jar to indicate that it must
   * appear before the Android SDK (or anything that transitively depends on the Android SDK) when
   * listing dependencies for IntelliJ. This would be a giant kludge to the prebuilt_jar rule, so
   * instead we just list jars before modules within an &lt;orderEntry scope="TEST"/> or an
   * &lt;orderEntry scope="COMPILE"/> group.
   */
  @Test
  public void testThatJarsAreListedBeforeModules() throws IOException {
    BuildRuleResolver ruleResolver = new BuildRuleResolver();

    JavaLibraryRule supportV4 = ruleResolver.buildAndAddToIndex(
        DefaultJavaLibraryRule.newJavaLibraryRuleBuilder(new FakeAbstractBuildRuleBuilderParams())
        .setBuildTarget(BuildTargetFactory.newInstance("//java/com/android/support/v4:v4"))
        .addVisibilityPattern(BuildTargetPattern.MATCH_ALL));

    PrebuiltJarRule httpCore = ruleResolver.buildAndAddToIndex(
        PrebuiltJarRule.newPrebuiltJarRuleBuilder(new FakeAbstractBuildRuleBuilderParams())
        .setBuildTarget(BuildTargetFactory.newInstance("//third_party/java/httpcore:httpcore"))
        .setBinaryJar("httpcore-4.0.1.jar")
        .addVisibilityPattern(BuildTargetPattern.MATCH_ALL));

    // The support-v4 library is loaded as a java_library() rather than a prebuilt_jar() because it
    // contains our local changes to the library.
    BuildTarget robolectricTarget =
        BuildTargetFactory.newInstance("//third_party/java/robolectric:robolectric");
    ruleResolver.buildAndAddToIndex(
        DefaultJavaLibraryRule.newJavaLibraryRuleBuilder(new FakeAbstractBuildRuleBuilderParams())
        .setBuildTarget(robolectricTarget)
        .addDep(BuildTargetFactory.newInstance("//java/com/android/support/v4:v4"))
        .addDep(BuildTargetFactory.newInstance("//third_party/java/httpcore:httpcore")));

    ProjectConfigRule projectConfig = ruleResolver.buildAndAddToIndex(
        ProjectConfigRule.newProjectConfigRuleBuilder(new FakeAbstractBuildRuleBuilderParams())
        .setBuildTarget(BuildTargetFactory.newInstance(
            "//third_party/java/robolectric:project_config"))
        .setSrcTarget(Optional.of(robolectricTarget))
        .setSrcRoots(ImmutableList.of("src/main/java")));

    ProjectWithModules projectWithModules = getModulesForPartialGraph(ruleResolver,
        ImmutableList.of(projectConfig),
        null /* javaPackageFinder */);
    List<Module> modules = projectWithModules.modules;
    assertEquals("Should be one module for the android_library", 1, modules.size());
    Module robolectricModule = Iterables.getOnlyElement(modules);

    assertListEquals(
        "It is imperative that httpcore-4.0.1.jar be listed before the support v4 library, " +
        "or else when robolectric is listed as a dependency, " +
        "org.apache.http.params.BasicHttpParams will be loaded from android.jar instead of " +
        "httpcore-4.0.1.jar.",
        ImmutableList.of(
            DependentModule.newSourceFolder(),
            DependentModule.newLibrary(httpCore.getBuildTarget(), "httpcore_4_0_1_jar"),
            DependentModule.newModule(
                supportV4.getBuildTarget(), "module_java_com_android_support_v4"),
            DependentModule.newStandardJdk()),
        robolectricModule.dependencies);
  }

  @Test
  public void testCreatePathToProjectDotPropertiesFileForModule() {
    Module rootModule = new Module(null /* buildRule */,
        BuildTargetFactory.newInstance("//:project_config"));
    rootModule.pathToImlFile = "fb4a.iml";
    assertEquals("project.properties", Project.createPathToProjectDotPropertiesFileFor(rootModule));

    Module someModule = new Module(null /* buildRule */,
        BuildTargetFactory.newInstance("//java/com/example/base:project_config"));
    someModule.pathToImlFile = "java/com/example/base/base.iml";
    assertEquals("java/com/example/base/project.properties",
        Project.createPathToProjectDotPropertiesFileFor(someModule));
  }

  /**
   * A project_config()'s src_roots argument can be {@code None}, {@code []}, or a non-empty array.
   * Each of these should be treated differently.
   */
  @Test
  public void testSrcRoots() throws IOException {
    // Create a project_config() with src_roots=None.
    BuildRuleResolver ruleResolver1 = new BuildRuleResolver();
    ruleResolver1.buildAndAddToIndex(
        AndroidResourceRule.newAndroidResourceRuleBuilder(new FakeAbstractBuildRuleBuilderParams())
        .setBuildTarget(BuildTargetFactory.newInstance("//resources/com/example:res")));
    ProjectConfigRule projectConfigNullSrcRoots = ruleResolver1.buildAndAddToIndex(
        ProjectConfigRule.newProjectConfigRuleBuilder(new FakeAbstractBuildRuleBuilderParams())
        .setBuildTarget(BuildTargetFactory.newInstance("//resources/com/example:project_config"))
        .setSrcTarget(Optional.of(BuildTargetFactory.newInstance("//resources/com/example:res")))
        .setSrcRoots(null));
    ProjectWithModules projectWithModules1 = getModulesForPartialGraph(ruleResolver1,
        ImmutableList.of(projectConfigNullSrcRoots),
        null /* javaPackageFinder */);

    // Verify that the correct source folders are created.
    assertEquals(1, projectWithModules1.modules.size());
    Module moduleNoJavaSource = projectWithModules1.modules.get(0);
    assertListEquals(
        "Only source folder should be gen/ when setSrcRoots(null) is specified.",
        ImmutableList.of(SourceFolder.GEN),
        moduleNoJavaSource.sourceFolders);

    // Create a project_config() with src_roots=[].
    BuildRuleResolver ruleResolver2 = new BuildRuleResolver();
    ruleResolver2.buildAndAddToIndex(
        AndroidLibraryRule.newAndroidLibraryRuleBuilder(new FakeAbstractBuildRuleBuilderParams())
        .setBuildTarget(BuildTargetFactory.newInstance("//java/com/example/base:base")));
    ProjectConfigRule inPackageProjectConfig = ruleResolver2.buildAndAddToIndex(
        ProjectConfigRule.newProjectConfigRuleBuilder(new FakeAbstractBuildRuleBuilderParams())
        .setBuildTarget(BuildTargetFactory.newInstance("//java/com/example/base:project_config"))
        .setSrcTarget(Optional.of(BuildTargetFactory.newInstance("//java/com/example/base:base")))
        .setSrcRoots(ImmutableList.<String>of()));

    // Verify that the correct source folders are created.
    JavaPackageFinder javaPackageFinder = EasyMock.createMock(JavaPackageFinder.class);
    EasyMock.expect(javaPackageFinder.findJavaPackageForPath(
        "java/com/example/base/module_java_com_example_base.iml")).andReturn("com.example.base");
    EasyMock.replay(javaPackageFinder);
    ProjectWithModules projectWithModules2 = getModulesForPartialGraph(ruleResolver2,
        ImmutableList.of(inPackageProjectConfig),
        javaPackageFinder);
    EasyMock.verify(javaPackageFinder);
    assertEquals(1, projectWithModules2.modules.size());
    Module moduleWithPackagePrefix = projectWithModules2.modules.get(0);
    assertListEquals(
        "The current directory should be a source folder with a package prefix " +
            "as well as the gen/ directory.",
        ImmutableList.of(
            new SourceFolder("file://$MODULE_DIR$", false /* isTestSource */, "com.example.base"),
            SourceFolder.GEN),
        moduleWithPackagePrefix.sourceFolders);

    // Create a project_config() with src_roots=['src'].
    BuildRuleResolver ruleResolver3 = new BuildRuleResolver();
    ruleResolver3.buildAndAddToIndex(
        AndroidLibraryRule.newAndroidLibraryRuleBuilder(new FakeAbstractBuildRuleBuilderParams())
        .setBuildTarget(BuildTargetFactory.newInstance("//java/com/example/base:base")));
    ProjectConfigRule hasSrcFolderProjectConfig = ruleResolver3.buildAndAddToIndex(
        ProjectConfigRule.newProjectConfigRuleBuilder(new FakeAbstractBuildRuleBuilderParams())
        .setBuildTarget(BuildTargetFactory.newInstance("//java/com/example/base:project_config"))
        .setSrcTarget(Optional.of(BuildTargetFactory.newInstance("//java/com/example/base:base")))
        .setSrcRoots(ImmutableList.of("src")));
    ProjectWithModules projectWithModules3 = getModulesForPartialGraph(ruleResolver3,
        ImmutableList.of(hasSrcFolderProjectConfig),
        null /* javaPackageFinder */);

    // Verify that the correct source folders are created.
    assertEquals(1, projectWithModules3.modules.size());
    Module moduleHasSrcFolder = projectWithModules3.modules.get(0);
    assertListEquals(
        "Both src/ and gen/ should be source folders.",
        ImmutableList.of(
            new SourceFolder("file://$MODULE_DIR$/src", false /* isTestSource */),
            SourceFolder.GEN),
        moduleHasSrcFolder.sourceFolders);
  }

  private static class ProjectWithModules {
    private final Project project;
    private final ImmutableList<Module> modules;
    private ProjectWithModules(Project project, ImmutableList<Module> modules) {
      this.project = project;
      this.modules = modules;
    }
  }

  private ProjectWithModules getModulesForPartialGraph(
      BuildRuleResolver ruleResolver,
      ImmutableList<ProjectConfigRule> projectConfigs,
      @Nullable JavaPackageFinder javaPackageFinder) throws IOException {
    if (javaPackageFinder == null) {
      javaPackageFinder = EasyMock.createMock(JavaPackageFinder.class);
    }

    DependencyGraph graph = RuleMap.createGraphFromBuildRules(ruleResolver);
    List<BuildTarget> targets = ImmutableList.copyOf(Iterables.transform(projectConfigs,
        new Function<ProjectConfigRule, BuildTarget>() {

      @Override
      public BuildTarget apply(ProjectConfigRule rule) {
        return rule.getBuildTarget();
      }
    }));
    PartialGraph partialGraph = PartialGraphFactory.newInstance(graph, targets);

    // Create the Project.
    ExecutionContext executionContext = EasyMock.createMock(ExecutionContext.class);
    ProjectFilesystem projectFilesystem = EasyMock.createMock(ProjectFilesystem.class);

    Properties keystoreProperties = new Properties();
    keystoreProperties.put("key.alias", "androiddebugkey");
    keystoreProperties.put("key.store.password", "android");
    keystoreProperties.put("key.alias.password", "android");
    EasyMock.expect(projectFilesystem.readPropertiesFile(
        "keystore/debug.keystore.properties"))
        .andReturn(keystoreProperties).anyTimes();

    ImmutableMap<String, String> basePathToAliasMap = ImmutableMap.of();
    Project project = new Project(
        partialGraph,
        basePathToAliasMap,
        javaPackageFinder,
        executionContext,
        projectFilesystem,
        /* pathToDefaultAndroidManifest */ Optional.<String>absent(),
        /* pathToPostProcessScript */ Optional.<String>absent(),
        BuckTestConstant.PYTHON_INTERPRETER);

    // Execute Project's business logic.
    EasyMock.replay(executionContext, projectFilesystem);
    List<Module> modules = project.createModulesForProjectConfigs();
    EasyMock.verify(executionContext, projectFilesystem);

    return new ProjectWithModules(project, ImmutableList.copyOf(modules));
  }

  private static BuildRule getRuleById(String id, PartialGraph graph) {
    String[] parts = id.split(":");
    BuildRule rule = graph.getDependencyGraph().findBuildRuleByTarget(
        BuildTargetFactory.newInstance(parts[0], parts[1]));
    Preconditions.checkNotNull(rule, "No rule for %s", id);
    return rule;
  }

  @Test
  public void testNdkLibraryHasCorrectPath() throws IOException {
    BuildRuleResolver ruleResolver = new BuildRuleResolver();

    // Build up a the graph that corresponds to:
    //
    // ndk_library(
    //   name = 'foo-jni'
    // )
    //
    // project_config(
    //   src_target = ':foo-jni',
    // )

    BuildTarget fooJni = BuildTargetFactory.newInstance("//third_party/java/foo/jni:foo-jni");
    NdkLibraryRule ndkLibrary = ruleResolver.buildAndAddToIndex(
        NdkLibraryRule.newNdkLibraryRuleBuilder(new FakeAbstractBuildRuleBuilderParams())
        .setBuildTarget(fooJni)
        .addSrc("Android.mk")
        .addVisibilityPattern(new SingletonBuildTargetPattern("//third_party/java/foo:foo")));

    ProjectConfigRule ndkProjectConfig = ruleResolver.buildAndAddToIndex(
        ProjectConfigRule.newProjectConfigRuleBuilder(new FakeAbstractBuildRuleBuilderParams())
        .setBuildTarget(BuildTargetFactory.newInstance("//third_party/java/foo/jni:project_config"))
        .setSrcTarget(Optional.of(fooJni)));

    ProjectWithModules projectWithModules = getModulesForPartialGraph(ruleResolver,
        ImmutableList.of(ndkProjectConfig),
        null /* javaPackageFinder */);
    List<Module> modules = projectWithModules.modules;

    assertEquals("Should be one module for the ndk_library.", 1, modules.size());
    Module androidLibraryModule = Iterables.getOnlyElement(modules);
    assertListEquals(ImmutableList.of(
            DependentModule.newSourceFolder(),
            DependentModule.newInheritedJdk()),
        androidLibraryModule.dependencies);
    assertEquals(
        String.format("../../../../%s", ndkLibrary.getLibraryPath()),
        androidLibraryModule.nativeLibs);
  }

  @Test
  public void shouldThrowAnExceptionIfAModuleIsMissingADependencyWhenGeneratingProjectFiles()
      throws IOException {
    BuildRuleResolver ruleResolver = new BuildRuleResolver();

    DefaultJavaLibraryRule ex1 = ruleResolver.buildAndAddToIndex(
        DefaultJavaLibraryRule.newJavaLibraryRuleBuilder(new FakeAbstractBuildRuleBuilderParams())
        .setBuildTarget(BuildTargetFactory.newInstance("//example/parent:ex1"))
        .addSrc("DoesNotExist.java")
        .addVisibilityPattern(BuildTargetPattern.MATCH_ALL));

    DefaultJavaLibraryRule ex2 = ruleResolver.buildAndAddToIndex(
        DefaultJavaLibraryRule.newJavaLibraryRuleBuilder(new FakeAbstractBuildRuleBuilderParams())
        .setBuildTarget(BuildTargetFactory.newInstance("//example/child:ex2"))
        .addSrc("AlsoDoesNotExist.java")
        .addDep(ex1.getBuildTarget())
        .addVisibilityPattern(BuildTargetPattern.MATCH_ALL));

    DefaultJavaLibraryRule tests = ruleResolver.buildAndAddToIndex(
        JavaTestRule.newJavaTestRuleBuilder(new FakeAbstractBuildRuleBuilderParams())
        .setBuildTarget(BuildTargetFactory.newInstance("//example/child:tests"))
        .addSrc("SomeTestFile.java")
        .addDep(ex2.getBuildTarget())
        .addVisibilityPattern(BuildTargetPattern.MATCH_ALL));

    ProjectConfigRule config = ruleResolver.buildAndAddToIndex(
        ProjectConfigRule.newProjectConfigRuleBuilder(new FakeAbstractBuildRuleBuilderParams())
        .setBuildTarget(BuildTargetFactory.newInstance("//example/child:config"))
        .setSrcTarget(Optional.of(ex2.getBuildTarget()))
        .setTestTarget(Optional.of(tests.getBuildTarget())));

    ProjectWithModules projectWithModules = getModulesForPartialGraph(
        ruleResolver, ImmutableList.of(config), null);

    Module module = Iterables.getOnlyElement(projectWithModules.modules);
    List<Module> modules = projectWithModules.project.createModulesForProjectConfigs();
    Map<String, Module> map = projectWithModules.project.buildNameToModuleMap(modules);

    try {
      projectWithModules.project.writeProjectDotPropertiesFile(module, map);
      fail("Should have thrown a HumanReadableException");
    } catch (HumanReadableException e) {
      assertEquals("You must define a project_config() in example/child/BUCK containing " +
          "//example/parent:ex1. The project_config() in //example/child:config transitively " +
          "depends on it.",
          Paths.normalizePathSeparator(e.getHumanReadableErrorMessage()));
    }
  }
}
