/*
 * Copyright 2013-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.io.MoreFiles;
import com.facebook.buck.io.MorePosixFilePermissions;
import com.google.common.collect.ImmutableList;
import com.google.common.io.ByteStreams;

import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
import org.apache.commons.compress.archivers.zip.ZipFile;

import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.attribute.PosixFilePermission;
import java.util.Enumeration;
import java.util.Set;

public class Unzip {

  /** Utility class: do not instantiate. */
  private Unzip() {}


  /**
   * Unzips a file to a destination and returns the paths of the written files.
   */
  public static ImmutableList<Path> extractZipFile(
      Path zipFile,
      Path destination,
      boolean overwriteExistingFiles) throws IOException {
    // Create output directory if it does not exist
    Files.createDirectories(destination);

    ImmutableList.Builder<Path> filesWritten = ImmutableList.builder();
    try (ZipFile zip = new ZipFile(zipFile.toFile())) {
      Enumeration<ZipArchiveEntry> entries = zip.getEntries();
      while (entries.hasMoreElements()) {
        ZipArchiveEntry entry = entries.nextElement();
        String fileName = entry.getName();
        Path target = destination.resolve(fileName);
        if (Files.exists(target) && !overwriteExistingFiles) {
          continue;
        }

        // TODO(mbolin): Keep track of which directories have already been written to avoid
        // making unnecessary Files.createDirectories() calls. In practice, a single zip file will
        // have many entries in the same directory.

        if (entry.isDirectory()) {
          // Create the directory and all its parent directories
          Files.createDirectories(target);
        } else {
          // Create parent folder
          Files.createDirectories(target.getParent());

          filesWritten.add(target);
          // Write file
          try (FileOutputStream out = new FileOutputStream(target.toFile())) {
            ByteStreams.copy(zip.getInputStream(entry), out);
          }

          // TODO(simons): Implement what the comment below says we should do.
          //
          // Sets the file permissions of the output file given the information in {@code entry}'s
          // extra data field. According to the docs at
          // http://www.opensource.apple.com/source/zip/zip-6/unzip/unzip/proginfo/extra.fld there
          // are two extensions that might support file permissions: Acorn and ASi UNIX. We shall
          // assume that inputs are not from an Acorn SparkFS. The relevant section from the docs:
          //
          // <pre>
          //    The following is the layout of the ASi extra block for Unix.  The
          //    local-header and central-header versions are identical.
          //    (Last Revision 19960916)
          //
          //    Value         Size        Description
          //    -----         ----        -----------
          //   (Unix3) 0x756e        Short       tag for this extra block type ("nu")
          //   TSize         Short       total data size for this block
          //   CRC           Long        CRC-32 of the remaining data
          //   Mode          Short       file permissions
          //   SizDev        Long        symlink'd size OR major/minor dev num
          //   UID           Short       user ID
          //   GID           Short       group ID
          //   (var.)        variable    symbolic link filename
          //
          //   Mode is the standard Unix st_mode field from struct stat, containing
          //   user/group/other permissions, setuid/setgid and symlink info, etc.
          // </pre>
          //
          // From the stat man page, we see that the following mask values are defined for the file
          // permissions component of the st_mode field:
          //
          // <pre>
          //   S_ISUID   0004000   set-user-ID bit
          //   S_ISGID   0002000   set-group-ID bit (see below)
          //   S_ISVTX   0001000   sticky bit (see below)
          //
          //   S_IRWXU     00700   mask for file owner permissions
          //
          //   S_IRUSR     00400   owner has read permission
          //   S_IWUSR     00200   owner has write permission
          //   S_IXUSR     00100   owner has execute permission
          //
          //   S_IRWXG     00070   mask for group permissions
          //   S_IRGRP     00040   group has read permission
          //   S_IWGRP     00020   group has write permission
          //   S_IXGRP     00010   group has execute permission
          //
          //   S_IRWXO     00007   mask for permissions for others
          //   (not in group)
          //   S_IROTH     00004   others have read permission
          //   S_IWOTH     00002   others have write permission
          //   S_IXOTH     00001   others have execute permission
          // </pre>
          //
          // For the sake of our own sanity, we're going to assume that no-one is using symlinks,
          // but we'll check and throw if they are.
          //
          // Before we do anything, we should check the header ID. Pfft!
          //
          // Having jumped through all these hoops, it turns out that InfoZIP's "unzip" store the
          // values in the external file attributes of a zip entry (found in the zip's central
          // directory) assuming that the OS creating the zip was one of an enormous list that
          // includes UNIX but not Windows, it first searches for the extra fields, and if not found
          // falls through to a code path that supports MS-DOS and which stores the UNIX file
          // attributes in the upper 16 bits of the external attributes field.
          //
          // We'll support neither approach fully, but we encode whether this file was executable
          // via storing 0100 in the fields that are typically used by zip implementations to store
          // POSIX permissions. If we find it was executable, use the platform independent java
          // interface to make this unpacked file executable.

          Set<PosixFilePermission> permissions =
              MorePosixFilePermissions.fromMode(entry.getExternalAttributes() >> 16);
          if (permissions.contains(PosixFilePermission.OWNER_EXECUTE)) {
            MoreFiles.makeExecutable(target.toFile());
          }

        }
      }
    }
    return filesWritten.build();
  }

}
