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

import static org.junit.Assert.assertTrue;

import com.google.common.base.Predicate;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.LinkedHashMultimap;
import com.google.common.collect.Multimap;
import com.google.common.collect.Sets;

import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Collections;
import java.util.Set;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipOutputStream;

public class DefaultZipSplitterTest {

  @Rule
  public TemporaryFolder tmpDir = new TemporaryFolder();

  private File testInZip;
  private Set<File> testInZips;
  private File outPrimary;
  private String secondaryPattern;
  private Predicate<String> processor = new Predicate<String>() {
    @Override
    public boolean apply(String name) {
      return name.startsWith("primary");
    }
  };

  @Before
  public void setUp() throws Exception {
    byte[] fakeData = {0, 0, 0, 0};

    // Map of output file => [ zip entry, ... ]
    Multimap<File, String> outputToInputMap = LinkedHashMultimap.create();

    // Uber in zip for tests.
    testInZip = new File(tmpDir.getRoot(), "in.zip");
    outputToInputMap.putAll(testInZip, ImmutableList.of(
        "secondary-1",
        "secondary-2",
        "secondary-3",
        "primary",
        "secondary-4"));

    // Tests with multiple input zips.
    testInZips = Sets.newLinkedHashSet();
    File inA = new File(tmpDir.getRoot(), "in-a.zip");
    testInZips.add(inA);
    outputToInputMap.putAll(inA, ImmutableList.of(
        "primary-a-1",
        "primary-a-2",
        "primary-a-3",
        "secondary-a-1",
        "secondary-a-2",
        "secondary-a-3"));
    File inB = new File(tmpDir.getRoot(), "in-b.zip");
    testInZips.add(inB);
    outputToInputMap.putAll(inB, ImmutableList.of(
        "secondary-b-1",
        "secondary-b-2"));
    File inC = new File(tmpDir.getRoot(), "in-c.zip");
    testInZips.add(inC);
    outputToInputMap.putAll(inC, ImmutableList.of(
        "secondary-c-1",
        "secondary-c-2",
        "secondary-c-3"));

    // Write the output files.
    for (File outputFile : outputToInputMap.keySet()) {
      ZipOutputStream zipOut = new ZipOutputStream(new FileOutputStream(outputFile));
      for (String name : outputToInputMap.get(outputFile)) {
        zipOut.putNextEntry(new ZipEntry(name));
        zipOut.write(fakeData);
      }
      zipOut.close();
    }

    outPrimary = new File(tmpDir.getRoot(), "primary.zip");
    secondaryPattern = "secondary-%d.zip";
  }

  @Test
  public void testBigLimit() throws IOException {
    DefaultZipSplitter.splitZip(Collections.singleton(testInZip),
        outPrimary,
        tmpDir.getRoot(),
        secondaryPattern,
        999 /* soft limit */,
        999 /* hard limit */,
        processor,
        ZipSplitter.DexSplitStrategy.MAXIMIZE_PRIMARY_DEX_SIZE,
        ZipSplitter.CanaryStrategy.DONT_INCLUDE_CANARIES,
        tmpDir.newFolder("report"))
        .execute();
    assertTrue(primaryZipContains("primary"));
    assertTrue(primaryZipContains("secondary-1"));
    assertTrue(primaryZipContains("secondary-2"));
    assertTrue(primaryZipContains("secondary-3"));
    assertTrue(primaryZipContains("secondary-4"));
  }

  @Test
  public void testMediumLimit() throws IOException {
    DefaultZipSplitter.splitZip(Collections.singleton(testInZip),
        outPrimary,
        tmpDir.getRoot(),
        secondaryPattern,
        12 /* soft limit */,
        12 /* hard limit */,
        processor,
        ZipSplitter.DexSplitStrategy.MAXIMIZE_PRIMARY_DEX_SIZE,
        ZipSplitter.CanaryStrategy.DONT_INCLUDE_CANARIES,
        tmpDir.newFolder("report"))
        .execute();
    assertTrue(primaryZipContains("primary"));
    assertTrue(primaryZipContains("secondary-3"));
    assertTrue(primaryZipContains("secondary-4"));
    assertTrue(nthSecondaryZipContains(1, "secondary-1"));
    assertTrue(nthSecondaryZipContains(1, "secondary-2"));
  }

  @Test
  public void testSmallLimit() throws IOException {
    DefaultZipSplitter.splitZip(Collections.singleton(testInZip),
        outPrimary,
        tmpDir.getRoot(),
        secondaryPattern,
        8 /* soft limit */,
        8 /* hard limit */,
        processor,
        ZipSplitter.DexSplitStrategy.MAXIMIZE_PRIMARY_DEX_SIZE,
        ZipSplitter.CanaryStrategy.DONT_INCLUDE_CANARIES,
        tmpDir.newFolder("report"))
        .execute();
    assertTrue(primaryZipContains("primary"));
    assertTrue(primaryZipContains("secondary-4"));
    assertTrue(nthSecondaryZipContains(1, "secondary-1"));
    assertTrue(nthSecondaryZipContains(1, "secondary-2"));
    assertTrue(nthSecondaryZipContains(2, "secondary-3"));
  }

