"use strict";

function time() {
    var a = process.hrtime();
    return 1e3 * a[0] + a[1] / 1e6;
}

function range(a, b) {
    var c = new Array(a);
    b = Number.isFinite(b) ? b : 0;
    for (var d = 0; d < a; d++) c[d] = d + b;
    return c;
}

function extractIpAddress(a) {
    if ("::1" === a) return "127.0.0.1";
    var b = a.match(/(\d+\.){3,3}\d+$/);
    return b && b[0] || "";
}

function rm(a) {
    return new Promise(function(b, c) {
        fs.existsSync(a) ? fs.unlink(a, function(a) {
            a ? c(a) : b();
        }) : b();
    });
}

function run(a, b) {
    return new Promise(function(c, d) {
        try {
            console.log("utils:run:" + a + " " + b.join(" "));
            var e = child_process_1.spawn(a, b);
            isFinite(e.pid) ? c(e) : e.on("error", d);
        } catch (f) {
            d(new Error("Not an execuatable: " + a));
        }
    });
}

function runAndWait(a, b, c) {
    return new Promise(function(d, e) {
        var f = [], g = [], h = b && ("string" == typeof b ? b.trim().split(/\s/) : b), i = child_process_1.spawn(a, h);
        console.log("run: " + a + " " + h.join(" ") + " , pid: " + i.pid), i.stdout.on("data", function(a) {
            return f.push("" + a);
        }), i.stderr.on("data", function(a) {
            return g.push("" + a);
        }), i.on("exit", function(j, k) {
            var l = {
                ok: 0 == j,
                code: j,
                signal: k,
                stdout: f.join(""),
                stderr: g.join("")
            };
            console.log("run: " + a + " " + h.join(" ") + " , exit:, pid: " + i.pid + ", code: " + j + ", signal:" + k + (j ? " , stderr: " + g : "")), 0 == j || c && c.permissive ? d(l) : e(Object.assign(new Error(a + " " + b + " , code=" + j + NaN + k + "\n" + g), l));
        }), i.on("error", function(a) {
            return e(a);
        }), c && c.stdinData && (i.stdin.write(c.stdinData), i.stdin.end());
    });
}

function isLocalAddress(a) {
    return !!a && (a.endsWith("127.0.0.1") || "::1" === a || "localhost" === a);
}

function monitorProc(a, b, c) {
    a.on("error", function() {
        console.error("[proc:" + b + "][E] exit!");
    }), c && a.stdout.on("data", function(a) {
        console.log("[proc:" + b + "] " + a + "\n");
    }), a.stderr.on("data", function(a) {
        console.error("[proc:" + b + "][E] " + a.toString() + "\n");
    });
}

function trapError(a, b) {
    var c = a.url, d = function(a) {
        return console.error("trapError:url=" + c, a);
    };
    a.on("error", d), b.on("error", d);
}

function getPathParts(a) {
    var b = mUrl.parse(a).pathname;
    try {
        b = decodeURI(b);
    } catch (c) {
        console.warn("getPathParts: decodeURI failed, use as-is: " + a, c);
    }
    return b.split("/").filter(function(a) {
        return !!a;
    });
}

function readStream(a, b) {
    return void 0 === b && (b = "string"), "string" !== b && "json" !== b || a.setEncoding("UTF-8"), new Promise(function(c, d) {
        var e = [], f = [];
        a.resume(), a.on("data", function(a) {
            "string" == typeof a ? e.push(a) : a.length && "buffers" === b && f.push(a);
        }), a.on("end", function() {
            try {
                if ("buffers" === b) c(f); else if ("string" === b) c(e.join()); else if ("json" === b) c(JSON.parse(e.join())); else {
                    if ("void" !== b) throw new TypeError("Not supported type: " + b);
                    c();
                }
            } catch (a) {
                d(a);
            }
        }), a.on("error", function(a) {
            d(a);
        });
    });
}

function readRequestBody(a, b) {
    return b || a.setEncoding("UTF-8"), new Promise(function(c, d) {
        var e = "", f = [];
        a.on("data", function(a) {
            "string" == typeof a ? e += a : a.length && f.push(a);
        }), a.on("end", function() {
            return c(b ? f : e);
        }), a.on("error", function(a) {
            console.error("readRequestBody:error:", a), d(a);
        });
    });
}

function sendBinaryBody(a, b) {
    var c = 0, d = function(e) {
        if (e || c >= b.length) e && console.log("sendBinaryBody:step:err:", e), a.end(); else {
            var f = b[c];
            c += 1, a.write(f, d);
        }
    };
    d();
}

function buffersLength(a) {
    return a.reduce(function(a, b) {
        return a + b.length;
    }, 0);
}

