#include "private.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.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  versionMadeBy;
    unsigned short  versionToExtract;
    unsigned short  gpBitFlag;
    unsigned short  compressionMethod;
    unsigned short  lastModFileTime;
    unsigned short  lastModFileDate;
    unsigned long   crc32;
    unsigned long   compressedSize;
    unsigned long   uncompressedSize;
    unsigned short  extraFieldLength;
    unsigned short  fileCommentLength;
    unsigned short  diskNumberStart;
    unsigned short  internalAttrs;
    unsigned long   externalAttrs;
    unsigned long   localHeaderRelOffset;
    const unsigned char*  extraField;
    const unsigned char*  fileComment;
    unsigned int dataOffset;
    unsigned short lfhExtraFieldSize;
    

    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;
    }

    versionMadeBy = read_le_short(&p[0x04]);
    versionToExtract = read_le_short(&p[0x06]);
    gpBitFlag = read_le_short(&p[0x08]);
    entry->compressionMethod = read_le_short(&p[0x0a]);
    lastModFileTime = read_le_short(&p[0x0c]);
    lastModFileDate = read_le_short(&p[0x0e]);
    crc32 = read_le_int(&p[0x10]);
    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]);
    diskNumberStart = read_le_short(&p[0x22]);
    internalAttrs = read_le_short(&p[0x24]);
    externalAttrs = read_le_int(&p[0x26]);
    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
    if (extraFieldLength != 0) {
        extraField = p;
    } else {
        extraField = NULL;
    }
    p += extraFieldLength;

    // comment, if any
    if (fileCommentLength != 0) {
        fileComment = p;
    } else {
        fileComment = NULL;
    }
    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;
    ssize_t 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 %d -- 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, sizeof(Zipentry), 0);

        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;
}

