// Copyright 2017 The Bazel Authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package com.google.devtools.build.lib.rules.android;

import static com.google.common.truth.Truth.assertThat;
import static com.google.devtools.build.lib.actions.util.ActionsTestUtil.getFirstArtifactEndingWith;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables;
import com.google.devtools.build.lib.actions.Artifact;
import com.google.devtools.build.lib.actions.CommandLineExpansionException;
import com.google.devtools.build.lib.actions.extra.JavaCompileInfo;
import com.google.devtools.build.lib.actions.util.ActionsTestUtil;
import com.google.devtools.build.lib.analysis.ConfiguredTarget;
import com.google.devtools.build.lib.analysis.actions.ParameterFileWriteAction;
import com.google.devtools.build.lib.cmdline.RepositoryName;
import com.google.devtools.build.lib.rules.java.JavaCompileAction;
import java.util.List;
import java.util.Set;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

/**
 * Tests for Bazel's Android data binding support.
 */
@RunWith(JUnit4.class)
public class AndroidDataBindingTest extends AndroidBuildViewTestCase {
  private void writeDataBindingFiles() throws Exception {
    scratch.file("java/android/library/BUILD",
        "android_library(",
        "    name = 'lib_with_data_binding',",
        "    enable_data_binding = 1,",
        "    manifest = 'AndroidManifest.xml',",
        "    srcs = ['MyLib.java'],",
        "    resource_files = [],",
        ")");
    scratch.file("java/android/library/MyLib.java",
        "package android.library; public class MyLib {};");
    scratch.file("java/android/binary/BUILD",
        "android_binary(",
        "    name = 'app',",
        "    enable_data_binding = 1,",
        "    manifest = 'AndroidManifest.xml',",
        "    srcs = ['MyApp.java'],",
        "    deps = ['//java/android/library:lib_with_data_binding'],",
        ")");
    scratch.file("java/android/binary/MyApp.java",
        "package android.binary; public class MyApp {};");
  }

  private void writeDataBindingFilesWithNoResourcesDep() throws Exception {
    scratch.file("java/android/lib_with_resource_files/BUILD",
        "android_library(",
        "    name = 'lib_with_resource_files',",
        "    enable_data_binding = 1,",
        "    manifest = 'AndroidManifest.xml',",
        "    srcs = ['LibWithResourceFiles.java'],",
        "    resource_files = glob(['res/**']),",
        ")");
    scratch.file("java/android/lib_with_resource_files/LibWithResourceFiles.java",
        "package android.lib_with_resource_files; public class LibWithResourceFiles {};");

    scratch.file("java/android/lib_no_resource_files/BUILD",
        "android_library(",
        "    name = 'lib_no_resource_files',",
        "    enable_data_binding = 1,",
        "    srcs = ['LibNoResourceFiles.java'],",
        "    deps = ['//java/android/lib_with_resource_files'],",
        ")");
    scratch.file("java/android/lib_no_resource_files/LibNoResourceFiles.java",
        "package android.lib_no_resource_files; public class LibNoResourceFiles {};");

    scratch.file("java/android/binary/BUILD",
        "android_binary(",
        "    name = 'app',",
        "    enable_data_binding = 1,",
        "    manifest = 'AndroidManifest.xml',",
        "    srcs = ['MyApp.java'],",
        "    deps = ['//java/android/lib_no_resource_files'],",
        ")");
    scratch.file("java/android/binary/MyApp.java",
        "package android.binary; public class MyApp {};");
  }

  /** Returns the .params file contents of a {@link JavaCompileAction} */
  private Iterable<String> getParamFileContents(JavaCompileAction action)
      throws CommandLineExpansionException {
    Artifact paramFile = getFirstArtifactEndingWith(action.getInputs(), "-2.params");
    return ((ParameterFileWriteAction) getGeneratingAction(paramFile)).getContents();
  }

