// 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.ImmutableMap;
import com.google.devtools.build.lib.actions.Artifact;
import com.google.devtools.build.lib.analysis.ConfiguredTarget;
import com.google.devtools.build.lib.analysis.actions.SpawnAction;
import com.google.devtools.build.lib.analysis.util.BuildViewTestCase;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.rules.android.AndroidRuleClasses.MultidexMode;
import java.util.Set;
import org.junit.Before;

/**
 * Base class for testing the multidex code of android_binary and android_test.
 */
public class AndroidMultidexBaseTest extends BuildViewTestCase {

  @Before
  public final void createFiles() throws Exception {
    scratch.file("java/android/BUILD",
        "android_binary(name = 'app',",
        "               srcs = ['A.java'],",
        "               manifest = 'AndroidManifest.xml',",
        "               resource_files = glob(['res/**']),",
        "              )");
    scratch.file("java/android/res/values/strings.xml",
        "<resources><string name = 'hello'>Hello Android!</string></resources>");
    scratch.file("java/android/A.java",
        "package android; public class A {};");
  }

  /**
   * Internal helper method: given an android_binary rule label, check that it builds in
   * multidex mode. Three multidex variations are possible: "legacy", "manual_main_dex" and
   * "native".
   *
   * @param ruleLabel the android_binary rule label to test against
   * @param multidexMode the multidex mode used in the rule
   */
  protected void internalTestMultidexBuildStructure(
      String ruleLabel, MultidexMode multidexMode) throws Exception {

    ConfiguredTarget binary = getConfiguredTarget(ruleLabel);
    Set<Artifact> artifacts = actionsTestUtil().artifactClosureOf(getFilesToBuild(binary));

    Artifact finalDexOutput = getFirstArtifactEndingWith(artifacts, "/classes.dex.zip");
    assertThat(finalDexOutput).isNotNull();

    // Only created in legacy mode:
    Artifact strippedJar = getFirstArtifactEndingWith(artifacts, "main_dex_intermediate.jar");
    Artifact mainDexList = getFirstArtifactEndingWith(artifacts, "main_dex_list.txt");
    String ruleName = Label.parseAbsolute(ruleLabel, ImmutableMap.of()).getName();
    Artifact mainDexProguardSpec = getFirstArtifactEndingWith(
        artifacts, "main_dex_" + ruleName + "_proguard.cfg");

    if (multidexMode == MultidexMode.LEGACY) {
      // First action: check that the stripped jar is generated through Proguard.
      assertThat(mainDexProguardSpec).isNotNull();
      AndroidSdkProvider sdk = AndroidSdkProvider.fromRuleContext(getRuleContext(binary));
      assertThat(strippedJar).isNotNull();
      SpawnAction stripAction = getGeneratingSpawnAction(strippedJar);
      assertThat(stripAction.getCommandFilename())
          .isEqualTo(sdk.getProguard().getExecutable().getExecPathString());
      assertThat(stripAction.getInputs()).contains(mainDexProguardSpec);

      // Second action: The dexer consumes the stripped jar to create the main dex class list.
      assertThat(mainDexList).isNotNull();
      SpawnAction mainDexAction = getGeneratingSpawnAction(mainDexList);
      assertThat(mainDexAction.getArguments()).containsAllOf(
          mainDexList.getExecPathString(),
          strippedJar.getExecPathString()).inOrder();
    } else if (multidexMode == MultidexMode.MANUAL_MAIN_DEX) {
      // Manual main dex mode: strippedJar shouldn't exist and mainDexList should be provided.
      assertThat(strippedJar).isNull();
      assertThat(mainDexList).isNotNull();
    } else {
      // Native mode: these shouldn't exist.
      assertThat(strippedJar).isNull();
      assertThat(mainDexList).isNull();
    }

    Artifact dexMergerInput = getFirstArtifactEndingWith(artifacts, "classes.jar");
    SpawnAction dexMergerAction = getGeneratingSpawnAction(finalDexOutput);
    ImmutableList.Builder<String> argsBuilder = ImmutableList.<String>builder()
        .add(
            "--input",
            dexMergerInput.getExecPathString(),
            "--output",
            finalDexOutput.getExecPathString());
    if (multidexMode != MultidexMode.OFF) {
      argsBuilder.add("--multidex=minimal");
    }
    if (multidexMode == MultidexMode.LEGACY || multidexMode == MultidexMode.MANUAL_MAIN_DEX) {
      argsBuilder.add("--main-dex-list", mainDexList.getExecPathString());
    }
    assertThat(dexMergerAction.getRemainingArguments())
        .containsExactlyElementsIn(argsBuilder.build())
        .inOrder();
  }

  /**
   * Internal helper method: given an android_binary rule label, check that the dex merger
   * runs is invoked with {@code --multidex=off}.
   */
  protected void internalTestNonMultidexBuildStructure(String ruleLabel) throws Exception {
    ConfiguredTarget binary = getConfiguredTarget(ruleLabel);
    Set<Artifact> artifacts = actionsTestUtil().artifactClosureOf(getFilesToBuild(binary));
    Artifact dexInput = getFirstArtifactEndingWith(artifacts, "classes.jar");
    Artifact dexOutput = getFirstArtifactEndingWith(artifacts, "classes.dex.zip");
    SpawnAction dexAction = getGeneratingSpawnAction(dexOutput);

    assertThat(dexAction.getRemainingArguments())
        .containsAllOf(
            "--input",
            dexInput.getExecPathString(),
            "--output",
            dexOutput.getExecPathString(),
            "--multidex=off")
        .inOrder();
  }
}

