"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
/* TODO auto-generated eslint ignore, please fix! */
/* eslint no-process-exit: "off", @typescript-eslint/no-var-requires: "off" */
/**
 * Start the Liza delta processor
 *
 *  Copyright (C) 2010-2019 R-T Specialty, LLC.
 *
 *  This file is part of the Liza Data Collection Framework.
 *
 *  liza is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
var amqplib = require("amqplib");
var AmqpPublisher_1 = require("../src/system/AmqpPublisher");
var MongoDeltaDao_1 = require("../src/system/db/MongoDeltaDao");
var DeltaProcessor_1 = require("../src/system/DeltaProcessor");
var DeltaPublisher_1 = require("../src/system/DeltaPublisher");
var AvroFactory_1 = require("../src/system/avro/AvroFactory");
var V1MessageWriter_1 = require("../src/system/avro/V1MessageWriter");
var delta_1 = require("../src/bucket/delta");
var MongoFactory_1 = require("../src/system/db/MongoFactory");
var EventMediator_1 = require("../src/system/EventMediator");
var events_1 = require("events");
var StandardLogger_1 = require("../src/system/StandardLogger");
var MetricsCollector_1 = require("../src/system/MetricsCollector");
var PrometheusFactory_1 = require("../src/system/PrometheusFactory");
var AmqpConnection_1 = require("../src/system/amqp/AmqpConnection");
var avro_js_1 = require("avro-js");
var os_1 = require("os");
var PromClient = require("prom-client");
require('dotenv-flow').config({ path: '..' });
var amqp_conf = AmqpPublisher_1.createAmqpConfig(process.env);
var prom_conf = PrometheusFactory_1.createPrometheusConfig(process.env, os_1.hostname());
var db_conf = MongoFactory_1.createMongoConfig(process.env);
var db = MongoFactory_1.createMongoDB(db_conf);
var process_interval_ms = +(process.env.PROCESS_INTERVAL_MS || 10000);
var env = process.env.NODE_ENV || 'Unknown Environment';
var emitter = new events_1.EventEmitter();
var log = new StandardLogger_1.StandardLogger(console, ts_ctor, env);
var amqp_connection = new AmqpConnection_1.AmqpConnection(amqplib, amqp_conf, emitter);
var message_writer = new V1MessageWriter_1.V1MessageWriter(AvroFactory_1.createAvroEncoder, avro_js_1.parse(__dirname + '/../src/system/avro/schema.avsc'));
var publisher = new DeltaPublisher_1.DeltaPublisher(emitter, ts_ctor, amqp_connection, message_writer);
// Prometheus Metrics
var prom_factory = new PrometheusFactory_1.PrometheusFactory();
var metrics = new MetricsCollector_1.MetricsCollector(PromClient, prom_factory, prom_conf, emitter, process.hrtime);
// Structured logging
new EventMediator_1.EventMediator(log, emitter);
var process_interval;
var dao;
MongoFactory_1.getMongoCollection(db, db_conf)
    .then(function (conn) {
    return new MongoDeltaDao_1.MongoDeltaDao(conn, env);
})
    .then(function (mongoDao) {
    dao = mongoDao;
})
    .then(function (_) { return amqp_connection.connect(); })
    .then(function (_) {
    log.info('Liza Delta Processor');
    handleShutdown();
    var processor = new DeltaProcessor_1.DeltaProcessor(dao, publisher, emitter, delta_1.applyDelta, delta_1.mergeDeltas);
    return new Promise(function (_resolve, reject) {
        process_interval = setInterval(function () {
            try {
                processor.process().catch(function (err) { return reject(err); });
            }
            catch (err) {
                reject(err);
            }
            dao.getErrorCount().then(function (count) {
                metrics.updateErrorCount(count);
            });
        }, process_interval_ms);
    });
})
    .catch(function (e) {
    emitter.emit('error', e);
    process.exit(1);
});
/**
 * Hook shutdown events
 */
function handleShutdown() {
    process
        .on('SIGINT', function () {
        shutdown('SIGINT');
    })
        .on('SIGTERM', function () {
        shutdown('SIGTERM');
    });
}
/**
 * Perform a graceful shutdown
 *
 * @param signal - the signal that caused the shutdown
 */
function shutdown(signal) {
    log.info('Received ' + signal + '. Beginning graceful shutdown:');
    log.info('...Stopping processing interval');
    clearInterval(process_interval);
    log.info('...Closing MongoDb connection');
    db.close(function (err, _data) {
        if (err) {
            console.error('    Error closing connection: ' + err);
        }
    });
    log.info('...Closing AMQP connection...');
    amqp_connection.close();
    log.info('...Stopping the metrics collector...');
    metrics.stop();
    log.info('Shutdown complete. Exiting.');
    process.exit();
}
/** Timestamp constructor
 *
 * @return a timestamp
 */
function ts_ctor() {
    return Math.floor(new Date().getTime() / 1000);
}
//# sourceMappingURL=data:application/json;base64, 