function createMainHandler(a) {
    function b(b, c) {
        console.log(b.method + " " + b.url + " , ip=" + b.socket.remoteAddress + ", remotePort=" + b.socket.remotePort);
        var d = getPathParts(b.url), e = (mUrl.parse(b.url), a[b.method]), f = e ? e[d[0]] : null;
        if (e && !f && (f = e["@default"]), f) {
            var g, h;
            try {
                g = f(b, c);
            } catch (i) {
                h = i;
            }
            (g || Promise.resolve())["catch"](function(a) {
                return h = a;
            }).then(function() {
                h && (console.error("onRequest: error: url= " + b.url + " , method=" + b.method, h), c.writeHead(h ? 500 : 200), c.end(h ? h + "" : "")), g && !c.headersSent && (c.writeHead(200), 
                c.end());
            });
        } else c.writeHead(404), c.end();
    }
    return b;
}

Object.defineProperty(exports, "__esModule", {
    value: !0
});

var child_process_1 = require("child_process"), mUrl = require("url"), fs = require("fs"), os_1 = require("os");

exports.time = time, exports.range = range, exports.extractIpAddress = extractIpAddress, exports.rm = rm, exports.run = run, exports.runAndWait = runAndWait, exports.isLocalAddress = isLocalAddress, 
exports.isLocalHost = function() {
    var a = os_1.networkInterfaces(), b = Date.now();
    return function(c) {
        var d = Date.now();
        if (d - b > 300 && (a = os_1.networkInterfaces(), b = d), "localhost" === c.toLowerCase()) return !0;
        for (var e in a) for (var f = a[e], g = 0, h = f; g < h.length; g++) {
            var i = h[g];
            if (i.address === c) return !0;
        }
        return !1;
    };
}(), exports.monitorProc = monitorProc, exports.trapError = trapError, exports.getPathParts = getPathParts, exports.readStream = readStream, exports.readRequestBody = readRequestBody, 
exports.sendBinaryBody = sendBinaryBody, exports.buffersLength = buffersLength;

var ProcWrapper = function() {
    function a(a, b, c) {
        this.name = a, this.cmd = b, this.args = c, this.logStdError = !0;
    }
    return a.prototype.start = function() {
        var a = this;
        return this.stop().then(function() {
            return run(a.cmd, a.args);
        }).then(function(b) {
            a.proc = b, a.pid = b.pid, b.on("exit", function(b, c) {
                console.log("ProcWrapper:start():on exit,name=" + a.name + ",pid=" + a.pid), a.killing || setImmediate(function() {
                    return a.onCrash(b, c);
                }), a.proc = null;
            }), a.logStdError && b.stderr.on("data", function(b) {
                console.warn("[ProcWrapper:" + a.name + "][" + a.pid + "][E] " + b.toString() + "\n");
            });
        }, function(b) {
            try {
                a.onError("start", b);
            } catch (c) {}
            throw b;
        });
    }, a.prototype.stop = function() {
        var a = this;
        return console.log("ProcWrapper:stop:name=" + this.name + ",pid=" + this.pid), this.isRunning ? this.killing ? this.killing : this.killing = new Promise(function(b, c) {
            a.proc.kill(), a.proc.on("exit", function(c, d) {
                console.log("ProcWrapper:stop:on exit,name=" + a.name + ",pid=" + a.pid), a.killing = null, setImmediate(function() {
                    return a.onStopped(c, d);
                }), b(d || c);
            }), a.proc.on("error", function(b) {
                console.error("ProcWrapper:failed to stop:name=" + a.name + ", error=", b), a.killing = null, setImmediate(function() {
                    return a.onError("stop", b);
                }), c(b);
            });
        }) : Promise.resolve(null);
    }, Object.defineProperty(a.prototype, "isRunning", {
        get: function() {
            return !!this.proc;
        },
        enumerable: !0,
        configurable: !0
    }), Object.defineProperty(a.prototype, "isStopping", {
        get: function() {
            return !!this.killing;
        },
        enumerable: !0,
        configurable: !0
    }), Object.defineProperty(a.prototype, "process", {
        get: function() {
            return this.proc;
        },
        enumerable: !0,
        configurable: !0
    }), a.prototype.onCrash = function(a, b) {
        console.error("ProcWrapper:crashed:name=" + this.name + ", pid=" + this.pid + ", code=" + a + ", signal=" + b + "\n");
    }, a.prototype.onStopped = function(a, b) {
        console.log("ProcWrapper:stopped:name=" + this.name + ", pid=" + this.pid + ", code=" + a + ", signal=" + b);
    }, a.prototype.onError = function(a, b) {
        console.error("ProcWrapper:failed: action=" + b + ", name=" + this.name + ", error=", a);
    }, a.prototype.writeStdin = function(a) {}, a.prototype.onStdout = function(a) {}, a.prototype.onStderror = function(a) {}, a;
}();

exports.ProcWrapper = ProcWrapper, exports.createMainHandler = createMainHandler;
//# sourceMappingURL=utils.js.map