// Copyright 2018 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.android;

import static com.google.common.truth.Truth.assertThat;
import static java.nio.charset.StandardCharsets.UTF_8;
import static org.hamcrest.CoreMatchers.containsString;
import static org.junit.Assert.assertNotNull;

import com.android.builder.core.VariantTypeImpl;
import com.google.common.base.Joiner;
import com.google.common.collect.ImmutableList;
import com.google.devtools.build.android.AarGeneratorAction.AarGeneratorOptions;
import com.google.devtools.build.zip.ZipReader;
import com.google.devtools.common.options.OptionsParser;
import com.google.devtools.common.options.OptionsParsingException;
import com.google.errorprone.annotations.CanIgnoreReturnValue;
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.attribute.FileTime;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

/** Tests for {@link AarGeneratorAction}. */
@RunWith(JUnit4.class)
public class AarGeneratorActionTest {

  private static class AarData {
    /** Templates for resource files generation. */
    enum ResourceType {
      VALUE {
        @Override public String create(String... lines) {
          return String.format(
              "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>%s</resources>",
              Joiner.on("\n").join(lines));
        }
      },
      LAYOUT {
        @Override public String create(String... lines) {
          return String.format("<?xml version=\"1.0\" encoding=\"utf-8\"?>"
              + "<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\""
              + " android:layout_width=\"fill_parent\""
              + " android:layout_height=\"fill_parent\">%s</LinearLayout>",
              Joiner.on("\n").join(lines));
        }
      },
      UNFORMATTED {
        @Override public String create(String... lines) {
          return String.format(Joiner.on("\n").join(lines));
        }
      };

      public abstract String create(String... lines);
    }

    private static class Builder {

      private final Path root;
      private final Path assetDir;
      private final Path resourceDir;
      private Path manifest;
      private Path rtxt;
      private Path classes;
      private Map<Path, String> filesToWrite = new HashMap<>();
      private Map<String, String> classesToWrite = new HashMap<>();
      private ImmutableList.Builder<Path> proguardSpecs = ImmutableList.builder();
      private boolean withEmptyRes = false;
      private boolean withEmptyAssets = false;

      public Builder(Path root) {
        this(root, "res", "assets");
      }

      public Builder(Path root, String resourceRoot, String assetRoot) {
        this.root = root;
        assetDir = root.resolve(assetRoot);
        resourceDir = root.resolve(resourceRoot);
        manifest = root.resolve("fake-manifest-path");
        rtxt = root.resolve("fake-rtxt-path");
        classes = root.resolve("fake-classes-path");
      }

      @CanIgnoreReturnValue
      public Builder addResource(String path, ResourceType template, String... lines) {
        filesToWrite.put(resourceDir.resolve(path), template.create(lines));
        return this;
      }

      @CanIgnoreReturnValue
      public Builder withEmptyResources(boolean isEmpty) {
        this.withEmptyRes = isEmpty;
        return this;
      }

      @CanIgnoreReturnValue
      public Builder addAsset(String path, String... lines) {
        filesToWrite.put(assetDir.resolve(path), Joiner.on("\n").join(lines));
        return this;
      }

      @CanIgnoreReturnValue
      public Builder withEmptyAssets(boolean isEmpty) {
        this.withEmptyAssets = isEmpty;
        return this;
      }

      @CanIgnoreReturnValue
      public Builder createManifest(String path, String manifestPackage, String... lines) {
        this.manifest = root.resolve(path);
        filesToWrite.put(manifest, String.format("<?xml version=\"1.0\" encoding=\"utf-8\"?>"
            + "<manifest xmlns:android='http://schemas.android.com/apk/res/android' package='%s'>"
            + "%s</manifest>", manifestPackage, Joiner.on("\n").join(lines)));
        return this;
      }

      @CanIgnoreReturnValue
      public Builder createRtxt(String path, String... lines) {
        this.rtxt = root.resolve(path);
        filesToWrite.put(rtxt, String.format("%s", Joiner.on("\n").join(lines)));
        return this;
      }

