// Tom Robinson
// Kris Kowal

var INFLATE = require("./inflate");
var Buffer = require("buffer").Buffer;

var LOCAL_FILE_HEADER = 0x04034b50;
var CENTRAL_DIRECTORY_FILE_HEADER = 0x02014b50;
var END_OF_CENTRAL_DIRECTORY_RECORD = 0x06054b50;

var Reader = exports.Reader = function (data) {
    if (!(this instanceof Reader))
        return new Reader(data);
    this._data = data;
    this._offset = 0;
}

Reader.prototype.length = function () {
    return this._data.length;
}

Reader.prototype.position = function () {
    return this._offset;
}

Reader.prototype.seek = function (offset) {
    this._offset = offset;
}

Reader.prototype.read = function (length) {
    var bytes = this._data.slice(this._offset, this._offset+length);
    this._offset += length;
    return bytes;
}

Reader.prototype.readInteger = function (length, bigEndian) {
    if (bigEndian)
        return bytesToNumberBE(this.read(length));
    else
        return bytesToNumberLE(this.read(length));
}

Reader.prototype.readString = function (length, charset) {
    return this.read(length).toString(charset || "UTF-8");
}

Reader.prototype.readUncompressed = function (length, method) {
    var compressed = this.read(length);
    var uncompressed = null;
    if (method === 0)
        uncompressed = compressed;
    else if (method === 8)
        uncompressed = INFLATE.inflate(compressed);
    else
        throw new Error("Unknown compression method: " + structure.compression_method);
    return uncompressed;
}

Reader.prototype.readStructure = function () {
    var stream = this;
    var structure = {};
    
    // local file header signature     4 bytes  (0x04034b50)
    structure.signature = stream.readInteger(4);
    
    switch (structure.signature) {
        case LOCAL_FILE_HEADER :
            this.readLocalFileHeader(structure);
            break;
        case CENTRAL_DIRECTORY_FILE_HEADER :
            this.readCentralDirectoryFileHeader(structure);
            break;
        case END_OF_CENTRAL_DIRECTORY_RECORD :
            this.readEndOfCentralDirectoryRecord(structure);
            break;
        default:
            throw new Error("Unknown ZIP structure signature: 0x" + structure.signature.toString(16));
    }
    
    return structure;
}

// ZIP local file header
// Offset   Bytes   Description
// 0        4       Local file header signature = 0x04034b50
// 4        2       Version needed to extract (minimum)
// 6        2       General purpose bit flag
// 8        2       Compression method
// 10       2       File last modification time
// 12       2       File last modification date
// 14       4       CRC-32
// 18       4       Compressed size
// 22       4       Uncompressed size
// 26       2       File name length (n)
// 28       2       Extra field length (m)
// 30       n       File name
// 30+n     m       Extra field
Reader.prototype.readLocalFileHeader = function (structure) {
    var stream = this;
    structure = structure || {};

    if (!structure.signature)
        structure.signature = stream.readInteger(4);    // Local file header signature = 0x04034b50

    if (structure.signature !== LOCAL_FILE_HEADER)
        throw new Error("ZIP local file header signature invalid (expects 0x04034b50, actually 0x" + structure.signature.toString(16) +")");
        
    structure.version_needed       = stream.readInteger(2);    // Version needed to extract (minimum)
    structure.flags                = stream.readInteger(2);    // General purpose bit flag
    structure.compression_method   = stream.readInteger(2);    // Compression method
    structure.last_mod_file_time   = stream.readInteger(2);    // File last modification time
    structure.last_mod_file_date   = stream.readInteger(2);    // File last modification date
    structure.crc_32               = stream.readInteger(4);    // CRC-32
    structure.compressed_size      = stream.readInteger(4);    // Compressed size
    structure.uncompressed_size    = stream.readInteger(4);    // Uncompressed size
    structure.file_name_length     = stream.readInteger(2);    // File name length (n)
    structure.extra_field_length   = stream.readInteger(2);    // Extra field length (m)
    
    var n = structure.file_name_length;
    var m = structure.extra_field_length;
    
    structure.file_name            = stream.readString(n);     // File name
    structure.extra_field          = stream.read(m);           // Extra fieldFile name

    return structure;
}