  @Test
  public void testBigLimitMinimizePrimaryZip() throws IOException {
    DefaultZipSplitter.splitZip(
        Collections.singleton(testInZip),
        outPrimary,
        tmpDir.getRoot(),
        secondaryPattern,
        999 /* soft limit */,
        999,
        processor,
        ZipSplitter.DexSplitStrategy.MINIMIZE_PRIMARY_DEX_SIZE,
        ZipSplitter.CanaryStrategy.DONT_INCLUDE_CANARIES,
        tmpDir.newFolder("report"))
        .execute();
    assertTrue(primaryZipContains("primary"));
    assertTrue(nthSecondaryZipContains(1, "secondary-1"));
    assertTrue(nthSecondaryZipContains(1, "secondary-2"));
    assertTrue(nthSecondaryZipContains(1, "secondary-3"));
    assertTrue(nthSecondaryZipContains(1, "secondary-4"));
  }

  @Test
  public void testMediumLimitMinimizePrimaryZip() throws IOException {
    DefaultZipSplitter.splitZip(
        Collections.singleton(testInZip),
        outPrimary,
        tmpDir.getRoot(),
        secondaryPattern,
        12 /* soft limit */,
        12,
        processor,
        ZipSplitter.DexSplitStrategy.MINIMIZE_PRIMARY_DEX_SIZE,
        ZipSplitter.CanaryStrategy.DONT_INCLUDE_CANARIES,
        tmpDir.newFolder("report"))
        .execute();
    assertTrue(primaryZipContains("primary"));
    assertTrue(nthSecondaryZipContains(1, "secondary-1"));
    assertTrue(nthSecondaryZipContains(1, "secondary-2"));
    assertTrue(nthSecondaryZipContains(1, "secondary-3"));
    assertTrue(nthSecondaryZipContains(2, "secondary-4"));
  }

  @Test
  public void testSmallLimitMinimizePrimaryZip() throws IOException {
    DefaultZipSplitter.splitZip(
        Collections.singleton(testInZip),
        outPrimary,
        tmpDir.getRoot(),
        secondaryPattern,
        8 /* soft limit */,
        8,
        processor,
        ZipSplitter.DexSplitStrategy.MINIMIZE_PRIMARY_DEX_SIZE,
        ZipSplitter.CanaryStrategy.DONT_INCLUDE_CANARIES,
        tmpDir.newFolder("report"))
        .execute();
    assertTrue(primaryZipContains("primary"));
    assertTrue(nthSecondaryZipContains(1, "secondary-1"));
    assertTrue(nthSecondaryZipContains(1, "secondary-2"));
    assertTrue(nthSecondaryZipContains(2, "secondary-3"));
    assertTrue(nthSecondaryZipContains(2, "secondary-4"));
  }

  @Test
  public void testSoftLimit() throws IOException {
    DefaultZipSplitter.splitZip(testInZips,
        outPrimary,
        tmpDir.getRoot(),
        secondaryPattern,
        8 /* soft limit */,
        12 /* hard limit */,
        processor,
        ZipSplitter.DexSplitStrategy.MAXIMIZE_PRIMARY_DEX_SIZE,
        ZipSplitter.CanaryStrategy.DONT_INCLUDE_CANARIES,
        tmpDir.newFolder("report"))
        .execute();
    assertTrue(primaryZipContains("primary-a-1"));
    assertTrue(primaryZipContains("primary-a-2"));
    assertTrue(primaryZipContains("primary-a-3"));
    assertTrue(nthSecondaryZipContains(1, "secondary-a-1"));
    assertTrue(nthSecondaryZipContains(1, "secondary-a-2"));
    assertTrue(nthSecondaryZipContains(1, "secondary-a-3"));
    assertTrue(nthSecondaryZipContains(2, "secondary-b-1"));
    assertTrue(nthSecondaryZipContains(2, "secondary-b-2"));
    assertTrue(nthSecondaryZipContains(3, "secondary-c-1"));
    assertTrue(nthSecondaryZipContains(3, "secondary-c-2"));
    assertTrue(nthSecondaryZipContains(3, "secondary-c-3"));
  }

  @Test
  public void testCanary() throws IOException {
    DefaultZipSplitter.splitZip(
        Collections.singleton(testInZip),
        outPrimary,
        tmpDir.getRoot(),
        secondaryPattern,
        80 /* soft limit */,
        80,
        processor,
        ZipSplitter.DexSplitStrategy.MINIMIZE_PRIMARY_DEX_SIZE,
        ZipSplitter.CanaryStrategy.INCLUDE_CANARIES,
        tmpDir.newFolder("report"))
        .execute();
    assertTrue(nthSecondaryZipContains(1, "secondary/dex01/Canary.class"));
    assertTrue(nthSecondaryZipContains(2, "secondary/dex02/Canary.class"));
    assertTrue(nthSecondaryZipContains(3, "secondary/dex03/Canary.class"));
    assertTrue(nthSecondaryZipContains(4, "secondary/dex04/Canary.class"));
  }

  private boolean primaryZipContains(String name) throws IOException {
    return zipContains(outPrimary, name);
  }

  private boolean nthSecondaryZipContains(int index, String name) throws IOException {
    String zipName = String.format(secondaryPattern, index);
    return zipContains(new File(tmpDir.getRoot(), zipName), name);
  }

  private static boolean zipContains(File file, String name) throws IOException {
    ZipFile zip = new ZipFile(file);
    try {
      return zip.getEntry(name) != null;
    } finally {
      zip.close();
    }
  }
}
