// Copyright 2015 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.ziputils;

import static com.google.devtools.build.android.ziputils.DataDescriptor.EXTLEN;
import static com.google.devtools.build.android.ziputils.DataDescriptor.EXTSIZ;
import static com.google.devtools.build.android.ziputils.DirectoryEntry.CENLEN;
import static com.google.devtools.build.android.ziputils.DirectoryEntry.CENOFF;
import static com.google.devtools.build.android.ziputils.DirectoryEntry.CENSIZ;
import static com.google.devtools.build.android.ziputils.EndOfCentralDirectory.ENDOFF;
import static com.google.devtools.build.android.ziputils.EndOfCentralDirectory.ENDSUB;

import com.google.common.primitives.UnsignedInts;
import com.google.errorprone.annotations.CanIgnoreReturnValue;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.channels.FileChannel;
import java.util.Map;

/**
 * API for reading a zip file. This does not perform decompression of entry data, but provides
 * a raw view of the content of a zip archive.
 */
public class ZipIn {

  private static final byte[] EOCD_SIG = {0x50, 0x4b, 0x05, 0x06};
  private static final byte[] HEADER_SIG = {0x50, 0x4b, 0x03, 0x04};
  private static final byte[] DATA_DESC_SIG = {0x50, 0x4b, 0x07, 0x08};


  /**
   * Max end-of-central-directory size, including variable length file comment..
   */
  private static final int MAX_EOCD_SIZE = 1024;

  /**
   * Max local file header size, including long filename.
   */
  private static final int MAX_HEADER_SIZE = 64 * 1024;

  /**
   * Default size of direct byte buffer used for reading content. Actual allocation will not
   * exceed the archive content size, and may be at least as big as the largest entry.
   */
  private static final int READ_BLOCK_SIZE = 20 * 1024 * 1024;

  private final String filename; // filename or nickname.
  private final FileChannel fileChannel; // input file.
  private BufferedFile bufferedFile;
  private CentralDirectory cdir = null;
  private EndOfCentralDirectory eocd = null;
  private final boolean useDirectory;
  private final boolean ignoreDeleted;
  private final boolean verbose = false;

  /**
   * Creates a {@code ZipIn} view of a file, with a (nick)name.
   *
   * @param channel File channel open for reading.
   * @param filename filename or nickname.
   */
  public ZipIn(FileChannel channel, String filename) {
    this.fileChannel = channel;
    this.filename = filename;
    this.useDirectory = true;
    this.ignoreDeleted = useDirectory;
  }

  /**
   * Gets the file name for this zip input file.
   * @return the filename set at time of construction.
   */
  public String getFilename() {
    return filename;
  }

  /**
   * Returns a view of the "end of central directory" record expected at (or towards) the end of a
   * zip file.
   *
   * @return A read-only, {@link EndOfCentralDirectory}.
   * @throws IOException
   */
  public EndOfCentralDirectory endOfCentralDirectory() throws IOException {
    if (eocd == null) {
      loadEndOfCentralDirectory();
    }
    return eocd;
  }

  /**
   * Returns a memory mapped view of the central directory.
   *
   * @return A read-only, {@link CentralDirectory} of the central directory.
   * @throws IOException
   */
  public CentralDirectory centralDirectory() throws IOException {
    if (cdir == null) {
      loadCentralDirectory();
    }
    return cdir;
  }

  /**
   * Scans all entries in the zip file and invokes the given {@link EntryHandler} on each.
   *
   * @param handler handler to invoke for each file entry.
   * @throws IOException
   */
  public void scanEntries(EntryHandler handler) throws IOException {
    centralDirectory();
    ZipEntry zipEntry = nextFrom(null);
    while (zipEntry.getCode() != ZipEntry.Status.ENTRY_NOT_FOUND) {
      if (zipEntry.getCode() != ZipEntry.Status.ENTRY_OK) {
        throw new IOException(zipEntry.getCode().toString());
      }
      handler.handle(this, zipEntry.getHeader(), zipEntry.getDirEntry(), zipEntry.getContent());
      if (useDirectory && ignoreDeleted) {
        zipEntry = ZipIn.this.nextFrom(zipEntry.getDirEntry());
      } else {
        zipEntry = nextFrom(zipEntry.limit());
      }
    }
  }