  @Test
  public void basicDataBindingIntegration() throws Exception {
    writeDataBindingFiles();
    ConfiguredTarget ctapp = getConfiguredTarget("//java/android/binary:app");
    Set<Artifact> allArtifacts = actionsTestUtil().artifactClosureOf(getFilesToBuild(ctapp));

    // "Data binding"-enabled targets invoke resource processing with a request for data binding
    // output:
    Artifact libResourceInfoOutput = getFirstArtifactEndingWith(allArtifacts,
        "databinding/lib_with_data_binding/layout-info.zip");
    assertThat(getGeneratingSpawnActionArgs(libResourceInfoOutput))
        .containsAllOf("--dataBindingInfoOut", libResourceInfoOutput.getExecPathString())
        .inOrder();

    Artifact binResourceInfoOutput = getFirstArtifactEndingWith(allArtifacts,
        "databinding/app/layout-info.zip");
    assertThat(getGeneratingSpawnActionArgs(binResourceInfoOutput))
        .containsAllOf("--dataBindingInfoOut", binResourceInfoOutput.getExecPathString())
        .inOrder();

    // Java compilation includes the data binding annotation processor, the resource processor's
    // output, and the auto-generated DataBindingInfo.java the annotation processor uses to figure
    // out what to do:
    JavaCompileAction libCompileAction = (JavaCompileAction) getGeneratingAction(
        getFirstArtifactEndingWith(allArtifacts, "lib_with_data_binding.jar"));
    assertThat(libCompileAction.getProcessorNames())
        .contains("android.databinding.annotationprocessor.ProcessDataBinding");
    assertThat(ActionsTestUtil.prettyArtifactNames(libCompileAction.getInputs()))
        .containsAllOf(
            "java/android/library/databinding/lib_with_data_binding/layout-info.zip",
            "java/android/library/databinding/lib_with_data_binding/DataBindingInfo.java");

    JavaCompileAction binCompileAction = (JavaCompileAction) getGeneratingAction(
        getFirstArtifactEndingWith(allArtifacts, "app.jar"));
    assertThat(binCompileAction.getProcessorNames())
        .contains("android.databinding.annotationprocessor.ProcessDataBinding");
    assertThat(ActionsTestUtil.prettyArtifactNames(binCompileAction.getInputs()))
        .containsAllOf(
            "java/android/binary/databinding/app/layout-info.zip",
            "java/android/binary/databinding/app/DataBindingInfo.java");
  }

  @Test
  public void dataBindingCompilationUsesMetadataFromDeps() throws Exception {
    writeDataBindingFiles();
    ConfiguredTarget ctapp = getConfiguredTarget("//java/android/binary:app");
    Set<Artifact> allArtifacts = actionsTestUtil().artifactClosureOf(getFilesToBuild(ctapp));

    // The library's compilation doesn't include any of the -setter_store.bin, layoutinfo.bin, etc.
    // files that store a dependency's data binding results (since the library has no deps).
    // We check that they don't appear as compilation inputs.
    JavaCompileAction libCompileAction = (JavaCompileAction)
        getGeneratingAction(getFirstArtifactEndingWith(allArtifacts, "lib_with_data_binding.jar"));
    assertThat(
        Iterables.filter(libCompileAction.getInputs(),
            ActionsTestUtil.getArtifactSuffixMatcher(".bin")))
        .isEmpty();

    // The binary's compilation includes the library's data binding results.
    JavaCompileAction binCompileAction = (JavaCompileAction) getGeneratingAction(
        getFirstArtifactEndingWith(allArtifacts, "app.jar"));
    Iterable<Artifact> depMetadataInputs = Iterables.filter(
        binCompileAction.getInputs(), ActionsTestUtil.getArtifactSuffixMatcher(".bin"));
    final String depMetadataBaseDir = Iterables.getFirst(depMetadataInputs, null).getExecPath()
        .getParentDirectory().toString();
        ActionsTestUtil.execPaths(Iterables.filter(
        binCompileAction.getInputs(), ActionsTestUtil.getArtifactSuffixMatcher(".bin")));
    assertThat(ActionsTestUtil.execPaths(depMetadataInputs)).containsExactly(
        depMetadataBaseDir + "/android.library-android.library-setter_store.bin",
        depMetadataBaseDir + "/android.library-android.library-layoutinfo.bin",
        depMetadataBaseDir + "/android.library-android.library-br.bin");
  }

  @Test
  public void dataBindingAnnotationProcessorFlags() throws Exception {
    writeDataBindingFiles();
    ConfiguredTarget ctapp = getConfiguredTarget("//java/android/binary:app");
    Set<Artifact> allArtifacts = actionsTestUtil().artifactClosureOf(getFilesToBuild(ctapp));
    JavaCompileAction binCompileAction = (JavaCompileAction) getGeneratingAction(
        getFirstArtifactEndingWith(allArtifacts, "app.jar"));
    String dataBindingFilesDir = targetConfig.getBinDirectory(RepositoryName.MAIN).getExecPath()
        .getRelative("java/android/binary/databinding/app").getPathString();
    ImmutableList<String> expectedJavacopts =
        ImmutableList.of(
            "-Aandroid.databinding.bindingBuildFolder=" + dataBindingFilesDir,
            "-Aandroid.databinding.generationalFileOutDir=" + dataBindingFilesDir,
            "-Aandroid.databinding.sdkDir=/not/used",
            "-Aandroid.databinding.artifactType=APPLICATION",
            "-Aandroid.databinding.xmlOutDir=" + dataBindingFilesDir,
            "-Aandroid.databinding.exportClassListTo=/tmp/exported_classes",
            "-Aandroid.databinding.modulePackage=android.binary",
            "-Aandroid.databinding.minApi=14",
            "-Aandroid.databinding.printEncodedErrors=0");
    assertThat(getParamFileContents(binCompileAction)).containsAllIn(expectedJavacopts);

    // Regression test for b/63134122
    JavaCompileInfo javaCompileInfo =
        binCompileAction
            .getExtraActionInfo(actionKeyContext)
            .getExtension(JavaCompileInfo.javaCompileInfo);
    assertThat(javaCompileInfo.getJavacOptList()).containsAllIn(expectedJavacopts);
  }