      @CanIgnoreReturnValue
      public Builder createClassesJar(String path) {
        this.classes = root.resolve(path);
        classesToWrite.put("META-INF/MANIFEST.MF", "Manifest-Version: 1.0\n");
        return this;
      }

      @CanIgnoreReturnValue
      public Builder addClassesFile(String filePackage, String filename, String... lines) {
        classesToWrite.put(filePackage.replace(".", "/") + "/" + filename,
            String.format("%s", Joiner.on("\n").join(lines)));
        return this;
      }

      @CanIgnoreReturnValue
      public Builder addProguardSpec(String path, String... lines) {
        Path proguardSpecPath = root.resolve(path);
        proguardSpecs.add(proguardSpecPath);
        filesToWrite.put(proguardSpecPath, String.format("%s", Joiner.on("\n").join(lines)));
        return this;
      }

      public AarData build() throws IOException {
        writeFiles();
        return new AarData(buildMerged(), manifest, rtxt, classes, proguardSpecs.build());
      }

      private MergedAndroidData buildMerged() {
        return new MergedAndroidData(
            resourceDir,
            assetDir,
            manifest);
      }

      private void writeFiles() throws IOException {
        assertNotNull("A manifest is required.", manifest);
        assertNotNull("A resource file is required.", rtxt);
        assertNotNull("A classes jar is required.", classes);
        if (withEmptyRes) {
          Files.createDirectories(resourceDir);
        }
        if (withEmptyAssets) {
          Files.createDirectories(assetDir);
        }
        for (Map.Entry<Path, String> entry : filesToWrite.entrySet()) {
          Path file = entry.getKey();
          // only write files in assets if assets has not been set to empty and same for resources
          if (!((file.startsWith(assetDir) && withEmptyAssets)
              || (file.startsWith(resourceDir) && withEmptyRes))) {
            Files.createDirectories(file.getParent());
            Files.write(file, entry.getValue().getBytes(StandardCharsets.UTF_8));
            assertThat(Files.exists(file)).isTrue();
          }
        }
        if (!classesToWrite.isEmpty()) {
          writeClassesJar();
        }
      }

      private void writeClassesJar() throws IOException {
        final ZipOutputStream zout = new ZipOutputStream(new FileOutputStream(classes.toFile()));

        for (Map.Entry<String, String> file : classesToWrite.entrySet()) {
          ZipEntry entry = new ZipEntry(file.getKey());
          zout.putNextEntry(entry);
          zout.write(file.getValue().getBytes(UTF_8));
          zout.closeEntry();
        }

        zout.close();

        Files.setLastModifiedTime(classes, FileTime.from(AarGeneratorAction.DEFAULT_TIMESTAMP));
      }
    }

    final MergedAndroidData data;
    final Path manifest;
    final Path rtxt;
    final Path classes;
    final ImmutableList<Path> proguardSpecs;

    private AarData(
        MergedAndroidData data,
        Path manifest,
        Path rtxt,
        Path classes,
        ImmutableList<Path> proguardSpecs) {
      this.data = data;
      this.manifest = manifest;
      this.rtxt = rtxt;
      this.classes = classes;
      this.proguardSpecs = proguardSpecs;
    }
  }

  /**
   * Operation to perform on a file.
   */
  private interface FileOperation {
    /**
     * Performs the operation on a file, given its name, modificationTime and contents.
     */
    void perform(String name, long modificationTime, String contents);
  }

  /**
   * Runs a {@link FileOperation} on every entry in a zip file.
   *
   * @param zip {@link Path} of the zip file to traverse.
   * @param operation {@link FileOperation} to be run on every entry of the zip file.
   * @throws IOException if there is an error reading the zip file.
   */
  private void traverseZipFile(Path zip, FileOperation operation) throws IOException {
    ZipInputStream zis = new ZipInputStream(Files.newInputStream(zip));
    ZipEntry z = zis.getNextEntry();
    while (z != null) {
      ByteArrayOutputStream baos = new ByteArrayOutputStream();
      byte[] buffer = new byte[1024];
      for (int count = 0; count != -1; count = zis.read(buffer)) {
        baos.write(buffer);
      }
      // Replace Windows path separators so that test cases are consistent across platforms.
      String name = z.getName().replace('\\', '/');
      operation.perform(
          name, z.getTime(), new String(baos.toByteArray(), StandardCharsets.UTF_8));
      z = zis.getNextEntry();
    }
  }