// ZIP central directory file header
// Offset   Bytes   Description
// 0        4       Central directory file header signature = 0x02014b50
// 4        2       Version made by
// 6        2       Version needed to extract (minimum)
// 8        2       General purpose bit flag
// 10       2       Compression method
// 12       2       File last modification time
// 14       2       File last modification date
// 16       4       CRC-32
// 20       4       Compressed size
// 24       4       Uncompressed size
// 28       2       File name length (n)
// 30       2       Extra field length (m)
// 32       2       File comment length (k)
// 34       2       Disk number where file starts
// 36       2       Internal file attributes
// 38       4       External file attributes
// 42       4       Relative offset of local file header
// 46       n       File name
// 46+n     m       Extra field
// 46+n+m   k       File comment
Reader.prototype.readCentralDirectoryFileHeader = function (structure) {
    var stream = this;
    structure = structure || {};

    if (!structure.signature)
        structure.signature = stream.readInteger(4); // Central directory file header signature = 0x02014b50

    if (structure.signature !== CENTRAL_DIRECTORY_FILE_HEADER)
        throw new Error("ZIP central directory file header signature invalid (expects 0x04034b50, actually 0x" + structure.signature.toString(16) +")");
        
    structure.version                   = stream.readInteger(2);    // Version made by
    structure.version_needed            = stream.readInteger(2);    // Version needed to extract (minimum)
    structure.flags                     = stream.readInteger(2);    // General purpose bit flag
    structure.compression_method        = stream.readInteger(2);    // Compression method
    structure.last_mod_file_time        = stream.readInteger(2);    // File last modification time
    structure.last_mod_file_date        = stream.readInteger(2);    // File last modification date
    structure.crc_32                    = stream.readInteger(4);    // CRC-32
    structure.compressed_size           = stream.readInteger(4);    // Compressed size
    structure.uncompressed_size         = stream.readInteger(4);    // Uncompressed size
    structure.file_name_length          = stream.readInteger(2);    // File name length (n)
    structure.extra_field_length        = stream.readInteger(2);    // Extra field length (m)
    structure.file_comment_length       = stream.readInteger(2);    // File comment length (k)
    structure.disk_number               = stream.readInteger(2);    // Disk number where file starts
    structure.internal_file_attributes  = stream.readInteger(2);    // Internal file attributes
    structure.external_file_attributes  = stream.readInteger(4);    // External file attributes
    structure.local_file_header_offset  = stream.readInteger(4);    // Relative offset of local file header
    
    var n = structure.file_name_length;
    var m = structure.extra_field_length;
    var k = structure.file_comment_length;
    
    structure.file_name                 = stream.readString(n);     // File name
    structure.extra_field               = stream.read(m);           // Extra field
    structure.file_comment              = stream.readString(k);     // File comment

    return structure;
}

// finds the end of central directory record
// I'd like to slap whoever thought it was a good idea to put a variable length comment field here
Reader.prototype.locateEndOfCentralDirectoryRecord = function () {
    var length = this.length();
    var minPosition = length - Math.pow(2, 16) - 22;

    var position = length - 22 + 1;
    while (--position) {
        if (position < minPosition)
            throw new Error("Unable to find end of central directory record");

        this.seek(position);
        var possibleSignature = this.readInteger(4);
        if (possibleSignature !== END_OF_CENTRAL_DIRECTORY_RECORD)
            continue;

        this.seek(position + 20);
        var possibleFileCommentLength = this.readInteger(2);
        if (position + 22 + possibleFileCommentLength === length)
            break;
    }

    this.seek(position);
    return position;
};

