"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.DeviceLogProvider = void 0;
const device_log_provider_base_1 = require("./device-log-provider-base");
const constants_1 = require("../constants");
const yok_1 = require("../yok");
const constants_2 = require("../../constants");
const color_1 = require("../../color");
class DeviceLogProvider extends device_log_provider_base_1.DeviceLogProviderBase {
    constructor($logFilter, $logger, $logSourceMapService, $timelineProfilerService, $options) {
        super($logFilter, $logger, $logSourceMapService);
        this.$logFilter = $logFilter;
        this.$logger = $logger;
        this.$logSourceMapService = $logSourceMapService;
        this.$timelineProfilerService = $timelineProfilerService;
        this.$options = $options;
        this.consoleLogLevelRegex = /^CONSOLE (LOG|INFO|WARN|ERROR|TRACE|INFO( .+)):\s/;
        this.consoleLevelColor = {
            log: (line) => line,
            info: color_1.color.cyanBright,
            warn: color_1.color.yellowBright,
            error: color_1.color.redBright,
            trace: color_1.color.grey,
            time: color_1.color.greenBright,
        };
        this.deviceColorMap = new Map();
        this.colorPool = [
            "bgBlackBright",
            "bgMagentaBright",
            "bgBlueBright",
            "bgWhiteBright",
            "bgCyanBright",
            "bgYellowBright",
            "bgGreenBright",
        ];
        this.colorPoolIndex = 0;
    }
    logData(lineText, platform, deviceIdentifier) {
        const loggingOptions = this.getDeviceLogOptionsForDevice(deviceIdentifier);
        let data = this.$logFilter.filterData(platform, lineText, loggingOptions);
        data = this.$logSourceMapService.replaceWithOriginalFileLocations(platform, data, loggingOptions);
        if (data) {
            this.$timelineProfilerService.processLogData(data, deviceIdentifier);
            this.logDataCore(data, deviceIdentifier);
            this.emit(constants_1.DEVICE_LOG_EVENT_NAME, lineText, deviceIdentifier, platform);
        }
    }
    setLogLevel(logLevel, deviceIdentifier) {
        this.$logFilter.loggingLevel = logLevel.toUpperCase();
    }
    getDeviceColor(deviceIdentifier) {
        if (this.deviceColorMap.has(deviceIdentifier)) {
            return this.deviceColorMap.get(deviceIdentifier);
        }
        const color = this.colorPool[this.colorPoolIndex];
        this.colorPoolIndex =
            this.colorPoolIndex === this.colorPool.length - 1
                ? 0
                : this.colorPoolIndex + 1;
        this.deviceColorMap.set(deviceIdentifier, color);
        return color;
    }
    logDataCore(data, deviceIdentifier) {
        var _a, _b, _c;
        if ("classicLogs" in ((_a = this.$options.env) !== null && _a !== void 0 ? _a : {})) {
            this.$logger.info(data, { [constants_2.LoggerConfigData.skipNewLine]: true });
            return;
        }
        let shouldPrepend = false;
        let splitIndexes = [];
        const lines = data
            .split(/\n(CONSOLE)/)
            .map((line, index, lines) => {
            if (line === "CONSOLE") {
                shouldPrepend = true;
                if (lines[index - 1]) {
                    splitIndexes.push(index - 1);
                }
                return null;
            }
            if (shouldPrepend) {
                shouldPrepend = false;
                return `CONSOLE${line}`;
            }
            const suffix = line.endsWith("\n") ? "" : "\n";
            return line + suffix;
        })
            .map((line, index) => {
            if (splitIndexes.includes(index)) {
                return line + "\n";
            }
            return line;
        })
            .filter((line) => {
            return line !== null;
        });
        if (!lines.length && data.length) {
            lines.push(data);
        }
        for (const line of lines) {
            let [match, level, timeLabel] = (_b = this.consoleLogLevelRegex.exec(line)) !== null && _b !== void 0 ? _b : [];
            if (timeLabel) {
                level = "time";
                timeLabel = timeLabel.replace("INFO ", "").trim() + ": ";
            }
            else {
                level = (_c = level === null || level === void 0 ? void 0 : level.toLowerCase()) !== null && _c !== void 0 ? _c : "log";
            }
            const toLog = [timeLabel !== null && timeLabel !== void 0 ? timeLabel : "", match ? line.replace(match, "") : line]
                .join("")
                .trim();
            toLog.split("\n").forEach((actualLine) => {
                this.printLine(color_1.color[this.getDeviceColor(deviceIdentifier)](" "), this.consoleLevelColor[level](actualLine));
            });
        }
    }
    printLine(prefix, ...parts) {
        const fullLine = parts.join(" ");
        console.log(prefix, fullLine);
    }
}
exports.DeviceLogProvider = DeviceLogProvider;
yok_1.injector.register("deviceLogProvider", DeviceLogProvider);