  private Set<String> getZipEntries(Path zip) throws IOException {
    final Set<String> zipEntries = new HashSet<>();
    traverseZipFile(zip, new FileOperation() {
      @Override public void perform(String name, long modificationTime, String contents) {
        zipEntries.add(name);
      }
    });
    return zipEntries;
  }

  private Set<Long> getZipEntryTimestamps(Path zip) throws IOException {
    final Set<Long> timestamps = new HashSet<>();
    traverseZipFile(zip, new FileOperation() {
      @Override public void perform(String name, long modificationTime, String contents) {
        timestamps.add(modificationTime);
      }
    });
    return timestamps;
  }

  private Path tempDir;

  @Rule public ExpectedException thrown = ExpectedException.none();

  @Before public void setUp() throws IOException {
    tempDir = Files.createTempDirectory(toString());
    tempDir.toFile().deleteOnExit();

  }

  @Test public void testCheckFlags() throws IOException, OptionsParsingException {
    Path manifest = tempDir.resolve("AndroidManifest.xml");
    Files.createFile(manifest);
    Path rtxt = tempDir.resolve("R.txt");
    Files.createFile(rtxt);
    Path classes = tempDir.resolve("classes.jar");
    Files.createFile(classes);

    String[] args = new String[] {"--manifest", manifest.toString(), "--rtxt", rtxt.toString(),
        "--classes", classes.toString()};
    OptionsParser optionsParser =
        OptionsParser.builder().optionsClasses(AarGeneratorOptions.class).build();
    optionsParser.parse(args);
    AarGeneratorOptions options = optionsParser.getOptions(AarGeneratorOptions.class);
    AarGeneratorAction.checkFlags(options);
  }

  @Test public void testCheckFlags_MissingClasses() throws IOException, OptionsParsingException {
    Path manifest = tempDir.resolve("AndroidManifest.xml");
    Files.createFile(manifest);
    Path rtxt = tempDir.resolve("R.txt");
    Files.createFile(rtxt);

    String[] args = new String[] {"--manifest", manifest.toString(), "--rtxt", rtxt.toString()};
    OptionsParser optionsParser =
        OptionsParser.builder().optionsClasses(AarGeneratorOptions.class).build();
    optionsParser.parse(args);
    AarGeneratorOptions options = optionsParser.getOptions(AarGeneratorOptions.class);
    thrown.expect(IllegalArgumentException.class);
    thrown.expectMessage("classes must be specified. Building an .aar without"
          + " classes is unsupported.");
    AarGeneratorAction.checkFlags(options);
  }

  @Test public void testCheckFlags_MissingMultiple() throws IOException, OptionsParsingException {
    Path manifest = tempDir.resolve("AndroidManifest.xml");
    Files.createFile(manifest);
    String[] args = new String[] {"--manifest", manifest.toString()};
    OptionsParser optionsParser =
        OptionsParser.builder().optionsClasses(AarGeneratorOptions.class).build();
    optionsParser.parse(args);
    AarGeneratorOptions options = optionsParser.getOptions(AarGeneratorOptions.class);
    thrown.expect(IllegalArgumentException.class);
    thrown.expectMessage("rtxt, classes must be specified. Building an .aar without"
          + " rtxt, classes is unsupported.");
    AarGeneratorAction.checkFlags(options);
  }

