"use strict";

Object.defineProperty(exports, "__esModule", {
    value: true
});
exports.readAsarJson = exports.readAsar = exports.AsarFilesystem = exports.Node = undefined;

var _bluebirdLst;

function _load_bluebirdLst() {
    return _bluebirdLst = require("bluebird-lst");
}

let readAsar = exports.readAsar = (() => {
    var _ref = (0, (_bluebirdLst || _load_bluebirdLst()).coroutine)(function* (archive) {
        const fd = yield (0, (_fsExtraP || _load_fsExtraP()).open)(archive, "r");
        let size;
        let headerBuf;
        try {
            const sizeBuf = Buffer.allocUnsafe(8);
            if ((yield (0, (_fsExtraP || _load_fsExtraP()).read)(fd, sizeBuf, 0, 8, null)) !== 8) {
                throw new Error("Unable to read header size");
            }
            const sizePickle = (0, (_chromiumPickleJs || _load_chromiumPickleJs()).createFromBuffer)(sizeBuf);
            size = sizePickle.createIterator().readUInt32();
            headerBuf = Buffer.allocUnsafe(size);
            if ((yield (0, (_fsExtraP || _load_fsExtraP()).read)(fd, headerBuf, 0, size, null)) !== size) {
                throw new Error("Unable to read header");
            }
        } finally {
            yield (0, (_fsExtraP || _load_fsExtraP()).close)(fd);
        }
        const headerPickle = (0, (_chromiumPickleJs || _load_chromiumPickleJs()).createFromBuffer)(headerBuf);
        const header = headerPickle.createIterator().readString();
        return new AsarFilesystem(archive, JSON.parse(header), size);
    });

    return function readAsar(_x5) {
        return _ref.apply(this, arguments);
    };
})();

let readAsarJson = exports.readAsarJson = (() => {
    var _ref2 = (0, (_bluebirdLst || _load_bluebirdLst()).coroutine)(function* (archive, file) {
        const fs = yield readAsar(archive);
        return yield fs.readJson(file);
    });

    return function readAsarJson(_x6, _x7) {
        return _ref2.apply(this, arguments);
    };
})();

let readFileFromAsar = (() => {
    var _ref3 = (0, (_bluebirdLst || _load_bluebirdLst()).coroutine)(function* (filesystem, filename, info) {
        const buffer = Buffer.allocUnsafe(info.size);
        if (info.size <= 0) {
            return buffer;
        }
        if (info.unpacked) {
            return yield (0, (_fsExtraP || _load_fsExtraP()).readFile)(_path.join(`${filesystem.src}.unpacked`, filename));
        }
        const fd = yield (0, (_fsExtraP || _load_fsExtraP()).open)(filesystem.src, "r");
        try {
            const offset = 8 + filesystem.headerSize + parseInt(info.offset, 10);
            yield (0, (_fsExtraP || _load_fsExtraP()).read)(fd, buffer, 0, info.size, offset);
        } finally {
            yield (0, (_fsExtraP || _load_fsExtraP()).close)(fd);
        }
        return buffer;
    });

    return function readFileFromAsar(_x8, _x9, _x10) {
        return _ref3.apply(this, arguments);
    };
})();
//# sourceMappingURL=asar.js.map


var _chromiumPickleJs;

function _load_chromiumPickleJs() {
    return _chromiumPickleJs = require("chromium-pickle-js");
}

var _fsExtraP;

function _load_fsExtraP() {
    return _fsExtraP = require("fs-extra-p");
}

var _path = _interopRequireWildcard(require("path"));

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }

const UINT64 = require("cuint").UINT64;
/** @internal */
class Node {}
exports.Node = Node; /** @internal */

class AsarFilesystem {
    constructor(src) {
        let header = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : new Node();
        let headerSize = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : -1;

        this.src = src;
        this.header = header;
        this.headerSize = headerSize;
        this.offset = UINT64(0);
        if (this.header.files == null) {
            this.header.files = {};
        }
    }
    searchNodeFromDirectory(p, isCreate) {
        let node = this.header;
        for (const dir of p.split(_path.sep)) {
            if (dir !== ".") {
                let child = node.files[dir];
                if (child == null) {
                    if (!isCreate) {
                        return null;
                    }
                    child = new Node();
                    child.files = {};
                    node.files[dir] = child;
                }
                node = child;
            }
        }
        return node;
    }
    getOrCreateNode(p) {
        if (p == null || p.length === 0) {
            return this.header;
        }
        const name = _path.basename(p);
        const dirNode = this.searchNodeFromDirectory(_path.dirname(p), true);
        if (dirNode.files == null) {
            dirNode.files = {};
        }
        let result = dirNode.files[name];
        if (result == null) {
            result = new Node();
            dirNode.files[name] = result;
        }
        return result;
    }
    addFileNode(file, dirNode, size, unpacked, stat) {
        if (size > 4294967295) {
            throw new Error(`${file}: file size cannot be larger than 4.2GB`);
        }
        const node = new Node();
        node.size = size;
        if (unpacked) {
            node.unpacked = true;
        } else {
            node.offset = this.offset.toString();
            if (process.platform !== "win32" && stat.mode & 0o100) {
                node.executable = true;
            }
            this.offset.add(UINT64(node.size));
        }
        let children = dirNode.files;
        if (children == null) {
            children = {};
            dirNode.files = children;
        }
        children[_path.basename(file)] = node;
        return node;
    }
    insertDirectory(p) {
        let unpacked = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;

        const node = this.getOrCreateNode(p);
        node.files = {};
        if (unpacked) {
            node.unpacked = unpacked;
        }
        return node.files;
    }
    getNode(p) {
        const node = this.searchNodeFromDirectory(_path.dirname(p), false);
        return node.files[_path.basename(p)];
    }
    getFile(p) {
        let followLinks = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;

        const info = this.getNode(p);
        // if followLinks is false we don't resolve symlinks
        return followLinks && info.link != null ? this.getFile(info.link) : info;
    }
    readJson(file) {
        var _this = this;

        return (0, (_bluebirdLst || _load_bluebirdLst()).coroutine)(function* () {
            return JSON.parse((yield _this.readFile(file)).toString());
        })();
    }
    readFile(file) {
        var _this2 = this;

        return (0, (_bluebirdLst || _load_bluebirdLst()).coroutine)(function* () {
            return yield readFileFromAsar(_this2, file, _this2.getFile(file));
        })();
    }
}
exports.AsarFilesystem = AsarFilesystem;