// 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.common.truth.Truth.assertWithMessage;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
import com.google.devtools.build.lib.actions.ActionAnalysisMetadata;
import com.google.devtools.build.lib.actions.Artifact;
import com.google.devtools.build.lib.analysis.ConfiguredTarget;
import com.google.devtools.build.lib.analysis.RuleContext;
import com.google.devtools.build.lib.packages.RuleClass.ConfiguredTargetFactory.RuleErrorException;
import com.google.devtools.build.lib.rules.android.databinding.DataBinding;
import com.google.devtools.build.lib.rules.android.databinding.DataBindingContext;
import com.google.devtools.build.lib.vfs.PathFragment;
import java.util.Optional;
import java.util.Set;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

/** Tests {@link AndroidResources} */
@RunWith(JUnit4.class)
public class AndroidResourcesTest extends ResourceTestBase {

  private static final PathFragment DEFAULT_RESOURCE_ROOT = PathFragment.create(RESOURCE_ROOT);
  private static final ImmutableList<PathFragment> RESOURCES_ROOTS =
      ImmutableList.of(DEFAULT_RESOURCE_ROOT);

  @Before
  public void setupCcToolchain() throws Exception {
    getAnalysisMock().ccSupport().setupCcToolchainConfigForCpu(mockToolsConfig, "armeabi-v7a");
  }

  @Before
  @Test
  public void testGetResourceRootsNoResources() throws Exception {
    assertThat(getResourceRoots()).isEmpty();
  }

  @Test
  public void testGetResourceRootsInvalidResourceDirectory() throws Exception {
    try {
      getResourceRoots("is-this-drawable-or-values/foo.xml");
      assertWithMessage("Expected exception not thrown!").fail();
    } catch (RuleErrorException e) {
      // expected
    }

    errorConsumer.assertAttributeError(
        "resource_files", "is not in the expected resource directory structure");
  }

  @Test
  public void testGetResourceRootsMultipleRoots() throws Exception {
    try {
      getResourceRoots("subdir/values/foo.xml", "otherdir/values/bar.xml");
      assertWithMessage("Expected exception not thrown!").fail();
    } catch (RuleErrorException e) {
      // expected
    }

    errorConsumer.assertAttributeError(
        "resource_files", "All resources must share a common directory");
  }

  @Test
  public void testGetResourceRoots() throws Exception {
    assertThat(getResourceRoots("values-hdpi/foo.xml", "values-mdpi/bar.xml"))
        .isEqualTo(RESOURCES_ROOTS);
  }

  @Test
  public void testGetResourceRootsCommonSubdirectory() throws Exception {
    assertThat(getResourceRoots("subdir/values-hdpi/foo.xml", "subdir/values-mdpi/bar.xml"))
        .containsExactly(DEFAULT_RESOURCE_ROOT.getRelative("subdir"));
  }

  private ImmutableList<PathFragment> getResourceRoots(String... pathResourceStrings)
      throws Exception {
    return getResourceRoots(getResources(pathResourceStrings));
  }

  private ImmutableList<PathFragment> getResourceRoots(ImmutableList<Artifact> artifacts)
      throws Exception {
    return AndroidResources.getResourceRoots(errorConsumer, artifacts, "resource_files");
  }

  @Test
  public void testFilterEmpty() throws Exception {
    assertFilter(ImmutableList.of(), ImmutableList.of());
  }

  @Test
  public void testFilterNoop() throws Exception {
    ImmutableList<Artifact> resources = getResources("values-en/foo.xml", "values-es/bar.xml");
    assertFilter(resources, resources);
  }

  @Test
  public void testFilterToEmpty() throws Exception {
    assertFilter(getResources("values-en/foo.xml", "values-es/bar.xml"), ImmutableList.of());
  }

  @Test
  public void testPartiallyFilter() throws Exception {
    Artifact keptResource = getResource("values-en/foo.xml");
    assertFilter(
        ImmutableList.of(keptResource, getResource("values-es/bar.xml")),
        ImmutableList.of(keptResource));
  }

  @Test
  public void testFilterIsDependency() throws Exception {
    Artifact keptResource = getResource("values-en/foo.xml");
    assertFilter(
        ImmutableList.of(keptResource, getResource("drawable/bar.png")),
        ImmutableList.of(keptResource),
        /* isDependency = */ true);
  }

  @Test
  public void testFilterValidatedNoop() throws Exception {
    ImmutableList<Artifact> resources = getResources("values-en/foo.xml", "values-es/bar.xml");
    assertFilterValidated(resources, resources);
  }

