"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 (mod) {
    if (mod && mod.__esModule) return mod;
    var result = {};
    if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
    __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.setLogsDirectory = exports.replaceSecrets = exports.setSecret = exports.inDebugMode = exports.consoleLog = exports.debugMode = exports.debugSpinner = exports.debug = exports.info = exports.warn = exports.fail = exports.succeed = exports.writeLog = exports.getSpinner = exports.Spinner = exports.ANSI_REGEX = void 0;
const fs_1 = __importDefault(require("fs"));
const path_1 = __importDefault(require("path"));
const ora = __importStar(require("ora"));
const chalk_1 = require("chalk");
const date_fns_tz_1 = require("date-fns-tz");
const promise_utils_1 = require("@api3/promise-utils");
const airnode_utilities_1 = require("@api3/airnode-utilities");
exports.ANSI_REGEX = new RegExp(/\033\[([0-9]{1,2}(;[0-9]{1,2})?)?[m|K]/g);
class Spinner {
    constructor() {
        this.oraInstance = oraInstance();
    }
    getOraInstance() {
        return this.oraInstance;
    }
    isSpinning() {
        return this.getOraInstance().isSpinning;
    }
    clear() {
        this.getOraInstance().clear();
    }
    frame() {
        this.getOraInstance().frame();
    }
    start(text, options) {
        if (text)
            writeLog(text, options);
        this.getOraInstance().start(text);
    }
    succeed(text, options) {
        if (text)
            writeLog(text, options);
        this.getOraInstance().succeed(text);
    }
    fail(text, options) {
        if (text)
            writeLog(text, options);
        this.getOraInstance().fail(text);
    }
    info(text, options) {
        if (text)
            writeLog(text, options);
        this.getOraInstance().info(text);
    }
    warn(text, options) {
        if (text)
            writeLog(text, options);
        this.getOraInstance().warn(text);
    }
    stop(text, options) {
        if (text)
            writeLog(text, options);
        this.getOraInstance().stop();
    }
}
exports.Spinner = Spinner;
let logsDirectory;
let logFileTimestamp;
const secrets = [];
let debugModeFlag = false;
const dummySpinner = {
    ...ora.default(),
    start: (_text) => dummySpinner,
    stop: () => dummySpinner,
    succeed: (_text) => dummySpinner,
    fail: (_text) => dummySpinner,
    warn: (_text) => dummySpinner,
    info: (_text) => dummySpinner,
    stopAndPersist: (_options) => dummySpinner,
    frame: () => '',
    clear: () => dummySpinner,
    render: () => dummySpinner,
};
let spinner;
function getSpinner() {
    if (spinner)
        return spinner;
    spinner = new Spinner();
    return spinner;
}
exports.getSpinner = getSpinner;
function oraInstance(text) {
    return debugModeFlag ? ora.default({ text, prefixText: () => new Date().toISOString() }) : ora.default(text);
}
function writeLog(text, options) {
    if (!logsDirectory)
        throw new Error('Missing log file directory.');
    const safeText = options?.secrets ? replaceSecrets(text, secrets) : text;
    // Strip ANSI characters to write tables to log files correctly and add new line
    const sanitizedLogs = exports.ANSI_REGEX.test(safeText) ? '\n' + safeText.replace(exports.ANSI_REGEX, '') : safeText;
    fs_1.default.appendFileSync(path_1.default.join(logsDirectory, `deployer-${logFileTimestamp}.log`), `${new Date().toISOString()}: ${sanitizedLogs}\n`);
}
exports.writeLog = writeLog;
function succeed(text, options) {
    writeLog(text, options);
    oraInstance().succeed(text);
}
exports.succeed = succeed;
function fail(text, options) {
    writeLog(text, options);
    oraInstance().fail(options?.bold ? (0, chalk_1.bold)(text) : text);
}
exports.fail = fail;
function warn(text, options) {
    writeLog(text, options);
    const currentOra = getSpinner();
    if (currentOra.isSpinning()) {
        currentOra.clear();
        currentOra.frame();
    }
    oraInstance().warn(text);
}
exports.warn = warn;
function info(text, options) {
    writeLog(text, options);
    const currentOra = getSpinner();
    if (currentOra.isSpinning()) {
        currentOra.clear();
        currentOra.frame();
    }
    oraInstance().info(text);
}
exports.info = info;
function debug(text, options) {
    if (debugModeFlag) {
        info(text);
    }
    else {
        writeLog(text, options);
    }
}
exports.debug = debug;
function debugSpinner(text, options) {
    writeLog(text, options);
    if (debugModeFlag) {
        const spinner = getSpinner();
        spinner.info(text);
        return spinner;
    }
    return dummySpinner;
}
exports.debugSpinner = debugSpinner;
function debugMode(mode) {
    debugModeFlag = mode;
}
exports.debugMode = debugMode;
function consoleLog(text, options) {
    writeLog(text, options);
    (0, airnode_utilities_1.consoleLog)(text);
}
exports.consoleLog = consoleLog;
function inDebugMode() {
    return debugModeFlag;
}
exports.inDebugMode = inDebugMode;
function setSecret(secret) {
    secrets.push(secret);
}
exports.setSecret = setSecret;
function replaceSecrets(input, secrets) {
    let output = input;
    secrets.forEach((secret) => (output = output.replace(secret, '***')));
    return output;
}
exports.replaceSecrets = replaceSecrets;
function setLogsDirectory(path) {
    logsDirectory = path;
    const goOutputWritable = (0, promise_utils_1.goSync)(() => fs_1.default.accessSync(logsDirectory, fs_1.default.constants.W_OK));
    if (!goOutputWritable.success) {
        const goMkdir = (0, promise_utils_1.goSync)(() => fs_1.default.mkdirSync(logsDirectory, { recursive: true }));
        if (!goMkdir.success)
            throw new Error(`Failed to create logs output directory. Error: ${goMkdir.error}.`);
    }
    logFileTimestamp = (0, date_fns_tz_1.format)(Date.now(), 'yyyy-MM-dd_HH:mm:ss');
}
exports.setLogsDirectory = setLogsDirectory;
//# sourceMappingURL=logger.js.map