'use strict';
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
    var ownKeys = function(o) {
        ownKeys = Object.getOwnPropertyNames || function (o) {
            var ar = [];
            for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
            return ar;
        };
        return ownKeys(o);
    };
    return function (mod) {
        if (mod && mod.__esModule) return mod;
        var result = {};
        if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
        __setModuleDefault(result, mod);
        return result;
    };
})();
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.RunnerMessage = void 0;
exports.parseMessage = parseMessage;
const node_path_1 = require("node:path");
const hdbUtil = __importStar(require("../../utility/common_utils.js"));
const hdbTerms = __importStar(require("../../utility/hdbTerms.js"));
const moment_1 = __importDefault(require("moment"));
const bulkLoad = __importStar(require("../../dataLayer/bulkLoad.js"));
const harper_logger_ts_1 = __importDefault(require("../../utility/logging/harper_logger.js"));
const jobs = __importStar(require("./jobs.js"));
const hdbExport = __importStar(require("../../dataLayer/export.js"));
const hdbDelete = __importStar(require("../../dataLayer/delete.js"));
const threadsStart = __importStar(require("../threads/manageThreads.js"));
const transactionLog = __importStar(require("../../utility/logging/transactionLog.js"));
const restart = __importStar(require("../../bin/restart.js"));
const worker_threads_1 = require("worker_threads");
const manageThreads_js_1 = require("../threads/manageThreads.js");
class RunnerMessage {
    job;
    json;
    constructor(jobObject, messageJson) {
        this.job = jobObject;
        this.json = messageJson;
    }
}
exports.RunnerMessage = RunnerMessage;
/**
 * Parses a RunnerMessage and runs the specified job.
 * @param runnerMessage
 * @throws Error
 */
async function parseMessage(runnerMessage) {
    if (!runnerMessage || Object.keys(runnerMessage).length === 0) {
        throw new Error('Empty runner passed to parseMessage');
    }
    if (!runnerMessage.json || Object.keys(runnerMessage.json).length === 0) {
        throw new Error('Empty JSON passed to parseMessage');
    }
    if (!runnerMessage.job || Object.keys(runnerMessage.job).length === 0) {
        throw new Error('Empty job passed to parseMessage');
    }
    if (hdbUtil.isEmptyOrZeroLength(runnerMessage.json.operation)) {
        throw new Error('Invalid operation');
    }
    if (hdbUtil.isEmptyOrZeroLength(runnerMessage.job.id)) {
        throw new Error('Empty job id specified');
    }
    switch (runnerMessage.json.operation) {
        case hdbTerms.JOB_TYPE_ENUM.csv_file_load:
            await runJob(runnerMessage, bulkLoad.csvFileLoad);
            break;
        case hdbTerms.JOB_TYPE_ENUM.csv_url_load:
            await runJob(runnerMessage, bulkLoad.csvURLLoad);
            break;
        case hdbTerms.JOB_TYPE_ENUM.csv_data_load:
            await runJob(runnerMessage, bulkLoad.csvDataLoad);
            break;
        case hdbTerms.JOB_TYPE_ENUM.import_from_s3:
            await runJob(runnerMessage, bulkLoad.importFromS3);
            break;
        case hdbTerms.JOB_TYPE_ENUM.empty_trash:
            break;
        case hdbTerms.JOB_TYPE_ENUM.export_local:
            await runJob(runnerMessage, hdbExport.export_local);
            break;
        case hdbTerms.JOB_TYPE_ENUM.export_to_s3:
            await runJob(runnerMessage, hdbExport.export_to_s3);
            break;
        case hdbTerms.JOB_TYPE_ENUM.delete_files_before:
        case hdbTerms.JOB_TYPE_ENUM.delete_records_before:
            await runJob(runnerMessage, hdbDelete.deleteFilesBefore);
            break;
        case hdbTerms.JOB_TYPE_ENUM.delete_audit_logs_before:
            // deprecated in favor of delete_transaction_logs_before
            await runJob(runnerMessage, hdbDelete.deleteAuditLogsBefore);
            break;
        case hdbTerms.JOB_TYPE_ENUM.delete_transaction_logs_before:
            await runJob(runnerMessage, transactionLog.deleteTransactionLogsBefore);
            break;
        case hdbTerms.JOB_TYPE_ENUM.restart_service:
            await runJob(runnerMessage, restart.restartService);
            return `Restarting ${runnerMessage.json.service}`;
            break;
        default:
            return `Invalid operation ${runnerMessage.json.operation} specified`;
    }
}
/**
 * Helper function to run the specified operation using the job update 'workflow'.
 * @param runnerMessage - The RunnerMessage created by the signal flow
 * @param operation - The operation to run.
 */
async function runJob(runnerMessage, operation) {
    try {
        runnerMessage.job.status = hdbTerms.JOB_STATUS_ENUM.IN_PROGRESS;
        runnerMessage.job.start_datetime = (0, moment_1.default)().valueOf();
        // Update with "IN PROGRESS"
        await jobs.updateJob(runnerMessage.job);
        // Run the operation.
        await launchJobThread(runnerMessage.job.id);
    }
    catch (e) {
        let errMessage = e.message !== undefined ? e.message : e;
        if (typeof errMessage === 'string') {
            errMessage = `There was an error running ${operation.name} job with id ${runnerMessage.job.id} - ${errMessage}`;
            e.message = errMessage;
        }
        else {
            //This ensures that the op/job id error is logged if the error message is passed as a non-string which will
            // be logged right after this below.  If the message is a string, everything will be logged below as the errMessage
            harper_logger_ts_1.default.error(`There was an error running ${operation.name} job with id ${runnerMessage.job.id}`);
        }
        harper_logger_ts_1.default.error(errMessage);
        runnerMessage.job.message = errMessage;
        runnerMessage.job.status = hdbTerms.JOB_STATUS_ENUM.ERROR;
        try {
            // Update with "Error"
            await jobs.updateJob(runnerMessage.job);
        }
        catch (ex) {
            harper_logger_ts_1.default.error(`Unable to update job with id ${runnerMessage.job.id}`);
            throw ex;
        }
        throw e;
    }
}
/**
 * Launches job in a separate process using processManagement
 * @param job_id
 * @returns {Promise<void>}
 */
async function launchJobThread(job_id) {
    harper_logger_ts_1.default.trace('launching job thread:', job_id);
    if (worker_threads_1.isMainThread) {
        threadsStart.startWorker((0, node_path_1.join)(__dirname, './jobProcess.js'), {
            autoRestart: false,
            name: 'job',
            env: { ...process.env, [hdbTerms.PROCESS_NAME_ENV_PROP]: `JOB-${job_id}` },
        });
    }
    else {
        worker_threads_1.parentPort.postMessage({
            type: hdbTerms.ITC_EVENT_TYPES.START_JOB,
            jobId: job_id,
        });
    }
}
if (worker_threads_1.isMainThread) {
    (0, manageThreads_js_1.onMessageByType)(hdbTerms.ITC_EVENT_TYPES.START_JOB, async (message) => {
        try {
            threadsStart.startWorker((0, node_path_1.join)(__dirname, './jobProcess.js'), {
                autoRestart: false,
                name: 'job',
                env: { ...process.env, [hdbTerms.PROCESS_NAME_ENV_PROP]: `JOB-${message.jobId}` },
            });
        }
        catch (e) {
            harper_logger_ts_1.default.error(e);
        }
    });
}
//# sourceMappingURL=jobRunner.js.map