  @Test
  public void testFilterValidated() throws Exception {
    Artifact keptResource = getResource("values-en/foo.xml");
    assertFilterValidated(
        ImmutableList.of(keptResource, getResource("drawable/bar.png")),
        ImmutableList.of(keptResource));
  }

  private void assertFilterValidated(
      ImmutableList<Artifact> unfilteredResources, ImmutableList<Artifact> filteredResources)
      throws Exception {
    RuleContext ruleContext = getRuleContext();
    final AndroidDataContext dataContext = AndroidDataContext.forNative(ruleContext);
    ValidatedAndroidResources unfiltered =
        new AndroidResources(unfilteredResources, getResourceRoots(unfilteredResources))
            .process(
                ruleContext,
                dataContext,
                getManifest(),
                DataBinding.contextFrom(ruleContext, dataContext.getAndroidConfig()),
                /* neverlink = */ false);
    Optional<? extends AndroidResources> maybeFiltered =
        assertFilter(unfiltered, filteredResources, /* isDependency = */ true);

    if (maybeFiltered.isPresent()) {
      AndroidResources filtered = maybeFiltered.get();
      assertThat(filtered instanceof ValidatedAndroidResources).isTrue();
      ValidatedAndroidResources validated = (ValidatedAndroidResources) filtered;

      // Validate fields related to validation are unchanged
      assertThat(validated.getRTxt()).isEqualTo(unfiltered.getRTxt());
      assertThat(validated.getAapt2RTxt()).isEqualTo(unfiltered.getAapt2RTxt());
    }
  }

  private void assertFilter(
      ImmutableList<Artifact> unfilteredResources, ImmutableList<Artifact> filteredResources)
      throws Exception {
    assertFilter(unfilteredResources, filteredResources, /* isDependency = */ false);
  }

  private void assertFilter(
      ImmutableList<Artifact> unfilteredResources,
      ImmutableList<Artifact> filteredResources,
      boolean isDependency)
      throws Exception {
    AndroidResources unfiltered =
        new AndroidResources(unfilteredResources, getResourceRoots(unfilteredResources));
    assertFilter(unfiltered, filteredResources, isDependency);
  }

  private Optional<? extends AndroidResources> assertFilter(
      AndroidResources unfiltered, ImmutableList<Artifact> filteredResources, boolean isDependency)
      throws Exception {

    ImmutableList.Builder<Artifact> filteredDepsBuilder = ImmutableList.builder();

    ResourceFilter fakeFilter =
        ResourceFilter.of(ImmutableSet.copyOf(filteredResources), filteredDepsBuilder::add);

    Optional<? extends AndroidResources> filtered =
        unfiltered.maybeFilter(errorConsumer, fakeFilter, isDependency);

    if (filteredResources.equals(unfiltered.getResources())) {
      // We expect filtering to have been a no-op
      assertThat(filtered.isPresent()).isFalse();
    } else {
      // The resources and their roots should be filtered
      assertThat(filtered.get().getResources())
          .containsExactlyElementsIn(filteredResources)
          .inOrder();
      assertThat(filtered.get().getResourceRoots())
          .containsExactlyElementsIn(getResourceRoots(filteredResources))
          .inOrder();
    }

    if (!isDependency) {
      // The filter should not record any filtered dependencies
      assertThat(filteredDepsBuilder.build()).isEmpty();
    } else {
      // The filtered dependencies should be exactly the list of filtered resources
      assertThat(unfiltered.getResources())
          .containsExactlyElementsIn(
              Iterables.concat(filteredDepsBuilder.build(), filteredResources));
    }

    return filtered;
  }

  @Test
  public void testParseAndCompile() throws Exception {
    RuleContext ruleContext = getRuleContext();
    ParsedAndroidResources parsed = assertParse(ruleContext);

    assertThat(parsed.getCompiledSymbols()).isNotNull();

    // Since there was no data binding, the compile action should just take in resources and output
    // compiled symbols.
    assertActionArtifacts(
        ruleContext,
        /* inputs = */ parsed.getResources(),
        /* outputs = */ ImmutableList.of(parsed.getCompiledSymbols()));
  }

