/*
 * 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.google.common.base.Charsets;

import java.io.IOException;
import java.io.OutputStream;
import java.util.zip.ZipEntry;

/**
 * Each zip file has a "central directory" at the end of the archive, which provides the indexes
 * required for fast random access to the contents of the zip. This class models that.
 * <p>
 * The central directory consists of a series of "file headers", describing each entry in the zip,
 * and a "end of central directory" signature containing book keeping information.
 */
class CentralDirectory {

  /**
   * Write the entire central directory, including the file headers and the end of central directory
   * signature.
   *
   * @param out The stream to output to.
   * @param startOffset The number of bytes offset within the zip file that this starts at.
   * @param entries The entries that are contained within the zip.
   * @throws IOException Should something go awry.
   */
  public void writeCentralDirectory(
      OutputStream out,
      long startOffset,
      Iterable<EntryAccounting> entries) throws IOException {

    int entryCount = 0;
    long size = 0;
    for (EntryAccounting entry : entries) {
      entryCount++;
      size += writeCentralDirectoryFileHeader(out, entry);
    }

    // End of central directory

    ByteIo.writeInt(out, ZipEntry.ENDSIG);

    ByteIo.writeShort(out, 0);  // Number of this disk (with end of central directory)
    ByteIo.writeShort(out, 0);  // Number of disk on which central directory starts.
    ByteIo.writeShort(out, entryCount);  // Number of central directory entries in this disk.
    ByteIo.writeShort(out, entryCount);  // Number of central directory entries.
    ByteIo.writeInt(out, size);  // Size of the central directory in bytes.
    ByteIo.writeInt(out, startOffset);    // Offset of the start of the central directory.
    ByteIo.writeShort(out, 0);  // Size of the comment (we don't have one)
  }

  /**
   * Each entry requires a description of that entry to be contained in the central directory.
   */
  private long writeCentralDirectoryFileHeader(
      OutputStream out,
      EntryAccounting entry) throws IOException {
    long size = 0;
    size += ByteIo.writeInt(out, ZipEntry.CENSIG);
    size += ByteIo.writeShort(out, entry.getRequiredExtractVersion());  // version made by.
    size += ByteIo.writeShort(out, entry.getRequiredExtractVersion());  // version to extract with.
    size += ByteIo.writeShort(out, entry.getFlags());
    size += ByteIo.writeShort(out, entry.getCompressionMethod());  // Compression.
    size += ByteIo.writeInt(out, entry.getTime());      // Modification time.
    size += ByteIo.writeInt(out, entry.getCrc());
    size += ByteIo.writeInt(out, entry.getCompressedSize());
    size += ByteIo.writeInt(out, entry.getSize());

    byte[] nameBytes = entry.getName().getBytes(Charsets.UTF_8);
    size += ByteIo.writeShort(out, nameBytes.length);  // Length of name.
    size += ByteIo.writeShort(out, 0);                 // Length of extra data.
    size += ByteIo.writeShort(out, 0);                 // Length of file comment.
    size += ByteIo.writeShort(out, 0);                 // Disk on which file starts.
    size += ByteIo.writeShort(out, 0);                 // internal file attributes (unknown)
    size += ByteIo.writeInt(out, 0);                   // external file attributes (unknown)
    size += ByteIo.writeInt(out, entry.getOffset());   // Offset of local file header.
    out.write(nameBytes);
    size += nameBytes.length;

    return size;
  }
}