  /**
   * Finds the next header, by scanning for a local header signature starting
   * at {@code offset}. This method will find headers for deleted or updated entries that
   * are not listed in the central directory, and may pickup false positive (e.g. entries
   * of an embedded zip file stored without compression). This method is primarily intended
   * for applications trying to recover data from corrupt archives.
   *
   * @param offset offset where to start the search.
   * @return the next local header at or beyond {@code offset}, or {@code null} if no
   * header is found.
   * @throws IOException
   */
  public LocalFileHeader nextHeaderFrom(long offset) throws IOException {
    int skipped = 0;
    for (ByteBuffer buffer = getData(offset + skipped, MAX_HEADER_SIZE);
        buffer.limit() >= LocalFileHeader.SIZE;
        buffer = getData(offset + skipped, MAX_HEADER_SIZE)) {
      int markerOffset = ScanUtil.scanTo(HEADER_SIG, buffer);
      if (markerOffset < 0) {
        skipped += buffer.limit() - 3;
      } else {
        skipped += markerOffset;
        LocalFileHeader header =  markerOffset == 0 ? localHeaderIn(buffer, offset + skipped)
            : localHeaderAt(offset + skipped);
        if (header != null) {
          if (skipped > 0) {
            System.out.println("Warning: local header search: skipped " + skipped + " bytes");
          }
          return header;
        }
        // If localHeaderIn or localHeaderAt decided it is not a header location,
        // we continue the search.
        skipped += 4;
      }
    }
    return null;
  }

  /**
   * Finds the header at the next higher offset listed in the central directory as containing
   * a local file header, starting from the offset of the given {@code dirEntry}. This method will
   * bypass any deleted or updated entries not listed in the directory, and also any entries from
   * embedded zip files, or random instance of the header signature. This is the preferred method
   * for sequentially reading the entries of a valid zip file.
   *
   * @param dirEntry directory entry for the "current entry", providing the start point
   * for searching the central directory for the entry with the next higher offset.
   * @return the next header according to the central directory, or {@code null} if there are no
   * more headers.
   * @throws IOException
   */
  public LocalFileHeader nextHeaderFrom(DirectoryEntry dirEntry) throws IOException {
    Long nextOffset = dirEntry == null ? -1 : dirEntry.get(CENOFF);
    while ((nextOffset = cdir.mapByOffset().higherKey(nextOffset)) != null) {
      LocalFileHeader header = localHeaderAt(nextOffset);
      if (header != null) {
        return header;
      }
      System.out.println("Warning: no header for file listed in directory "
          + dirEntry.getFilename());
      // The file is corrupt! Continue to see how bad it is.
    }
    return null;
  }

  /**
   * Provides a {@code LocalFileHeader} view of a local header located at the offset indicated
   * by the given {@code dirEntry}.
   *
   * @param dirEntry the directory entry referring to the headers location.
   * @return the requested header, or {@code null} if the given location can't possibly contain a
   * valid file header (e.g. missing header signature), or if {@code dirEntry} is {@code null}.
   * @throws IOException
   */
  public LocalFileHeader localHeaderFor(DirectoryEntry dirEntry) throws IOException {
    return dirEntry == null ? null : localHeaderAt(dirEntry.get(CENOFF));
  }

  /**
   * Provides a {@code LocalFileHeader} view of a local header located at the offset indicated by
   * the given {@code dirEntry}.
   *
   * @param offset offset at which header is presumed to exist.
   * @return the requested header, or {@code null} if the given location can't possibly contain a
   *     valid file header (e.g. missing header signature).
   * @throws IOException
   */
  public LocalFileHeader localHeaderAt(long offset) throws IOException {
    return localHeaderIn(getData(offset, MAX_HEADER_SIZE), offset);
  }