  @Test
  public void testMergeCompiled() throws Exception {
    RuleContext ruleContext = getRuleContext();
    ParsedAndroidResources parsed = assertParse(ruleContext);
    MergedAndroidResources merged =
        parsed.merge(
            AndroidDataContext.forNative(ruleContext),
            ResourceDependencies.fromRuleDeps(ruleContext, /* neverlink = */ false));

    // Besides processed manifest, inherited values should be equal
    assertThat(parsed).isEqualTo(new ParsedAndroidResources(merged, parsed.getStampedManifest()));

    // There should be a new processed manifest
    assertThat(merged.getManifest()).isNotEqualTo(parsed.getManifest());

    assertThat(merged.getDataBindingInfoZip()).isNull();
    assertThat(merged.getCompiledSymbols()).isNotNull();

    // We use the compiled symbols file to build the resource class jar
    assertActionArtifacts(
        ruleContext,
        /*inputs=*/ ImmutableList.of(merged.getCompiledSymbols(), parsed.getManifest()),
        /*outputs=*/ ImmutableList.of(merged.getClassJar(), merged.getManifest()));
  }

  @Test
  public void testValidateAapt2() throws Exception {
    RuleContext ruleContext = getRuleContext();

    MergedAndroidResources merged = makeMergedResources(ruleContext);
    ValidatedAndroidResources validated =
        merged.validate(AndroidDataContext.forNative(ruleContext));

    // Inherited values should be equal
    assertThat(merged).isEqualTo(new MergedAndroidResources(validated));

    // aapt artifacts should be generated
    assertActionArtifacts(
        ruleContext,
        /* inputs = */ ImmutableList.of(validated.getCompiledSymbols(), validated.getManifest()),
        /* outputs = */ ImmutableList.of(
            validated.getRTxt(), validated.getJavaSourceJar(), validated.getApk()));

    // aapt2 artifacts should be recorded
    assertThat(validated.getCompiledSymbols()).isNotNull();
    assertThat(validated.getAapt2RTxt()).isNotNull();
    assertThat(validated.getAapt2SourceJar()).isNotNull();
    assertThat(validated.getStaticLibrary()).isNotNull();

    // Compile the resources into compiled symbols files
    assertActionArtifacts(
        ruleContext,
        /* inputs = */ validated.getResources(),
        /* outputs = */ ImmutableList.of(validated.getCompiledSymbols()));

    // Use the compiled symbols and manifest to build aapt2 packaging outputs
    assertActionArtifacts(
        ruleContext,
        /* inputs = */ ImmutableList.of(validated.getCompiledSymbols(), validated.getManifest()),
        /* outputs = */ ImmutableList.of(
            validated.getAapt2RTxt(), validated.getAapt2SourceJar(), validated.getStaticLibrary()));
  }

  @Test
  public void testValidate() throws Exception {
    RuleContext ruleContext = getRuleContext();

    makeMergedResources(ruleContext).validate(AndroidDataContext.forNative(ruleContext));

    Set<String> actionMnemonics =
        ruleContext.getAnalysisEnvironment().getRegisteredActions().stream()
            .map(ActionAnalysisMetadata::getMnemonic)
            .collect(ImmutableSet.toImmutableSet());
    // These are unfortunately the mnemonics used in Bazel; these should be changed once aapt1 is
    // removed.
    assertThat(actionMnemonics).contains("AndroidResourceLink"); // aapt2 validation
    assertThat(actionMnemonics).doesNotContain("AndroidResourceValidator"); // aapt1 validation
  }

  @Test
  public void testGenerateRClass() throws Exception {
    RuleContext ruleContext = getRuleContext();
    Artifact rTxt = ruleContext.getImplicitOutputArtifact(AndroidRuleClasses.ANDROID_R_TXT);
    ProcessedAndroidManifest manifest = getManifest();

    ProcessedAndroidData processedData =
        ProcessedAndroidData.of(
            makeParsedResources(ruleContext),
            AndroidAssets.from(ruleContext)
                .process(AndroidDataContext.forNative(ruleContext), AssetDependencies.empty()),
            manifest,
            rTxt,
            ruleContext.getImplicitOutputArtifact(AndroidRuleClasses.ANDROID_JAVA_SOURCE_JAR),
            ruleContext.getImplicitOutputArtifact(AndroidRuleClasses.ANDROID_RESOURCES_APK),
            /* dataBindingInfoZip = */ null,
            ResourceDependencies.fromRuleDeps(ruleContext, /* neverlink = */ false),
            null,
            null);

    ValidatedAndroidResources validated =
        processedData
            .generateRClass(AndroidDataContext.forNative(ruleContext))
            .getValidatedResources();

    // An action to generate the R.class file should be registered.
    assertActionArtifacts(
        ruleContext,
        /* inputs = */ ImmutableList.of(rTxt, manifest.getManifest()),
        /* outputs = */ ImmutableList.of(validated.getJavaClassJar()));
  }

