#include "private.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#include <utils/Compat.h>

enum {
    // finding the directory
    CD_SIGNATURE = 0x06054b50,
    EOCD_LEN     = 22,        // EndOfCentralDir len, excl. comment
    MAX_COMMENT_LEN = 65535,
    MAX_EOCD_SEARCH = MAX_COMMENT_LEN + EOCD_LEN,

    // central directory entries
    ENTRY_SIGNATURE = 0x02014b50,
    ENTRY_LEN = 46,          // CentralDirEnt len, excl. var fields

    // local file header
    LFH_SIZE = 30,
};

unsigned int
read_le_int(const unsigned char* buf)
{
    return buf[0] | (buf[1] << 8) | (buf[2] << 16) | (buf[3] << 24);
}

unsigned int
read_le_short(const unsigned char* buf)
{
    return buf[0] | (buf[1] << 8);
}

static int
read_central_dir_values(Zipfile* file, const unsigned char* buf, int len)
{
    if (len < EOCD_LEN) {
        // looks like ZIP file got truncated
        fprintf(stderr, " Zip EOCD: expected >= %d bytes, found %d\n",
                EOCD_LEN, len);
        return -1;
    }

    file->disknum = read_le_short(&buf[0x04]);
    file->diskWithCentralDir = read_le_short(&buf[0x06]);
    file->entryCount = read_le_short(&buf[0x08]);
    file->totalEntryCount = read_le_short(&buf[0x0a]);
    file->centralDirSize = read_le_int(&buf[0x0c]);
    file->centralDirOffest = read_le_int(&buf[0x10]);
    file->commentLen = read_le_short(&buf[0x14]);

    if (file->commentLen > 0) {
        if (EOCD_LEN + file->commentLen > len) {
            fprintf(stderr, "EOCD(%d) + comment(%d) exceeds len (%d)\n",
                    EOCD_LEN, file->commentLen, len);
            return -1;
        }
        file->comment = buf + EOCD_LEN;
    }

    return 0;
}

static int
read_central_directory_entry(Zipfile* file, Zipentry* entry,
                const unsigned char** buf, ssize_t* len)
{
    const unsigned char* p;

    unsigned short  extraFieldLength;
    unsigned short  fileCommentLength;
    unsigned long   localHeaderRelOffset;
    unsigned int dataOffset;

    p = *buf;

    if (*len < ENTRY_LEN) {
        fprintf(stderr, "cde entry not large enough\n");
        return -1;
    }

    if (read_le_int(&p[0x00]) != ENTRY_SIGNATURE) {
        fprintf(stderr, "Whoops: didn't find expected signature\n");
        return -1;
    }

    entry->compressionMethod = read_le_short(&p[0x0a]);
    entry->compressedSize = read_le_int(&p[0x14]);
    entry->uncompressedSize = read_le_int(&p[0x18]);
    entry->fileNameLength = read_le_short(&p[0x1c]);
    extraFieldLength = read_le_short(&p[0x1e]);
    fileCommentLength = read_le_short(&p[0x20]);
    localHeaderRelOffset = read_le_int(&p[0x2a]);

    p += ENTRY_LEN;

    // filename
    if (entry->fileNameLength != 0) {
        entry->fileName = p;
    } else {
        entry->fileName = NULL;
    }
    p += entry->fileNameLength;

    // extra field
    p += extraFieldLength;

    // comment, if any
    p += fileCommentLength;

    *buf = p;

    // the size of the extraField in the central dir is how much data there is,
    // but the one in the local file header also contains some padding.
    p = file->buf + localHeaderRelOffset;
    extraFieldLength = read_le_short(&p[0x1c]);

    dataOffset = localHeaderRelOffset + LFH_SIZE
        + entry->fileNameLength + extraFieldLength;
    entry->data = file->buf + dataOffset;
#if 0
    printf("file->buf=%p entry->data=%p dataOffset=%x localHeaderRelOffset=%d "
           "entry->fileNameLength=%d extraFieldLength=%d\n",
           file->buf, entry->data, dataOffset, localHeaderRelOffset,
           entry->fileNameLength, extraFieldLength);
#endif
    return 0;
}

/*
 * Find the central directory and read the contents.
 *
 * The fun thing about ZIP archives is that they may or may not be
 * readable from start to end.  In some cases, notably for archives
 * that were written to stdout, the only length information is in the
 * central directory at the end of the file.
 *
 * Of course, the central directory can be followed by a variable-length
 * comment field, so we have to scan through it backwards.  The comment
 * is at most 64K, plus we have 18 bytes for the end-of-central-dir stuff
 * itself, plus apparently sometimes people throw random junk on the end
 * just for the fun of it.
 *
 * This is all a little wobbly.  If the wrong value ends up in the EOCD
 * area, we're hosed.  This appears to be the way that everbody handles
 * it though, so we're in pretty good company if this fails.
 */
int
read_central_dir(Zipfile *file)
{
    int err;

    const unsigned char* buf = file->buf;
    ZD_TYPE bufsize = file->bufsize;
    const unsigned char* eocd;
    const unsigned char* p;
    const unsigned char* start;
    ssize_t len;
    int i;

    // too small to be a ZIP archive?
    if (bufsize < EOCD_LEN) {
        fprintf(stderr, "Length is " ZD " -- too small\n", bufsize);
        goto bail;
    }

    // find the end-of-central-dir magic
    if (bufsize > MAX_EOCD_SEARCH) {
        start = buf + bufsize - MAX_EOCD_SEARCH;
    } else {
        start = buf;
    }
    p = buf + bufsize - 4;
    while (p >= start) {
        if (*p == 0x50 && read_le_int(p) == CD_SIGNATURE) {
            eocd = p;
            break;
        }
        p--;
    }
    if (p < start) {
        fprintf(stderr, "EOCD not found, not Zip\n");
        goto bail;
    }

    // extract eocd values
    err = read_central_dir_values(file, eocd, (buf+bufsize)-eocd);
    if (err != 0) {
        goto bail;
    }

    if (file->disknum != 0
          || file->diskWithCentralDir != 0
          || file->entryCount != file->totalEntryCount) {
        fprintf(stderr, "Archive spanning not supported\n");
        goto bail;
    }

    // Loop through and read the central dir entries.
    p = buf + file->centralDirOffest;
    len = (buf+bufsize)-p;
    for (i=0; i < file->totalEntryCount; i++) {
        Zipentry* entry = malloc(sizeof(Zipentry));
        memset(entry, 0, sizeof(Zipentry));

        err = read_central_directory_entry(file, entry, &p, &len);
        if (err != 0) {
            fprintf(stderr, "read_central_directory_entry failed\n");
            free(entry);
            goto bail;
        }

        // add it to our list
        entry->next = file->entries;
        file->entries = entry;
    }

    return 0;
bail:
    return -1;
}