  @Test public void testWriteAar() throws Exception {
    Path aar = tempDir.resolve("foo.aar");
    AarData aarData = new AarData.Builder(tempDir.resolve("data"))
        .createManifest("AndroidManifest.xml", "com.google.android.apps.foo.d1", "")
        .createRtxt("R.txt",
            "int string app_name 0x7f050001",
            "int string hello_world 0x7f050002")
        .addResource("values/ids.xml",
            AarData.ResourceType.VALUE,
            "<item name=\"id_name\" type=\"id\"/>")
        .addAsset("some/other/ft/data.txt", "bar")
        .createClassesJar("classes.jar")
        .addClassesFile("com.google.android.apps.foo", "Test.class", "test file contents")
        .build();

    AarGeneratorAction.writeAar(aar,
        aarData.data,
        aarData.manifest,
        aarData.rtxt,
        aarData.classes,
        aarData.proguardSpecs);
  }

  @Test public void testWriteAar_DefaultTimestamps() throws Exception {
    Path aar = tempDir.resolve("foo.aar");
    AarData aarData = new AarData.Builder(tempDir.resolve("data"))
        .createManifest("AndroidManifest.xml", "com.google.android.apps.foo.d1", "")
        .createRtxt("R.txt",
            "int string app_name 0x7f050001",
            "int string hello_world 0x7f050002")
        .addResource("values/ids.xml",
            AarData.ResourceType.VALUE,
            "<item name=\"id_name\" type=\"id\"/>")
        .addAsset("some/other/ft/data.txt", "bar")
        .createClassesJar("classes.jar")
        .addClassesFile("com.google.android.apps.foo", "Test.class", "test file contents")
        .build();

    AarGeneratorAction.writeAar(aar,
        aarData.data,
        aarData.manifest,
        aarData.rtxt,
        aarData.classes,
        aarData.proguardSpecs);

    assertThat(getZipEntryTimestamps(aar))
        .containsExactly(AarGeneratorAction.DEFAULT_TIMESTAMP.toEpochMilli());
    assertThat(Files.getLastModifiedTime(aar).toInstant())
        .isEqualTo(AarGeneratorAction.DEFAULT_TIMESTAMP);
  }

  @Test public void testAssetResourceSubdirs() throws Exception {
    Path aar = tempDir.resolve("foo.aar");
    AarData aarData = new AarData.Builder(tempDir.resolve("data"), "xyz", "assets")
        .createManifest("AndroidManifest.xml", "com.google.android.apps.foo.d1", "")
        .createRtxt("R.txt",
            "int string app_name 0x7f050001",
            "int string hello_world 0x7f050002")
        .addResource("values/ids.xml",
            AarData.ResourceType.VALUE,
            "<item name=\"id_name\" type=\"id\"/>")
        .addAsset("some/other/ft/data.txt", "bar")
        .createClassesJar("classes.jar")
        .addClassesFile("com.google.android.apps.foo", "Test.class", "test file contents")
        .build();

    AarGeneratorAction.writeAar(aar,
        aarData.data,
        aarData.manifest,
        aarData.rtxt,
        aarData.classes,
        aarData.proguardSpecs);

    // verify aar archive
    Set<String> zipEntries = getZipEntries(aar);
    assertThat(zipEntries).contains("res/");
    assertThat(zipEntries).contains("assets/");
  }

  @Test public void testMissingManifest() throws Exception {
    Path aar = tempDir.resolve("foo.aar");
    AarData aarData = new AarData.Builder(tempDir.resolve("data"))
        .createRtxt("R.txt",
            "int string app_name 0x7f050001",
            "int string hello_world 0x7f050002")
        .addResource("values/ids.xml",
            AarData.ResourceType.VALUE,
            "<item name=\"id_name\" type=\"id\"/>")
        .addAsset("some/other/ft/data.txt", "bar")
        .createClassesJar("classes.jar")
        .addClassesFile("com.google.android.apps.foo", "Test.class", "test file contents")
        .build();

    thrown.expect(IOException.class);
    thrown.expectMessage(containsString("fake-manifest-path"));
    AarGeneratorAction.writeAar(aar,
        aarData.data,
        aarData.manifest,
        aarData.rtxt,
        aarData.classes,
        aarData.proguardSpecs);
  }