  /**
   * Finds the next zip file entry, by scanning for a local header using the
   * {@link #nextHeaderFrom(long) }method.
   *
   * @param offset offset where to start the search.
   * @return a {@code ZipEntry} object with the result of the search.
   * @throws IOException
   */
  public ZipEntry nextFrom(long offset) throws IOException {
    LocalFileHeader header = ZipIn.this.nextHeaderFrom(offset);
    return entryWith(header);
  }

  /**
   * Finds the next zip file entry, by first invoking
   * {@link #nextHeaderFrom(com.google.devtools.build.android.ziputils.DirectoryEntry) }
   * to find its header.
   *
   * @param entry the directory entry for the "current" zip entry, or {@code null} to get
   * the first entry.
   * @return a {@code ZipEntry} object with the result of the search.
   * @throws IOException
   */
  public ZipEntry nextFrom(DirectoryEntry entry) throws IOException {
    long offset = entry == null ? -1 : entry.get(CENOFF);
    Map.Entry<Long, DirectoryEntry> mapEntry = cdir.mapByOffset().higherEntry(offset);
    if (mapEntry == null) {
      return entryWith(null);
    }
    LocalFileHeader header = localHeaderAt(mapEntry.getKey());
    return entryWith(header, mapEntry.getValue());
  }

  /**
   * Finds the zip file entry, for a given directory entry.
   *
   * @param entry the directory entry for which a zip entry is requested.
   * @return a {@code ZipEntry} object with the result of the search.
   * @throws IOException
   */
  public ZipEntry entryFor(DirectoryEntry entry) throws IOException {
    return entryWith(localHeaderFor(entry), entry);
  }

  /**
   * Returns the zip file entry at the given offset.
   *
   * @param offset presumed location of local file header.
   * @return a {@link ZipEntry} for the given location.
   * @throws IOException
   */
  public ZipEntry entryAt(long offset) throws IOException {
    LocalFileHeader header = localHeaderAt(offset);
    return entryWith(header);
  }

  /**
   * Constructs a {@link ZipEntry} view of the entry at the location of the given header.
   *
   * @param header a previously located header. If (@code useDirectory} is set, this will attempt to
   *     lookup a corresponding directory entry. If there is none, and {@code ignoreDeleted} is also
   *     set, the return value will flag this entry with a {@code ZipEntry.Status.ENTRY_NOT_FOUND}
   *     status code.
   * @return {@link ZipEntry} for the given location.
   * @throws IOException
   */
  public ZipEntry entryWith(LocalFileHeader header) throws IOException {
    if (header == null) {
      return new ZipEntry().withCode(ZipEntry.Status.ENTRY_NOT_FOUND);
    }
    // header != null
    long offset = header.fileOffset();
    DirectoryEntry dirEntry = null;
    if (useDirectory) {
      dirEntry = cdir.mapByOffset().get(offset);
      if (dirEntry == null && ignoreDeleted) {
        return new ZipEntry().withCode(ZipEntry.Status.ENTRY_DELETED);
      }
    }
    return entryWith(header, dirEntry);
  }