  @Test
  public void dataBindingIncludesTransitiveDepsForLibsWithNoResources() throws Exception {
    writeDataBindingFilesWithNoResourcesDep();
    ConfiguredTarget ct = getConfiguredTarget("//java/android/binary:app");
    Set<Artifact> allArtifacts = actionsTestUtil().artifactClosureOf(getFilesToBuild(ct));

    // Data binding resource processing outputs are expected for the app and libs with resources.
    assertThat(getFirstArtifactEndingWith(allArtifacts,
        "databinding/lib_with_resource_files/layout-info.zip")).isNotNull();
    assertThat(getFirstArtifactEndingWith(allArtifacts, "databinding/app/layout-info.zip"))
        .isNotNull();

    // Compiling the app's Java source includes data binding metadata from the resource-equipped
    // lib, but not the resource-empty one.
    JavaCompileAction binCompileAction = (JavaCompileAction) getGeneratingAction(
        getFirstArtifactEndingWith(allArtifacts, "app.jar"));
    List<String> appJarInputs = ActionsTestUtil.prettyArtifactNames(binCompileAction.getInputs());
    String libWithResourcesMetadataBaseDir = "java/android/binary/databinding/app/"
        + "dependent-lib-artifacts/java/android/lib_with_resource_files/databinding/"
        + "lib_with_resource_files/bin-files/android.lib_with_resource_files-";
    assertThat(appJarInputs).containsAllOf(
        "java/android/binary/databinding/app/layout-info.zip",
        libWithResourcesMetadataBaseDir + "android.lib_with_resource_files-setter_store.bin",
        libWithResourcesMetadataBaseDir + "android.lib_with_resource_files-layoutinfo.bin",
        libWithResourcesMetadataBaseDir + "android.lib_with_resource_files-br.bin");
    for (String compileInput : appJarInputs) {
      assertThat(compileInput).doesNotMatch(".*lib_no_resource_files.*.bin");
    }
  }

  @Test
  public void libsWithNoResourcesOnlyRunAnnotationProcessor() throws Exception {
    // Bazel skips resource processing because there are no new resources to process. But it still
    // runs the annotation processor to ensure the Java compiler reads Java sources referenced by
    // the deps' resources (e.g. "<variable type="some.package.SomeClass" />"). Without this,
    // JavaBuilder's --reduce_classpath feature would strip out those sources as "unused" and fail
    // the binary's compilation with unresolved symbol errors.
    writeDataBindingFilesWithNoResourcesDep();
    ConfiguredTarget ct = getConfiguredTarget("//java/android/lib_no_resource_files");
    Iterable<Artifact> libArtifacts = getFilesToBuild(ct);

    assertThat(getFirstArtifactEndingWith(libArtifacts, "_resources.jar")).isNull();
    assertThat(getFirstArtifactEndingWith(libArtifacts, "layout-info.zip")).isNull();

    JavaCompileAction libCompileAction = (JavaCompileAction) getGeneratingAction(
        getFirstArtifactEndingWith(libArtifacts, "lib_no_resource_files.jar"));
    // The annotation processor is attached to the Java compilation:
    assertThat(getParamFileContents(libCompileAction)).containsAllOf(
        "--processors",
        "android.databinding.annotationprocessor.ProcessDataBinding");
    // The dummy .java file with annotations that trigger the annotation process is present:
    assertThat(ActionsTestUtil.prettyArtifactNames(libCompileAction.getInputs()))
        .contains("java/android/lib_no_resource_files/databinding/lib_no_resource_files/"
            + "DataBindingInfo.java");
  }

  @Test
  public void missingDataBindingAttributeStillAnalyzes() throws Exception {
    // When a library is missing enable_data_binding = 1, we expect it to fail in execution (because
    // aapt doesn't know how to read the data binding expressions). But analysis should work.
    scratch.file("java/android/library/BUILD",
        "android_library(",
        "    name = 'lib_with_data_binding',",
        "    enable_data_binding = 1,",
        "    manifest = 'AndroidManifest.xml',",
        "    srcs = ['MyLib.java'],",
        "    resource_files = [],",
        ")");
    scratch.file("java/android/library/MyLib.java",
        "package android.library; public class MyLib {};");
    scratch.file("java/android/binary/BUILD",
        "android_binary(",
        "    name = 'app',",
        "    enable_data_binding = 0,",
        "    manifest = 'AndroidManifest.xml',",
        "    srcs = ['MyApp.java'],",
        "    deps = ['//java/android/library:lib_with_data_binding'],",
        ")");
    scratch.file("java/android/binary/MyApp.java",
        "package android.binary; public class MyApp {};");
    assertThat(getConfiguredTarget("//java/android/binary:app")).isNotNull();
  }
}