  @Test public void testMissingRtxt() throws Exception {
    Path aar = tempDir.resolve("foo.aar");
    AarData aarData = new AarData.Builder(tempDir.resolve("data"))
        .createManifest("AndroidManifest.xml", "com.google.android.apps.foo.d1", "")
        .addResource("values/ids.xml",
            AarData.ResourceType.VALUE,
            "<item name=\"id_name\" type=\"id\"/>")
        .addAsset("some/other/ft/data.txt", "bar")
        .createClassesJar("classes.jar")
        .addClassesFile("com.google.android.apps.foo", "Test.class", "test file contents")
        .build();

    thrown.expect(IOException.class);
    thrown.expectMessage(containsString("fake-rtxt-path"));
    AarGeneratorAction.writeAar(aar,
        aarData.data,
        aarData.manifest,
        aarData.rtxt,
        aarData.classes,
        aarData.proguardSpecs);
  }

  @Test public void testMissingClasses() throws Exception {
    Path aar = tempDir.resolve("foo.aar");
    AarData aarData = new AarData.Builder(tempDir.resolve("data"))
        .createManifest("AndroidManifest.xml", "com.google.android.apps.foo.d1", "")
        .createRtxt("R.txt",
            "int string app_name 0x7f050001",
            "int string hello_world 0x7f050002")
        .addResource("values/ids.xml",
            AarData.ResourceType.VALUE,
            "<item name=\"id_name\" type=\"id\"/>")
        .addAsset("some/other/ft/data.txt", "bar")
        .build();

    thrown.expect(IOException.class);
    thrown.expectMessage(containsString("fake-classes-path"));
    AarGeneratorAction.writeAar(aar,
        aarData.data,
        aarData.manifest,
        aarData.rtxt,
        aarData.classes,
        aarData.proguardSpecs);
  }

  @Test public void testMissingResources() throws Exception {
    Path aar = tempDir.resolve("foo.aar");
    AarData aarData = new AarData.Builder(tempDir.resolve("data"))
        .createManifest("AndroidManifest.xml", "com.google.android.apps.foo.d1", "")
        .createRtxt("R.txt",
            "int string app_name 0x7f050001",
            "int string hello_world 0x7f050002")
        .addAsset("some/other/ft/data.txt", "bar")
        .createClassesJar("classes.jar")
        .addClassesFile("com.google.android.apps.foo", "Test.class", "test file contents")
        .build();

    thrown.expect(IOException.class);
    thrown.expectMessage(containsString("res"));
    AarGeneratorAction.writeAar(aar,
        aarData.data,
        aarData.manifest,
        aarData.rtxt,
        aarData.classes,
        aarData.proguardSpecs);
  }

  @Test public void testEmptyResources() throws Exception {
    Path aar = tempDir.resolve("foo.aar");
    AarData aarData = new AarData.Builder(tempDir.resolve("data"))
        .createManifest("AndroidManifest.xml", "com.google.android.apps.foo.d1", "")
        .createRtxt("R.txt",
            "int string app_name 0x7f050001",
            "int string hello_world 0x7f050002")
        .withEmptyResources(true)
        .addResource("values/ids.xml",
            AarData.ResourceType.VALUE,
            "<item name=\"id_name\" type=\"id\"/>")
        .addAsset("some/other/ft/data.txt", "bar")
        .createClassesJar("classes.jar")
        .addClassesFile("com.google.android.apps.foo", "Test.class", "test file contents")
        .build();

    AarGeneratorAction.writeAar(aar,
        aarData.data,
        aarData.manifest,
        aarData.rtxt,
        aarData.classes,
        aarData.proguardSpecs);
  }

