"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
/**
 * General purpose logger
 */
const fs = require("fs");
const settings_1 = require("./settings");
let rfs = require('rotating-file-stream');
const Utils = require("./utils");
var LOG_LEVEL;
(function (LOG_LEVEL) {
    LOG_LEVEL[LOG_LEVEL["INFO"] = 1] = "INFO";
    LOG_LEVEL[LOG_LEVEL["WARNING"] = 2] = "WARNING";
    LOG_LEVEL[LOG_LEVEL["ERROR"] = 4] = "ERROR";
    LOG_LEVEL[LOG_LEVEL["DEBUG"] = 8] = "DEBUG";
    LOG_LEVEL[LOG_LEVEL["DEBUG_VERBOSE"] = 16] = "DEBUG_VERBOSE";
    LOG_LEVEL[LOG_LEVEL["QUERIES"] = 32] = "QUERIES";
    LOG_LEVEL[LOG_LEVEL["EXTERNAL_API"] = 64] = "EXTERNAL_API";
    LOG_LEVEL[LOG_LEVEL["INTERNAL_API"] = 128] = "INTERNAL_API";
})(LOG_LEVEL = exports.LOG_LEVEL || (exports.LOG_LEVEL = {}));
class OutputSystem {
    constructor(filename, path, size, interval = 1000) {
        this.buf = [];
        this.timer = null;
        this.inRotation = false;
        // ensure log directory exists
        fs.existsSync(path) || fs.mkdirSync(path);
        let options = {
            size: size,
            path: path
        };
        this.stream = rfs(filename, options);
        this.interval = interval;
        let self = this;
        this.stream.on("rotation", function () {
            self.inRotation = true;
            if (self.timer != null) {
                clearTimeout(self.timer);
                self.flush();
            }
        });
        this.stream.on("rotated", function (filename) {
            self.inRotation = false;
            if (self.buf.length > 0) {
                self.flush();
            }
        });
    }
    // flush function
    flush() {
        this.timer = null;
        this.stream.write(this.buf.join(''));
        this.buf.length = 0;
    }
    // write function
    write(str) {
        if (this.timer === null && !this.inRotation) {
            this.timer = setTimeout(this.flush.bind(this), this.interval);
        }
        this.buf.push(str);
    }
    close() {
        this.stream.end();
    }
}
class Logger {
    constructor(token) {
        let config = settings_1.default.Instance.getLogger(token);
        this.currentLogLevel = config.logLevel != null ? config.logLevel : LOG_LEVEL.INFO | LOG_LEVEL.WARNING | LOG_LEVEL.ERROR;
        this.debugLogging = config.debugLogging ? config.debugLogging : false;
        let outputFile = config.outputFile ? config.outputFile : "outputFile";
        let errorFile = config.errorFile ? config.errorFile : "errorFile";
        let logFolder = config.logFolder ? config.logFolder : "logs";
        let rotatingSize = config.rotatingSize ? config.rotatingSize : "1d";
        logFolder = Utils.default.getFullRouteFrom(logFolder);
        this.outputStream = new OutputSystem(outputFile, logFolder, rotatingSize);
        this.errorStream = new OutputSystem(errorFile, logFolder, rotatingSize);
    }
    setLogLevel(level) {
        this.currentLogLevel = level;
    }
    destroy() {
        this.outputStream.close();
        this.errorStream.close();
    }
    getStatus() {
        return "unknown";
    }
    isFunctional() {
        return true;
    }
    /**
     * based on the parameters add a new entry in crawler, workers logs or console if it that option was selected via settings
     * @param str
     * @param level
     */
    log(str, level) {
        let time = new Date().toISOString();
        if (level && (this.currentLogLevel & level)) {
            if (this.debugLogging) {
                console.log("[" + time + "] [" + this.getLevelStr(level) + '] ' + str);
            }
            else {
                this.outputStream.write("[" + time + "] [" + this.getLevelStr(level) + '] ' + str + "\n");
            }
        }
        if (level == Logger.LOG_LEVEL.ERROR) {
            this.errorStream.write("[" + time + "] [" + this.getLevelStr(level) + '] ' + str + "\n");
        }
    }
    getLevelStr(_level) {
        switch (_level) {
            case Logger.LOG_LEVEL.INFO:
                return "INFO";
            case Logger.LOG_LEVEL.WARNING:
                return "WARNING";
            case Logger.LOG_LEVEL.ERROR:
                return "ERROR";
            case Logger.LOG_LEVEL.DEBUG:
                return "DEBUG";
            case Logger.LOG_LEVEL.DEBUG_VERBOSE:
                return "VERBOSE";
            case Logger.LOG_LEVEL.QUERIES:
                return "QUERY";
            case Logger.LOG_LEVEL.EXTERNAL_API:
                return "EXTERNAL_API";
            case Logger.LOG_LEVEL.INTERNAL_API:
                return "INTERNAL_API";
            default:
                return "";
        }
    }
}
Logger.LOG_LEVEL = LOG_LEVEL;
exports.default = Logger;
//# sourceMappingURL=logger.js.map