'use strict';

exports = module.exports = {
    sendFailureLogs: sendFailureLogs
};

var assert = require('assert'),
    mailer = require('./mailer.js'),
    safe = require('safetydance'),
    path = require('path'),
    util = require('util');

var COLLECT_LOGS_CMD = path.join(__dirname, 'scripts/collectlogs.sh');

var CRASH_LOG_TIMESTAMP_OFFSET = 1000 * 60 * 60; // 60 min
var CRASH_LOG_TIMESTAMP_FILE = '/tmp/crashlog.timestamp';
var CRASH_LOG_STASH_FILE = '/tmp/crashlog';
var CRASH_LOG_FILE_LIMIT = 2 * 1024 * 1024; // 2mb

function collectLogs(unitName, callback) {
    assert.strictEqual(typeof unitName, 'string');
    assert.strictEqual(typeof callback, 'function');

    var logs = safe.child_process.execSync('sudo ' + COLLECT_LOGS_CMD + ' ' + unitName, { encoding: 'utf8' });
    logs = logs + '\n\n=====================================\n\n';

    callback(null, logs);
}

function stashLogs(logs) {
    var stat = safe.fs.statSync(CRASH_LOG_STASH_FILE);
    if (stat && (stat.size > CRASH_LOG_FILE_LIMIT)) {
        console.error('Dropping logs since crash file has become too big');
        return;
    }

    // append here
    safe.fs.writeFileSync(CRASH_LOG_STASH_FILE, logs, { flag: 'a' });
}

function sendFailureLogs(processName, options) {
    assert.strictEqual(typeof processName, 'string');
    assert.strictEqual(typeof options, 'object');

    collectLogs(options.unit || processName, function (error, newLogs) {
        if (error) {
            console.error('Failed to collect logs.', error);
            newLogs = util.format('Failed to collect logs.', error);
        }

        console.log('Sending failure logs for', processName);

        var timestamp = safe.fs.readFileSync(CRASH_LOG_TIMESTAMP_FILE, 'utf8');

        // check if we already sent a mail in the last CRASH_LOG_TIME_OFFSET window
        if (timestamp && (parseInt(timestamp) + CRASH_LOG_TIMESTAMP_OFFSET) > Date.now()) {
            console.log('Crash log already sent within window. Stashing logs.');
            return stashLogs(newLogs);
        }

        var stashedLogs = safe.fs.readFileSync(CRASH_LOG_STASH_FILE, 'utf8');
        var compiledLogs = stashedLogs ? (stashedLogs + newLogs) : newLogs;
        var mailSubject = processName + (stashedLogs ? ' and others' : '');

        mailer.unexpectedExit(mailSubject, compiledLogs, function (error) {
            if (error) {
                console.log('Error sending crashlog. Stashing logs.');
                return stashLogs(newLogs);
            }

            // write the new timestamp file and delete stash file
            safe.fs.writeFileSync(CRASH_LOG_TIMESTAMP_FILE, String(Date.now()));
            safe.fs.unlinkSync(CRASH_LOG_STASH_FILE);
        });
    });
}
