var __read = (this && this.__read) || function (o, n) {
    var m = typeof Symbol === "function" && o[Symbol.iterator];
    if (!m) return o;
    var i = m.call(o), r, ar = [], e;
    try {
        while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
    }
    catch (error) { e = { error: error }; }
    finally {
        try {
            if (r && !r.done && (m = i["return"])) m.call(i);
        }
        finally { if (e) throw e.error; }
    }
    return ar;
};
var __spread = (this && this.__spread) || function () {
    for (var ar = [], i = 0; i < arguments.length; i++) ar = ar.concat(__read(arguments[i]));
    return ar;
};
import Promise from 'bluebird';
import JSZip from 'jszip';
import { readFileAsArrayBuffer } from './utils';
// Valid file type.
function isValidImageType(fileName) {
    var name = fileName.split('/');
    name = name[name.length - 1];
    return (/\.(vs|fs|json)$/i).test(fileName)
        && !/__MACOSX/.test(fileName) && !/^\.[\s\S]*/.test(name);
}
function isMacZip(zipFiles) {
    return Object.keys(zipFiles).filter(function (item) {
        return /__MACOSX/.test(zipFiles[item].name);
    }).length > 0;
}
function getContents(zipFiles) {
    var contents = Object.keys(zipFiles).filter(function (item) {
        var zipEntry = zipFiles[item];
        return !zipEntry.dir && !/__MACOSX/.test(zipEntry.name);
    }).map(function (item) {
        // const zip_entry = zipFiles[item];
        var lastInd = item.lastIndexOf('/') + 1;
        var r = item.slice(0, lastInd);
        return r;
    });
    contents = __spread(new Set(contents));
    return contents;
}
function getContentsHash(contentArr) {
    // TODO 完善获取 hash 值，目前只获取一层
    var contentHash = {};
    contentArr.forEach(function (item, index) {
        var content = item.split('/');
        if (content[0] === '' || content[0] === '<fixed_zh_cn>') {
            content.splice(0, 1);
        }
        if (content.length >= 2 && content[1] !== '') {
            contentHash[content[1]] = index + 1;
        }
        else {
            contentHash[content[0]] = 0;
        }
    });
    return contentHash;
}
var UnCompress = /** @class */ (function () {
    function UnCompress() {
        this.archives = [];
    }
    UnCompress.prototype.archiveOpenFile = function (file, password, options) {
        var _this = this;
        var fileName = file.name;
        return readFileAsArrayBuffer(file).then(function (buffer) {
            var isZip = _this.isZipFile(buffer);
            var zipHandle;
            var entries;
            if (isZip) {
                try {
                    zipHandle = _this.zipOpen(fileName, password, buffer, options);
                    entries = _this.zipGetEntries(zipHandle, options);
                }
                catch (error) {
                    throw new Error('Failed to open archive.');
                }
            }
            else {
                throw new Error('不支持的文件格式');
            }
            // Sort the entries by name
            entries = entries.then(function (_a) {
                var isMacZip = _a.isMacZip, list = _a.list;
                var res = list.sort(function (a, b) {
                    if (a.name < b.name)
                        return -1;
                    if (a.name > b.name)
                        return 1;
                    return 0;
                });
                return {
                    isMacZip: isMacZip,
                    list: res,
                };
            }).then(function (_a) {
                var list = _a.list, isMacZip = _a.isMacZip;
                return Promise.map(list, function (i) {
                    if (i.name.indexOf('<fixed_zh_cn>') !== -1) {
                        var name_1 = i.name.substr('<fixed_zh_cn>'.length);
                        i.name = isMacZip ? "cp866" + name_1 : "cp936" + name_1;
                    }
                    i.size = i.size_uncompressed;
                    return i.readData().then(function (buffer) {
                        return {
                            buffer: buffer,
                            name: i.name,
                        };
                    });
                });
            });
            return {
                fileName: fileName,
                buffer: buffer,
                entries: entries,
                handle: zipHandle,
            };
        });
    };
    UnCompress.prototype.zipGetEntries = function (zipHandle, options) {
        return zipHandle.zip.then(function (zip) {
            // Get all the entries
            var entries = {
                isMacZip: false,
                list: [],
            };
            var contents = options && options.rememberDeep > 1 ? getContents(zip.files) : [];
            var contentsHash = contents ? getContentsHash(contents) : {};
            entries.isMacZip = isMacZip(zip.files);
            Object.keys(zip.files).forEach(function (i) {
                var zipEntry = zip.files[i];
                // const name = zip_entry.name;
                var isFile = !zipEntry.dir;
                var sizeCompressed = zipEntry._data ? zipEntry._data.compressedSize : 0;
                var sizeUncompressed = zipEntry._data ? zipEntry._data.uncompressedSize : 0;
                var contentTemp = zipEntry.name.split('/');
                if (contentTemp[0] === '' || contentTemp[0] === '<fixed_zh_cn>') {
                    contentTemp.splice(0, 1);
                }
                var imageGroup = isFile
                    && contentTemp.length >= 3 ? contentsHash[contentTemp[1]] : 0;
                if (isValidImageType(zipEntry.name)) {
                    entries.list.push({
                        imageGroup: imageGroup,
                        name: contentTemp[contentTemp.length - 1],
                        is_file: isFile,
                        size_compressed: sizeCompressed,
                        size_uncompressed: sizeUncompressed,
                        readData: function () {
                            if (isFile) {
                                return zipEntry.async('arraybuffer');
                            }
                            return new Promise.resolve('It is not a file.');
                        },
                    });
                }
            });
            zip.files = null;
            return entries;
        });
    };
    UnCompress.prototype.zipOpen = function (fileName, password, buffer, options) {
        // fix 中文编码导致图片丢失问题 http://stuk.github.io/jszip/documentation/api_jszip/load_async.html
        var zip = JSZip.loadAsync(buffer);
        return {
            fileName: fileName,
            buffer: buffer,
            password: password,
            zip: zip,
        };
    };
    UnCompress.prototype.saneJoin = function (array, separator) {
        var retval = '';
        for (var i = 0; i < array.length; i += 1) {
            if (i === 0) {
                retval += array[i];
            }
            else {
                retval += separator + array[i];
            }
        }
        return retval;
    };
    UnCompress.prototype.isZipFile = function (buffer) {
        // The ZIP header
        var zipHeader = this.saneJoin([0x50, 0x4b, 0x03, 0x04], ', ');
        // Just return false if the file is smaller than the header
        if (buffer.byteLength < 4) {
            return false;
        }
        // Return true if the header matches the ZIP header
        var header = this.saneJoin(new Uint8Array(buffer).slice(0, 4), ', ');
        return (header === zipHeader);
    };
    return UnCompress;
}());
export default UnCompress;
