"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.analyzeLogs = exports.structureLogs = exports.stringifyLog = exports.parseLogs = void 0;
function parseLogs(logs) {
    const regexp = /^(?<label>[^\s]+) (?:\((?<tags>[^\)]+)\) )?\| (?<timestamp>\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z)? (?:\[(?<level>[A-Z]+)\s*\])? (?<message>.+)$/;
    const lines = logs.split('\n');
    return lines.reduce((logs, line) => {
        var _a, _b;
        const match = line.match(regexp);
        if (match) {
            logs.push({
                ...match.groups,
                tags: (_b = (_a = match.groups) === null || _a === void 0 ? void 0 : _a.tags) === null || _b === void 0 ? void 0 : _b.split(' & ').map(tags => tags.split('/')),
            });
        }
        else if (logs[logs.length - 1]) {
            logs[logs.length - 1].message += line;
        }
        return logs;
    }, []);
}
exports.parseLogs = parseLogs;
function stringifyLog(log) {
    var _a;
    // eslint-disable-next-line
    return `${log.label} (${(_a = log.tags) === null || _a === void 0 ? void 0 : _a.map(tags => tags.join('/')).join(' & ')}) ${log.timestamp} [${log.level}] ${log.message}`;
}
exports.stringifyLog = stringifyLog;
function structureLogs(logs) {
    const groups = {};
    groups.logs;
    logs.forEach(log => {
        var _a;
        const tags = (_a = log.tags) !== null && _a !== void 0 ? _a : [[]];
        tags.forEach(tags => {
            var _a;
            const group = tags.reduce((object, key) => {
                var _a;
                (_a = object[key]) !== null && _a !== void 0 ? _a : (object[key] = {});
                return object[key];
            }, groups);
            (_a = group.logs) !== null && _a !== void 0 ? _a : (group.logs = []);
            group.logs.push(log);
        });
    });
    return groups;
}
exports.structureLogs = structureLogs;
function analyzeLogs({ logs, ...groups }) {
    var _a, _b;
    const analysis = {};
    analysis.logs = logs === null || logs === void 0 ? void 0 : logs.map(stringifyLog);
    const groupAnalyses = Object.fromEntries(Object.entries(groups).map(([name, group]) => [name, analyzeLogs(group)]));
    analysis.startedAt = Math.min(Date.parse((_a = logs === null || logs === void 0 ? void 0 : logs[0]) === null || _a === void 0 ? void 0 : _a.timestamp) || Infinity, ...Object.values(groupAnalyses).map(group => group.startedAt));
    analysis.finishedAt = Math.max(Date.parse((_b = logs === null || logs === void 0 ? void 0 : logs[logs.length - 1]) === null || _b === void 0 ? void 0 : _b.timestamp) || 0, ...Object.values(groupAnalyses).map(group => group.finishedAt));
    analysis.time = analysis.finishedAt - analysis.startedAt;
    analysis.conclusion = '';
    analysis.conclusion += `Time taken: ${formatTime(analysis.time)};`;
    if (Object.keys(groupAnalyses).length > 0) {
        analysis.conclusion += `Longest group: ${Object.keys(groupAnalyses).reduce((prev, cur) => groupAnalyses[cur].time > groupAnalyses[prev].time ? cur : prev)}`;
    }
    return { ...analysis, ...groupAnalyses };
}
exports.analyzeLogs = analyzeLogs;
function formatTime(ms) {
    const h = Math.floor(ms / 3600000);
    if (h)
        ms -= h * 3600000;
    const m = Math.floor(ms / 60000);
    if (m)
        ms -= m * 60000;
    const s = Math.floor(ms / 1000);
    if (s)
        ms -= s * 1000;
    return [h && `${h}h`, m && `${m}m`, s && `${s}s`, ms && `${ms}ms`].filter(Boolean).join(' ');
}