// ZIP end of central directory record
// Offset   Bytes   Description
// 0        4       End of central directory signature = 0x06054b50
// 4        2       Number of this disk
// 6        2       Disk where central directory starts
// 8        2       Number of central directory records on this disk
// 10       2       Total number of central directory records
// 12       4       Size of central directory (bytes)
// 16       4       Offset of start of central directory, relative to start of archive
// 20       2       ZIP file comment length (n)
// 22       n       ZIP file comment
Reader.prototype.readEndOfCentralDirectoryRecord = function (structure) {
    var stream = this;
    structure = structure || {};

    if (!structure.signature)
        structure.signature = stream.readInteger(4); // End of central directory signature = 0x06054b50

    if (structure.signature !== END_OF_CENTRAL_DIRECTORY_RECORD)
        throw new Error("ZIP end of central directory record signature invalid (expects 0x04034b50, actually 0x" + structure.signature.toString(16) +")");
        
    structure.disk_number               = stream.readInteger(2);    // Number of this disk
    structure.central_dir_disk_number   = stream.readInteger(2);    // Disk where central directory starts
    structure.central_dir_disk_records  = stream.readInteger(2);    // Number of central directory records on this disk
    structure.central_dir_total_records = stream.readInteger(2);    // Total number of central directory records
    structure.central_dir_size          = stream.readInteger(4);    // Size of central directory (bytes)
    structure.central_dir_offset        = stream.readInteger(4);    // Offset of start of central directory, relative to start of archive
    structure.file_comment_length       = stream.readInteger(2);    // ZIP file comment length (n)

    var n = structure.file_comment_length;

    structure.file_comment              = stream.readString(n);     // ZIP file comment
    
    return structure;
}

Reader.prototype.readDataDescriptor = function () {
    var stream = this;
    var descriptor = {};

    descriptor.crc_32 = stream.readInteger(4);
    if (descriptor.crc_32 === 0x08074b50)
        descriptor.crc_32 = stream.readInteger(4); // CRC-32

    descriptor.compressed_size          = stream.readInteger(4);    // Compressed size
    descriptor.uncompressed_size        = stream.readInteger(4);    // Uncompressed size

    return descriptor;
}

Reader.prototype.iterator = function () {
    var stream = this;
    
    // find the end record and read it
    stream.locateEndOfCentralDirectoryRecord();
    var endRecord = stream.readEndOfCentralDirectoryRecord();
    
    // seek to the beginning of the central directory
    stream.seek(endRecord.central_dir_offset);
    
    var count = endRecord.central_dir_disk_records;

    return {
        next: function () {
            if ((count--) === 0)
                throw "stop-iteration";

            // read the central directory header
            var centralHeader = stream.readCentralDirectoryFileHeader();

            // save our new position so we can restore it
            var saved = stream.position();

            // seek to the local header and read it
            stream.seek(centralHeader.local_file_header_offset);
            var localHeader = stream.readLocalFileHeader();

            var uncompressed = null;
            if (localHeader.file_name.slice(-1) !== "/") {
                uncompressed = stream.readUncompressed(centralHeader.compressed_size, centralHeader.compression_method);
            }

            // seek back to the next central directory header
            stream.seek(saved);

            return new Entry(localHeader, uncompressed);
        }
    };
};

Reader.prototype.forEach = function (block, context) {
    var iterator = this.iterator();
    var next;
    while (true) {
        try {
            next = iterator.next();
        } catch (exception) {
            if (exception === "stop-iteration")
                break;
            if (exception === "skip-iteration")
                continue;
            throw exception;
        }
        block.call(context, next);
    }
};

Reader.prototype.toObject = function (charset) {
    var object = {};
    this.forEach(function (entry) {
        if (entry.isFile()) {
            var data = entry.getData();
            if (charset)
                data = data.toString(charset);
            object[entry.getName()] = data;
        }
    });
    return object;
};

Reader.prototype.close = function (mode, options) {
};

var Entry = exports.Entry = function (header, stream) {
    this._header = header;
    this._stream = stream;
};

Entry.prototype.getName = function () {
    return this._header.file_name;
};

Entry.prototype.isFile = function () {
    return !this.isDirectory();
};

Entry.prototype.isDirectory = function () {
    return this.getName().slice(-1) === "/";
};

Entry.prototype.getData = function () {
    return this._stream;
};

var bytesToNumberLE = function (bytes) {
    var acc = 0;
    for (var i = 0; i < bytes.length; i++)
        acc += bytes.get(i) << (8*i);
    return acc;
};
 
var bytesToNumberBE = function (bytes) {
    var acc = 0;
    for (var i = 0; i < bytes.length; i++)
        acc = (acc << 8) + bytes.get(i);
    return acc;
};

var numberToBytesLE = function (number, length) {
    var bytes = [];
    for (var i = 0; i < length; i++)
        bytes[i] = (number >> (8*i)) & 0xFF;
    return new Buffer(bytes);
};

var numberToBytesBE = function (number, length) {
    var bytes = [];
    for (var i = 0; i < length; i++)
        bytes[length-i-1] = (number >> (8*i)) & 0xFF;
    return new Buffer(bytes);
};