  @Test
  public void testProcessBinaryDataGeneratesProguardOutput() throws Exception {
    RuleContext ruleContext = getRuleContext("android_binary", "manifest='AndroidManifest.xml',");
    AndroidDataContext dataContext = AndroidDataContext.forNative(ruleContext);

    ResourceApk resourceApk =
        ProcessedAndroidData.processBinaryDataFrom(
                dataContext,
                ruleContext,
                getManifest(),
                false,
                ImmutableMap.of(),
                AndroidResources.empty(),
                AndroidAssets.empty(),
                ResourceDependencies.empty(),
                AssetDependencies.empty(),
                ResourceFilterFactory.empty(),
                ImmutableList.of(),
                false,
                DataBinding.contextFrom(ruleContext, dataContext.getAndroidConfig()))
            .generateRClass(dataContext);

    assertThat(resourceApk.getResourceProguardConfig()).isNotNull();
    assertThat(resourceApk.getMainDexProguardConfig()).isNotNull();
  }

  /**
   * Validates that a parse action was invoked correctly. Returns the {@link ParsedAndroidResources}
   * for further validation.
   */
  private ParsedAndroidResources assertParse(RuleContext ruleContext) throws Exception {
    return assertParse(
        ruleContext,
        DataBinding.contextFrom(
            ruleContext, ruleContext.getConfiguration().getFragment(AndroidConfiguration.class)));
  }

  private ParsedAndroidResources assertParse(
      RuleContext ruleContext, DataBindingContext dataBindingContext) throws Exception {
    ImmutableList<Artifact> resources = getResources("values-en/foo.xml", "drawable-hdpi/bar.png");
    AndroidResources raw =
        new AndroidResources(
            resources, AndroidResources.getResourceRoots(ruleContext, resources, "resource_files"));
    StampedAndroidManifest manifest = getManifest();

    ParsedAndroidResources parsed =
        raw.parse(
            AndroidDataContext.forNative(ruleContext),
            manifest,
            dataBindingContext);

    // Inherited values should be equal
    assertThat(raw).isEqualTo(new AndroidResources(parsed));

    // Label should be set from RuleContext
    assertThat(parsed.getLabel()).isEqualTo(ruleContext.getLabel());

    return parsed;
  }

  private MergedAndroidResources makeMergedResources(RuleContext ruleContext)
      throws RuleErrorException, InterruptedException {
    return makeParsedResources(ruleContext)
        .merge(
            AndroidDataContext.forNative(ruleContext),
            ResourceDependencies.fromRuleDeps(ruleContext, /* neverlink = */ false));
  }

  private ParsedAndroidResources makeParsedResources(RuleContext ruleContext)
      throws RuleErrorException, InterruptedException {
    DataBindingContext dataBindingContext =
        DataBinding.contextFrom(
            ruleContext, ruleContext.getConfiguration().getFragment(AndroidConfiguration.class));
    return makeParsedResources(ruleContext, dataBindingContext);
  }

  private ParsedAndroidResources makeParsedResources(
      RuleContext ruleContext, DataBindingContext dataBindingContext)
      throws RuleErrorException, InterruptedException {
    ImmutableList<Artifact> resources = getResources("values-en/foo.xml", "drawable-hdpi/bar.png");
    return new AndroidResources(
            resources, AndroidResources.getResourceRoots(ruleContext, resources, "resource_files"))
        .parse(
            AndroidDataContext.forNative(ruleContext),
            getManifest(),
            dataBindingContext);
  }

  private ProcessedAndroidManifest getManifest() {
    return new ProcessedAndroidManifest(
        getResource("some/path/AndroidManifest.xml"), "some.java.pkg", /* exported = */ true);
  }

  /** Gets a dummy rule context object by creating a dummy target. */
  private RuleContext getRuleContext() throws Exception {
    return getRuleContext("android_library");
  }

  /** Gets a dummy rule context object by creating a dummy target. */
  private RuleContext getRuleContext(String kind, String... additionalLines) throws Exception {
    ConfiguredTarget target =
        scratchConfiguredTarget(
            "java/foo",
            "target",
            ImmutableList.<String>builder()
                .add(kind + "(name = 'target',")
                .add(additionalLines)
                .add(")")
                .build()
                .toArray(new String[0]));
    return getRuleContextForActionTesting(target);
  }
}