  /**
   * Constructs a zip entry object for the location of the given header, with the corresponding
   * directory entry.
   *
   * @param header local file header for the entry.
   * @param dirEntry corresponding directory entry, or {@code null} if not available.
   * @return a zip entry with the given header and directory entry.
   * @throws IOException
   */
  private ZipEntry entryWith(LocalFileHeader header, DirectoryEntry dirEntry) throws IOException {
    ZipEntry zipEntry = new ZipEntry().withHeader(header).withEntry(dirEntry);
    long offset = header.fileOffset() + header.getSize();
    // !useDirectory || dirEntry != null || !ignoreDeleted
    String entryName = header.getFilename();
    if (dirEntry != null && !entryName.equals(dirEntry.getFilename())) {
      return zipEntry.withEntry(dirEntry).withCode(ZipEntry.Status.FILENAME_ERROR);
    }
    long sizeByHeader = header.dataSize();
    long sizeByDir = dirEntry != null ? dirEntry.dataSize() : -1;
    ByteBuffer content;
    if (sizeByDir == sizeByHeader && sizeByDir >= 0) {
      // Ideal case, header and directory in agreement
      content = getData(offset, sizeByHeader);
      if (content.limit() == sizeByHeader) {
        return zipEntry.withContent(content).withCode(ZipEntry.Status.ENTRY_OK);
      } else {
        return zipEntry.withContent(content).withCode(ZipEntry.Status.NOT_ENOUGH_DATA);
      }
    }
    if (sizeByDir >= 0) {
      // If file is correct, we get here because of a 0x8 flag, and we expect
      // data to be followed by a data descriptor.
      content = getData(offset, sizeByDir);
      DataDescriptor dataDesc = descriptorAt(offset + sizeByDir, dirEntry);
      if (dataDesc != null) {
        return zipEntry
            .withContent(content)
            .withDescriptor(dataDesc)
            .withCode(ZipEntry.Status.ENTRY_OK);
      }
      return zipEntry.withContent(content).withCode(ZipEntry.Status.NO_DATA_DESC);
    }
    if (!ignoreDeleted) {
      if (sizeByHeader >= 0) {
        content = getData(offset, sizeByHeader);
        if (content.limit() == sizeByHeader) {
          return zipEntry.withContent(content).withCode(ZipEntry.Status.ENTRY_OK);
        }
        return zipEntry.withContent(content).withCode(ZipEntry.Status.NOT_ENOUGH_DATA);
      } else {

        DataDescriptor dataDesc = descriptorFrom(offset, dirEntry);
        if (dataDesc == null) {
          // Only way now would be to decompress
          return zipEntry.withCode(ZipEntry.Status.UNKNOWN_SIZE);
        }
        long sizeByDesc = dataDesc.get(EXTSIZ);
        if (sizeByDesc != dataDesc.fileOffset() - offset) {
          // That just can't be the right
          return zipEntry.withDescriptor(dataDesc).withCode(ZipEntry.Status.UNKNOWN_SIZE);
        }
        content = getData(offset, sizeByDesc);
        return zipEntry
            .withContent(content)
            .withDescriptor(dataDesc)
            .withCode(ZipEntry.Status.ENTRY_OK);
      }
    }
    return zipEntry.withCode(ZipEntry.Status.UNKNOWN_SIZE);
  }

  /**
   * Scans for a data descriptor from a given offset.
   *
   * @param offset position where to start the search.
   * @param dirEntry directory entry for validation, or {@code null}.
   * @return A data descriptor view for the next position containing the data descriptor signature.
   * @throws IOException
   */
  public DataDescriptor descriptorFrom(final long offset, final DirectoryEntry dirEntry)
      throws IOException {
    int skipped = 0;
    for (ByteBuffer buffer = getData(offset + skipped, MAX_HEADER_SIZE);
        buffer.limit() >= 16; buffer = getData(offset + skipped, MAX_HEADER_SIZE)) {
      int markerOffset = ScanUtil.scanTo(DATA_DESC_SIG, buffer);
      if (markerOffset < 0) {
        skipped += buffer.limit() - 3;
      } else {
        skipped += markerOffset;
        return markerOffset == 0 ? descriptorIn(buffer, offset + skipped, dirEntry)
            : descriptorAt(offset + skipped, dirEntry);
      }
    }
    return null;
  }

  /**
   * Creates a data descriptor view at a given offset.
   *
   * @param offset presumed location of data descriptor.
   * @param dirEntry directory entry to use for validation, or {@code null}.
   * @return a data descriptor view over the given file offset.
   * @throws IOException
   */
  public DataDescriptor descriptorAt(long offset, DirectoryEntry dirEntry) throws IOException {
    return descriptorIn(getData(offset, 16), offset, dirEntry);
  }

  /**
   * Constructs a local header view over a give byte buffer.
   *
   * @param buffer byte buffer with local header data.
   * @param offset file offset at which the buffer is based.
   * @return a local header view.
   */
  private LocalFileHeader localHeaderIn(ByteBuffer buffer, long offset) {
    return buffer.limit() < LocalFileHeader.SIZE
        || buffer.getInt(0) != LocalFileHeader.SIGNATURE
        ? null : LocalFileHeader.viewOf(buffer).at(offset);
  }

