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

import com.facebook.buck.step.ExecutionContext;
import com.facebook.buck.step.Step;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.hash.HashCode;
import com.google.common.hash.Hashing;
import com.google.common.io.ByteStreams;
import com.google.common.io.Files;

import java.io.File;
import java.io.IOException;
import java.util.Map;
import java.util.Set;
import java.util.zip.ZipEntry;

/**
 * Command to zip up a directory while respecting a file size limit to be deflated.
 * <p>
 * Currently, Froyo has a limitation where it will not deflate files out of a zip if the inflated
 * size exceeds 1 MiB (1 << 20 bytes).  This utility is useful for including assets into the APK
 * where we deflate those that we can, and store the ones we can't.
 */
public class ZipDirectoryWithMaxDeflateStep implements Step {

  /**
   * Extensions of files we don't want to DEFLATE (e.g. already compressed).
   */
  private final Set<String> EXTENSIONS_NOT_TO_DEFLATE = ImmutableSet.of(
      "gzip",
      "jar",
      "jpg",
      "png",
      "xz"
  );

  private final String inputDirectoryPath;
  private final String outputZipPath;
  private final long maxDeflatedBytes;

  public ZipDirectoryWithMaxDeflateStep(String inputDirectoryPath, String outputZipPath) {
    this(inputDirectoryPath, outputZipPath, 0);
  }

  public ZipDirectoryWithMaxDeflateStep(String inputDirectoryPath,
                                        String outputZipPath,
                                        long maxDeflatedBytes) {
    Preconditions.checkState(maxDeflatedBytes >= 0);

    this.maxDeflatedBytes = maxDeflatedBytes;
    this.inputDirectoryPath = Preconditions.checkNotNull(inputDirectoryPath);
    this.outputZipPath = Preconditions.checkNotNull(outputZipPath);
  }

  @Override
  public int execute(ExecutionContext context) {
    File inputDirectory = new File(inputDirectoryPath);
    Preconditions.checkState(inputDirectory.exists() && inputDirectory.isDirectory(),
        "%s must be a directory.",
        inputDirectoryPath);

    try {
      ImmutableMap.Builder<File, ZipEntry> zipEntriesBuilder = ImmutableMap.builder();
      addDirectoryToZipEntryList(inputDirectory, "", zipEntriesBuilder);
      ImmutableMap<File, ZipEntry> zipEntries = zipEntriesBuilder.build();

      if (!zipEntries.isEmpty()) {
        try (CustomZipOutputStream outputStream =
                 ZipOutputStreams.newOutputStream(new File(outputZipPath))
        ) {
          for (Map.Entry<File, ZipEntry> zipEntry : zipEntries.entrySet()) {
            outputStream.putNextEntry(zipEntry.getValue());
            ByteStreams.copy(Files.newInputStreamSupplier(zipEntry.getKey()), outputStream);
            outputStream.closeEntry();
          }
        }
      }
    } catch (IOException e) {
      e.printStackTrace(context.getStdErr());
      return 1;
    }
    return 0;
  }

  private void addDirectoryToZipEntryList(File directory,
                                 String currentPath,
                                 ImmutableMap.Builder<File, ZipEntry> zipEntriesBuilder)
      throws IOException {
    Preconditions.checkNotNull(currentPath);

    for (File inputFile : directory.listFiles()) {
      String childPath = currentPath +
          (currentPath.isEmpty() ? "" : "/") +
          inputFile.getName();

      if (inputFile.isDirectory()) {
        addDirectoryToZipEntryList(inputFile, childPath, zipEntriesBuilder);
      } else {
        ZipEntry nextEntry = new ZipEntry(childPath);
        long fileLength = inputFile.length();
        if (fileLength > maxDeflatedBytes ||
            EXTENSIONS_NOT_TO_DEFLATE.contains(Files.getFileExtension(inputFile.getName()))) {
          nextEntry.setMethod(ZipEntry.STORED);
          nextEntry.setCompressedSize(inputFile.length());
          nextEntry.setSize(inputFile.length());
          HashCode crc = ByteStreams.hash(Files.newInputStreamSupplier(inputFile), Hashing.crc32());
          nextEntry.setCrc(crc.padToLong());
        }

        zipEntriesBuilder.put(inputFile, nextEntry);
      }
    }
  }

  @Override
  public String getShortName() {
    return "zip_directory";
  }

  @Override
  public String getDescription(ExecutionContext context) {
    return String.format("zip -r %s %s", outputZipPath, inputDirectoryPath);
  }
}
