"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const child_process_1 = require("child_process");
const fs_1 = require("fs");
const systemd_1 = require("./template/systemd");
const initd_1 = require("./template/initd");
/**
 * Returns true if system support systemd daemons
 * @return {Boolean}
 */
function hasSystemD() {
    return fs_1.existsSync('/usr/lib/systemd/system') || fs_1.existsSync('/bin/systemctl');
}
/**
 * Returns true if system support init.d daemons
 * @return {Boolean}
 */
function hasSystemV() {
    return fs_1.existsSync('/etc/init.d');
}
/**
 * Deletes a service file from /etc/systemd/system/
 */
async function deleteSystemD(name, callback) {
    const filepath = `/etc/systemd/system/${name}.service`;
    console.log(`Removing service on: ${filepath}`);
    const exists = fs_1.existsSync(filepath);
    if (!exists) {
        callback("Service doesn't exists, nothing to uninstall");
        return;
    }
    try {
        fs_1.unlinkSync(filepath);
        const cmd = 'systemctl daemon-reload';
        console.log('Running %s...', cmd);
        child_process_1.exec(cmd, (e) => {
            callback(e, 'SystemD service removed successfully');
        });
    }
    catch (e) {
        callback(e);
    }
}
/**
 * Installs a service file to /etc/systemd/system/
 *
 * It deals with logs, restarts and by default points
 * to the normal system install
 */
async function setupSystemD(name, options, callback) {
    options.stdOut = (options.logDir && `${options.logDir}/${name}-out.log`) || null;
    options.stdErr = (options.logDir && `${options.logDir}/${name}-err.log`) || null;
    const filepath = `/etc/systemd/system/${name}.service`;
    const script = systemd_1.default(options);
    if (options.dryRun) {
        console.log(script);
        return;
    }
    console.log(`Installing service on: ${filepath}`);
    const exists = fs_1.existsSync(filepath);
    if (!exists) {
        callback('Service already exists, please uninstall first');
        return;
    }
    try {
        fs_1.writeFileSync(filepath, script);
        fs_1.chmodSync(filepath, '755');
        const cmd = 'systemctl daemon-reload';
        console.log('Running %s...', cmd);
        child_process_1.exec(cmd, (e2) => {
            callback(e2, 'SystemD service registered successfully');
        });
    }
    catch (e) {
        callback(e);
    }
}
/**
 * Deletes a service file from /etc/init.d/
 */
async function deleteSystemV(name, callback) {
    const filepath = `/etc/init.d/${name}`;
    console.log(`Removing service on: ${filepath}`);
    const exists = fs_1.existsSync(filepath);
    if (!exists) {
        callback("Service doesn't exists, nothing to uninstall");
        return;
    }
    try {
        fs_1.unlinkSync(filepath);
        callback(null, 'SystemD service removed successfully');
    }
    catch (e) {
        callback(e);
    }
}
/**
 * Installs a service file to /etc/init.d/
 *
 * It deals with logs, restarts and by default points
 * to the normal system install
 */
async function setupSystemV(name, options, callback) {
    options.stdOut = (options.logDir && `${options.logDir}/${name}-out.log`) || '/dev/null';
    options.stdErr = (options.logDir && `${options.logDir}/${name}-err.log`) || '&1';
    const script = initd_1.default(options);
    if (options.dryRun) {
        console.log(script);
        return;
    }
    const filepath = `/etc/init.d/${name}`;
    console.log(`Installing service on: ${filepath}`);
    const exists = fs_1.existsSync(filepath);
    if (!exists) {
        callback('Service already exists, please uninstall first');
        return;
    }
    try {
        fs_1.writeFileSync(filepath, script);
        fs_1.chmodSync(filepath, '755');
        callback(null, 'init.d service registered successfully');
    }
    catch (e) {
        callback(e);
    }
}
/**
 * Adds a service, either via systemd or init.d
 * @param {String}   name the name of the service
 * @param {Object}   options  options to configure deepstream service
 * @param {Function} callback called when complete
 */
exports.add = (name, options, callback) => {
    options.name = name;
    options.pidFile = options.pidFile || `/var/run/${name}.pid`;
    options.exec = options.exec;
    options.logDir = options.logDir || '/var/log/deepstream';
    options.user = options.user || 'root';
    options.group = options.group || 'root';
    if (options && !options.runLevels) {
        options.runLevels = [2, 3, 4, 5].join(' ');
    }
    else {
        options.runLevels = options.runLevels.join(' ');
    }
    if (!options.programArgs) {
        options.programArgs = [];
    }
    options.deepstreamArgs = ['daemon'].concat(options.programArgs).join(' ');
    if (hasSystemD()) {
        setupSystemD(name, options, callback);
    }
    else if (hasSystemV()) {
        setupSystemV(name, options, callback);
    }
    else {
        callback('Only systemd and init.d services are currently supported.');
    }
};
/**
 * Delete a service, either from systemd or init.d
 * @param {String}   name the name of the service
 * @param {Function} callback called when complete
 */
exports.remove = (name, callback) => {
    if (hasSystemD()) {
        deleteSystemD(name, callback);
    }
    else if (hasSystemV()) {
        deleteSystemV(name, callback);
    }
    else {
        callback('Only systemd and init.d services are currently supported.');
    }
};
/**
 * Start a service, either from systemd or init.d
 * @param {String}   name the name of the service
 * @param {Function} callback called when complete
 */
exports.start = (name, callback) => {
    if (hasSystemD() || hasSystemV()) {
        child_process_1.exec(`service ${name} start`, (err, stdOut, stdErr) => {
            callback(err || stdErr, stdOut);
        });
    }
    else {
        callback('Only systemd and init.d services are currently supported.');
    }
};
/**
 * Stop a service, either from systemd or init.d
 * @param {String}   name the name of the service
 * @param {Function} callback called when complete
 */
exports.stop = (name, callback) => {
    if (hasSystemD() || hasSystemV()) {
        child_process_1.exec(`service ${name} stop`, (err, stdOut, stdErr) => {
            callback(err || stdErr, stdOut);
        });
    }
    else {
        callback('Only systemd and init.d services are currently supported.');
    }
};
/**
 * Get the status of the service, either from systemd or init.d
 * @param {String}   name the name of the service
 * @param {Function} callback called when complete
 */
exports.status = (name, callback) => {
    if (hasSystemD() || hasSystemV()) {
        child_process_1.exec(`service ${name} status`, (err, stdOut, stdErr) => {
            callback(err || stdErr, stdOut);
        });
    }
    else {
        callback('Only systemd and init.d services are currently supported.');
    }
};
/**
 * Restart the service, either from systemd or init.d
 * @param {String}   name the name of the service
 * @param {Function} callback called when complete
 */
exports.restart = (name, callback) => {
    if (hasSystemD() || hasSystemV()) {
        child_process_1.exec(`service ${name} restart`, (err, stdOut, stdErr) => {
            callback(err || stdErr, stdOut);
        });
    }
    else {
        callback('Only systemd and init.d services are currently supported.');
    }
};
//# sourceMappingURL=service.js.map