"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.getTasks = exports.init = exports.Task = exports.TaskState = exports.jobResultWarning = exports.jobResultOkay = exports.JobResultState = void 0;
const node_cron_1 = __importDefault(require("node-cron"));
const moment_1 = __importDefault(require("moment"));
const config_1 = require("../config");
const logger_1 = __importDefault(require("../logger"));
const MailQueueJob_1 = __importDefault(require("./MailQueueJob"));
const FixNodeFilenamesJob_1 = __importDefault(require("./FixNodeFilenamesJob"));
const NodeInformationRetrievalJob_1 = __importDefault(require("./NodeInformationRetrievalJob"));
const MonitoringMailsSendingJob_1 = __importDefault(require("./MonitoringMailsSendingJob"));
const OfflineNodesDeletionJob_1 = __importDefault(require("./OfflineNodesDeletionJob"));
var JobResultState;
(function (JobResultState) {
    JobResultState["OKAY"] = "okay";
    JobResultState["WARNING"] = "warning";
})(JobResultState = exports.JobResultState || (exports.JobResultState = {}));
function jobResultOkay(message) {
    return {
        state: JobResultState.OKAY,
        message
    };
}
exports.jobResultOkay = jobResultOkay;
function jobResultWarning(message) {
    return {
        state: JobResultState.WARNING,
        message
    };
}
exports.jobResultWarning = jobResultWarning;
var TaskState;
(function (TaskState) {
    TaskState["IDLE"] = "idle";
    TaskState["RUNNING"] = "running";
    TaskState["FAILED"] = "failed";
})(TaskState = exports.TaskState || (exports.TaskState = {}));
class Task {
    constructor(id, name, description, schedule, job, runningSince, lastRunStarted, lastRunDuration, state, result, enabled) {
        this.id = id;
        this.name = name;
        this.description = description;
        this.schedule = schedule;
        this.job = job;
        this.runningSince = runningSince;
        this.lastRunStarted = lastRunStarted;
        this.lastRunDuration = lastRunDuration;
        this.state = state;
        this.result = result;
        this.enabled = enabled;
    }
    run() {
        if (this.runningSince || !this.enabled) {
            // job is still running, skip execution
            return;
        }
        this.runningSince = moment_1.default();
        this.lastRunStarted = this.runningSince;
        this.state = TaskState.RUNNING;
        const done = (state, result) => {
            const now = moment_1.default();
            const duration = now.diff(this.runningSince || now);
            logger_1.default.tag('jobs').profile('[%sms]\t%s', duration, this.name);
            this.runningSince = null;
            this.lastRunDuration = duration;
            this.state = state;
            this.result = result;
        };
        this.job.run().then(result => {
            done(TaskState.IDLE, result);
        }).catch((err) => {
            logger_1.default.tag('jobs').error("Job %s failed: %s", this.name, err);
            done(TaskState.FAILED, null);
        });
    }
}
exports.Task = Task;
const tasks = {};
let taskId = 1;
function nextTaskId() {
    const id = taskId;
    taskId += 1;
    return id;
}
function schedule(expr, job) {
    logger_1.default.tag('jobs').info('Scheduling job: %s  %s', expr, job.name);
    const id = nextTaskId();
    const task = new Task(id, job.name, job.description, expr, job, null, null, null, TaskState.IDLE, null, true);
    node_cron_1.default.schedule(expr, () => task.run());
    tasks['' + id] = task;
}
function init() {
    logger_1.default.tag('jobs').info('Scheduling background jobs...');
    try {
        schedule('0 */1 * * * *', MailQueueJob_1.default);
        schedule('15 */1 * * * *', FixNodeFilenamesJob_1.default);
        if (config_1.config.client.monitoring.enabled) {
            schedule('30 */15 * * * *', NodeInformationRetrievalJob_1.default);
            schedule('45 */5 * * * *', MonitoringMailsSendingJob_1.default);
            schedule('0 0 3 * * *', OfflineNodesDeletionJob_1.default); // every night at 3:00
        }
    }
    catch (error) {
        logger_1.default.tag('jobs').error('Error during scheduling of background jobs:', error);
        throw error;
    }
    logger_1.default.tag('jobs').info('Scheduling of background jobs done.');
}
exports.init = init;
function getTasks() {
    return tasks;
}
exports.getTasks = getTasks;
//# sourceMappingURL=scheduler.js.map