  /**
   * Constructs a data descriptor view over a given byte buffer.
   *
   * @param buf byte buffer with data descriptor data.
   * @param offset file offset at which the buffer is based.
   * @param dirEntry directory entry with presumed reliable content size information.
   * @return a data descriptor
   */
  private DataDescriptor descriptorIn(ByteBuffer buf, long offset, DirectoryEntry dirEntry) {
    if (buf.limit() < 12) {
      return null;
    }
    DataDescriptor desc = DataDescriptor.viewOf(buf).at(offset);
    if (desc.hasMarker() || (dirEntry != null
        && desc.get(EXTSIZ) == dirEntry.get(CENSIZ)
        && desc.get(EXTLEN) == dirEntry.get(CENLEN))) {
      return desc;
    }
    return null;
  }

  /** Obtains a byte buffer at a given offset. */
  private ByteBuffer getData(long offset, long size) throws IOException {
    return bufferedFile
        .getBuffer(offset, UnsignedInts.checkedCast(size))
        .order(ByteOrder.LITTLE_ENDIAN);
  }

  /**
   * Locates the "end of central directory" record, expected located at the end of the file, and
   * reads it into a byte buffer. Called on the first invocation of
   * {@link #endOfCentralDirectory() }.
   *
   * @throws IOException
   */
  protected void loadEndOfCentralDirectory() throws IOException {
    cdir = null;
    long size = fileChannel.size();
    verbose("Loading ZipIn: " + filename);
    verbose("-- size: " + size);
    int cap = (int) Math.min(size, MAX_EOCD_SIZE);
    ByteBuffer buffer = ByteBuffer.allocate(cap).order(ByteOrder.LITTLE_ENDIAN);
    long offset = size - cap;
    while (true) {
      fileChannel.position(offset);
      while (buffer.hasRemaining()) {
        fileChannel.read(buffer, offset);
      }
      // scan to find it...
      int endOfDirOffset = ScanUtil.scanBackwardsTo(EOCD_SIG, buffer);
      if (endOfDirOffset < 0) {
        if (offset == 0) {
          if (useDirectory) {
            throw new IllegalStateException("No end of central directory marker");
          } else {
            break;
          }
        }
        offset = Math.max(offset - 1000, 0);
        buffer.clear();
        continue;
      }
      long eocdFileOffset = offset + endOfDirOffset;
      verbose("-- EOCD: " + eocdFileOffset + " size: " + (size - eocdFileOffset));
      buffer.position(endOfDirOffset);
      eocd = EndOfCentralDirectory.viewOf(buffer).at(offset + endOfDirOffset);
      // TODO (bazel-team): check that the end of central directory, points to a valid
      // first directory entry. If not, assume we happened to find the signature inside
      // a file comment, and resume the search.
      break;
    }

    if (eocd != null) {
      bufferedFile = new BufferedFile(fileChannel, 0, eocd.get(ENDOFF),
          READ_BLOCK_SIZE);
    } else {
      bufferedFile = new BufferedFile(fileChannel, READ_BLOCK_SIZE);
    }
  }

  /**
   * Maps the central directory to memory. Called on the first invocation of
   * {@link #centralDirectory() }.
   *
   * @throws IOException
   */
  protected void loadCentralDirectory() throws IOException {
    if (eocd == null) {
      loadEndOfCentralDirectory();
    }
    if (eocd == null) {
      return;
    }
    long cdOffset = eocd.get(ENDOFF);
    long len = eocd.fileOffset() - cdOffset;
    verbose("-- CDIR: " + cdOffset + " size: " + len + " count: " + eocd.get(ENDSUB));
    // Read directory to buffer.
    // TODO(bazel-team): we currently assume the directory fits in memory (and int).
    ByteBuffer buffer = ByteBuffer.allocateDirect((int) len);
    while (len > 0) {
      int read = fileChannel.read(buffer, cdOffset);
      len -= read;
      cdOffset += read;
    }
    buffer.rewind();
    cdir = CentralDirectory.viewOf(buffer).at(cdOffset).parse();
    cdir.buffer.flip();
  }