  @Test public void testMissingAssets() throws Exception {
    Path aar = tempDir.resolve("foo.aar");
    AarData aarData = new AarData.Builder(tempDir.resolve("data"))
        .createManifest("AndroidManifest.xml", "com.google.android.apps.foo.d1", "")
        .createRtxt("R.txt",
            "int string app_name 0x7f050001",
            "int string hello_world 0x7f050002")
        .addResource("values/ids.xml",
            AarData.ResourceType.VALUE,
            "<item name=\"id_name\" type=\"id\"/>")
        .createClassesJar("classes.jar")
        .addClassesFile("com.google.android.apps.foo", "Test.class", "test file contents")
        .build();

    AarGeneratorAction.writeAar(aar,
        aarData.data,
        aarData.manifest,
        aarData.rtxt,
        aarData.classes,
        aarData.proguardSpecs);
  }

  @Test public void testEmptyAssets() throws Exception {
    Path aar = tempDir.resolve("foo.aar");
    AarData aarData = new AarData.Builder(tempDir.resolve("data"))
        .createManifest("AndroidManifest.xml", "com.google.android.apps.foo.d1", "")
        .createRtxt("R.txt",
            "int string app_name 0x7f050001",
            "int string hello_world 0x7f050002")
        .addResource("values/ids.xml",
            AarData.ResourceType.VALUE,
            "<item name=\"id_name\" type=\"id\"/>")
        .withEmptyAssets(true)
        .createClassesJar("classes.jar")
        .addClassesFile("com.google.android.apps.foo", "Test.class", "test file contents")
        .build();

    AarGeneratorAction.writeAar(aar,
        aarData.data,
        aarData.manifest,
        aarData.rtxt,
        aarData.classes,
        aarData.proguardSpecs);
  }