  /**
   * Zip file entry container class, for use with the low-level scanning operations of this
   * API, supporting zip file scanner construction.
   */
  public static class ZipEntry {

    private LocalFileHeader header;
    private DataDescriptor descriptor;
    private ByteBuffer content;
    private DirectoryEntry entry;
    private Status code;

    /**
     * Creates a zip entry, setting the initial status to not found.
     */
    public ZipEntry() {
      code = Status.ENTRY_NOT_FOUND;
    }

    /**
     * Gets the header of this zip entry.
     */
    public LocalFileHeader getHeader() {
      return header;
    }

    /**
     * Sets the header of this zip entry.
     *
     * @return this object.
     */
    @CanIgnoreReturnValue
    public ZipEntry withHeader(LocalFileHeader header) {
      this.header = header;
      return this;
    }

    /**
     * Gets the data descriptor of this zip entry, if any.
     */
    public DataDescriptor getDescriptor() {
      return descriptor;
    }

    /**
     * Sets the data descriptor of this zip entry.
     *
     * @return this object.
     */
    @CanIgnoreReturnValue
    public ZipEntry withDescriptor(DataDescriptor descriptor) {
      this.descriptor = descriptor;
      return this;
    }

    /**
     * Gets a byte buffer for accessing the raw content of this zip entry.
     */
    public ByteBuffer getContent() {
      return content;
    }

    /**
     * Sets the byte buffer providing access to the raw content of this zip entry.
     *
     * @return this object
     */
    @CanIgnoreReturnValue
    public ZipEntry withContent(ByteBuffer content) {
      this.content = content;
      return this;
    }

    /**
     * Gets the central directory entry for this zip entry, if any.
     */
    public DirectoryEntry getDirEntry() {
      return entry;
    }

    /**
     * Sets the central directory entry for this zip entry.
     *
     * @return this object.
     */
    @CanIgnoreReturnValue
    public ZipEntry withEntry(DirectoryEntry entry) {
      this.entry = entry;
      return this;
    }

    /**
     * Gets the status code for parsing this zip entry.
     */
    public Status getCode() {
      return code;
    }

    /**
     * Sets the status code for this zip entry.
     *
     * @return this object.
     */
    @CanIgnoreReturnValue
    public ZipEntry withCode(Status code) {
      this.code = code;
      return this;
    }

    /**
     * Calculates, best-effort, the file offset just past this zip entry.
     */
    public long limit() {
      if (header == null) {
        return 0;
      }
      if (descriptor != null) {
        return descriptor.fileOffset() + descriptor.getSize();
      }
      long offset = header.fileOffset() + header.dataSize();
      if (content != null) {
        offset += content.limit();
      }
      return offset;
    }

    /**
     * Zip entry parsing status codes.
     */
    public enum Status {
      /**
       * This zip entry contains valid header and data
       */
      ENTRY_OK,
      /**
       * No header at the given location
       */
      ENTRY_NOT_FOUND,
      /**
       * The given location contains a header that is not listed in the central directory
       */
      ENTRY_DELETED,
      /**
       * The header in the given location has a different filename than the
       * directory entry for this location.
       */
      FILENAME_ERROR,
      /**
       * The given location has the header signature, but the remaining data is insufficient
       * to constitute a complete entry.
       */
      NOT_ENOUGH_DATA,
      /**
       * The entry appears to be missing an expected data descriptor.
       */
      NO_DATA_DESC,
      /**
       * The implementation was unable to determine the size of the content of the entry.
       * The client will have to either parse using the central directory, or if all else
       * fails, attempt to decompress the entry.
       */
      UNKNOWN_SIZE,
    }
  }

  private void verbose(String msg) {
    if (verbose) {
      System.out.println(msg);
    }
  }
}