  @Test public void testFullIntegration() throws Exception {
    Path aar = tempDir.resolve("foo.aar");
    AarData aarData = new AarData.Builder(tempDir.resolve("data"))
        .createManifest("AndroidManifest.xml", "com.google.android.apps.foo", "")
        .createRtxt("R.txt",
            "int string app_name 0x7f050001",
            "int string hello_world 0x7f050002")
        .addResource("values/ids.xml",
            AarData.ResourceType.VALUE,
            "<item name=\"id\" type=\"id\"/>")
        .addResource("layout/layout.xml",
            AarData.ResourceType.LAYOUT,
            "<TextView android:id=\"@+id/text2\""
                + " android:layout_width=\"wrap_content\""
                + " android:layout_height=\"wrap_content\""
                + " android:text=\"Hello, I am a TextView\" />")
        .addAsset("some/other/ft/data.txt",
            "foo")
        .createClassesJar("classes.jar")
        .addClassesFile("com.google.android.apps.foo", "Test.class", "test file contents")
        .build();

    MergedAndroidData md1 = new AarData.Builder(tempDir.resolve("d1"))
        .addResource("values/ids.xml",
            AarData.ResourceType.VALUE,
            "<item name=\"id\" type=\"id\"/>")
        .addResource("layout/foo.xml",
            AarData.ResourceType.LAYOUT,
            "<TextView android:id=\"@+id/text\""
                + " android:layout_width=\"wrap_content\""
                + " android:layout_height=\"wrap_content\""
                + " android:text=\"Hello, I am a TextView\" />")
        .addAsset("some/other/ft/data1.txt",
            "bar")
        .createManifest("AndroidManifest.xml", "com.google.android.apps.foo.d1", "")
        .build().data;

    MergedAndroidData md2 = new AarData.Builder(tempDir.resolve("d2"))
        .addResource("values/ids.xml",
            AarData.ResourceType.VALUE,
            "<item name=\"id2\" type=\"id\"/>")
        .addResource("layout/bar.xml",
            AarData.ResourceType.LAYOUT,
            "<TextView android:id=\"@+id/textbar\""
                + " android:layout_width=\"wrap_content\""
                + " android:layout_height=\"wrap_content\""
                + " android:text=\"Hello, I am a TextView\" />")
        .addResource("drawable-mdpi/icon.png",
            AarData.ResourceType.UNFORMATTED,
            "Thttpt.")
        .addResource("drawable-xxxhdpi/icon.png",
            AarData.ResourceType.UNFORMATTED,
            "Double Thttpt.")
        .addAsset("some/other/ft/data2.txt",
            "foo")
        .createManifest("AndroidManifest.xml", "com.google.android.apps.foo.d2", "")
        .build().data;

    UnvalidatedAndroidData primary = new UnvalidatedAndroidData(
        ImmutableList.of(aarData.data.getResourceDir()),
        ImmutableList.of(aarData.data.getAssetDir()),
        aarData.data.getManifest());

    DependencyAndroidData d1 =
        new DependencyAndroidData(
            ImmutableList.of(md1.getResourceDir()),
            ImmutableList.of(md1.getAssetDir()),
            md1.getManifest(),
            null,
            null,
            null);

    DependencyAndroidData d2 =
        new DependencyAndroidData(
            ImmutableList.of(md2.getResourceDir()),
            ImmutableList.of(md2.getAssetDir()),
            md2.getManifest(),
            null,
            null,
            null);

    Path working = tempDir;

    Path resourcesOut = working.resolve("resources");
    Path assetsOut = working.resolve("assets");

    MergedAndroidData mergedData =
        AndroidResourceMerger.mergeDataAndWrite(
            primary,
            ImmutableList.of(d1, d2),
            ImmutableList.<DependencyAndroidData>of(),
            resourcesOut,
            assetsOut,
            VariantTypeImpl.LIBRARY,
            null,
            /* filteredResources= */ ImmutableList.of(),
            true);

    AarGeneratorAction.writeAar(
        aar, mergedData, aarData.manifest, aarData.rtxt, aarData.classes, aarData.proguardSpecs);

    // verify aar archive
    Set<String> zipEntries = getZipEntries(aar);
    assertThat(zipEntries).containsExactly(
        "AndroidManifest.xml",
        "R.txt",
        "classes.jar",
        "res/",
        "res/values/",
        "res/values/values.xml",
        "res/layout/",
        "res/layout/layout.xml",
        "res/layout/foo.xml",
        "res/layout/bar.xml",
        "res/drawable-mdpi-v4/",
        "res/drawable-mdpi-v4/icon.png",
        "res/drawable-xxxhdpi-v4/",
        "res/drawable-xxxhdpi-v4/icon.png",
        "assets/",
        "assets/some/",
        "assets/some/other/",
        "assets/some/other/ft/",
        "assets/some/other/ft/data.txt",
        "assets/some/other/ft/data1.txt",
        "assets/some/other/ft/data2.txt");
  }

  @Test public void testProguardSpecs() throws Exception {
    Path aar = tempDir.resolve("foo.aar");
    AarData aarData =
        new AarData.Builder(tempDir.resolve("data"))
            .createManifest("AndroidManifest.xml", "com.google.android.apps.foo.d1", "")
            .createRtxt("R.txt", "")
            .withEmptyResources(true)
            .withEmptyAssets(true)
            .createClassesJar("classes.jar")
            .addProguardSpec("spec1", "foo", "bar")
            .addProguardSpec("spec2", "baz")
            .build();

    AarGeneratorAction.writeAar(
        aar,
        aarData.data,
        aarData.manifest,
        aarData.rtxt,
        aarData.classes,
        aarData.proguardSpecs);
    Set<String> zipEntries = getZipEntries(aar);
    assertThat(zipEntries).contains("proguard.txt");
    List<String> proguardTxtContents = null;
    try (ZipReader aarReader = new ZipReader(aar.toFile())) {
      try (BufferedReader entryReader =
          new BufferedReader(
              new InputStreamReader(
                  aarReader.getInputStream(aarReader.getEntry("proguard.txt")),
                  StandardCharsets.UTF_8))) {
        proguardTxtContents = entryReader.lines().collect(Collectors.toList());
      }
    }
    assertThat(proguardTxtContents).containsExactly("foo", "bar", "baz").inOrder();
  }
}
