"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.getTrackedProjectIssueLogDirectory = getTrackedProjectIssueLogDirectory;
exports.getTrackedProjectIssueLogPath = getTrackedProjectIssueLogPath;
exports.readIssueLogText = readIssueLogText;
exports.readServiceLogText = readServiceLogText;
exports.listTrackedProjectIssueLogIds = listTrackedProjectIssueLogIds;
exports.listTrackedProjectIssueLogPaths = listTrackedProjectIssueLogPaths;
exports.sliceTextTail = sliceTextTail;
exports.searchTrackedProjectIssueLogs = searchTrackedProjectIssueLogs;
exports.searchIssueLogText = searchIssueLogText;
exports.renderIssueLogSearchBlocks = renderIssueLogSearchBlocks;
exports.renderEmptyIssueLogList = renderEmptyIssueLogList;
exports.renderEmptyIssueLogShow = renderEmptyIssueLogShow;
exports.renderEmptyIssueLogSearch = renderEmptyIssueLogSearch;
exports.renderEmptyServiceLog = renderEmptyServiceLog;
exports.formatIssueLogList = formatIssueLogList;
const promises_1 = require("node:fs/promises");
const node_os_1 = __importDefault(require("node:os"));
const fs_errors_1 = require("../core/fs-errors");
const file_readers_1 = require("../core/file-readers");
const paths_1 = require("../core/paths");
const global_settings_1 = require("../core/global-settings");
const catalog_1 = require("../i18n/catalog");
const provider_resolution_1 = require("../platform/provider-resolution");
function getTrackedProjectIssueLogDirectory(trackedProject, homeDirectory = node_os_1.default.homedir()) {
    return (0, global_settings_1.resolveIssueLogDirectory)((0, provider_resolution_1.getTrackedProjectStorageSegments)(trackedProject), homeDirectory);
}
function getTrackedProjectIssueLogPath(trackedProject, issueId, homeDirectory = node_os_1.default.homedir()) {
    return (0, global_settings_1.resolveIssueLogPath)((0, provider_resolution_1.getTrackedProjectStorageSegments)(trackedProject), issueId, homeDirectory);
}
async function readIssueLogText(trackedProject, issueId, homeDirectory = node_os_1.default.homedir()) {
    return (0, file_readers_1.readTextFileIfExists)(getTrackedProjectIssueLogPath(trackedProject, issueId, homeDirectory));
}
async function readServiceLogText(homeDirectory = node_os_1.default.homedir()) {
    return (0, file_readers_1.readTextFileIfExists)((0, paths_1.getServiceLogPath)(homeDirectory));
}
async function listTrackedProjectIssueLogIds(trackedProject, homeDirectory = node_os_1.default.homedir()) {
    const directory = getTrackedProjectIssueLogDirectory(trackedProject, homeDirectory);
    try {
        const entries = await (0, promises_1.readdir)(directory, { withFileTypes: true });
        return entries
            .filter((entry) => entry.isFile())
            .map((entry) => entry.name)
            .map((name) => name.match(/^(\d+)\.log$/)?.[1])
            .filter((issueId) => issueId !== undefined)
            .sort((left, right) => Number(left) - Number(right));
    }
    catch (error) {
        if ((0, fs_errors_1.isMissingFileError)(error)) {
            return [];
        }
        throw error;
    }
}
async function listTrackedProjectIssueLogPaths(trackedProject, homeDirectory = node_os_1.default.homedir()) {
    const issueIds = await listTrackedProjectIssueLogIds(trackedProject, homeDirectory);
    return issueIds.map((issueId) => ({
        issueId,
        path: getTrackedProjectIssueLogPath(trackedProject, issueId, homeDirectory),
    }));
}
function sliceTextTail(text, lineCount) {
    if (lineCount === undefined) {
        return text;
    }
    if (lineCount <= 0) {
        return "";
    }
    const hasTrailingNewline = /\r?\n$/.test(text);
    const lines = splitLogLines(text);
    const output = lines.slice(-lineCount).join("\n");
    if (output.length === 0) {
        return "";
    }
    return hasTrailingNewline ? `${output}\n` : output;
}
async function searchTrackedProjectIssueLogs(trackedProject, query, context = 0, homeDirectory = node_os_1.default.homedir()) {
    const issueLogPaths = await listTrackedProjectIssueLogPaths(trackedProject, homeDirectory);
    const blocks = [];
    for (const { issueId, path: issueLogPath } of issueLogPaths) {
        const text = await (0, file_readers_1.readTextFileIfExists)(issueLogPath);
        if (text === null) {
            continue;
        }
        blocks.push(...searchIssueLogText(issueId, text, query, context));
    }
    return blocks;
}
function searchIssueLogText(issueId, text, query, context = 0) {
    const normalizedQuery = query.toLowerCase();
    const normalizedContext = Math.max(0, context);
    const lines = splitLogLines(text);
    const windows = [];
    for (let lineIndex = 0; lineIndex < lines.length; lineIndex += 1) {
        const line = lines[lineIndex];
        if (line === undefined) {
            continue;
        }
        if (!line.toLowerCase().includes(normalizedQuery)) {
            continue;
        }
        windows.push({
            start: Math.max(0, lineIndex - normalizedContext),
            end: Math.min(lines.length - 1, lineIndex + normalizedContext),
        });
    }
    return mergeContextWindows(windows).map((window) => ({
        issueId,
        lines: lines.slice(window.start, window.end + 1).map((text, index) => ({
            lineNumber: window.start + index + 1,
            text,
        })),
    }));
}
function renderIssueLogSearchBlocks(blocks, locale) {
    return blocks
        .map((block) => [
        (0, catalog_1.translate)(locale, "issue.log.search.issueHeading", {
            issueId: block.issueId,
        }),
        ...block.lines.map((line) => `${line.lineNumber}: ${line.text}`),
    ].join("\n"))
        .join("\n\n");
}
function renderEmptyIssueLogList(locale) {
    return (0, catalog_1.translate)(locale, "issue.log.list.empty");
}
function renderEmptyIssueLogShow(locale, issueId) {
    return (0, catalog_1.translate)(locale, "issue.log.show.empty", { issueId });
}
function renderEmptyIssueLogSearch(locale) {
    return (0, catalog_1.translate)(locale, "issue.log.search.empty");
}
function renderEmptyServiceLog(locale) {
    return (0, catalog_1.translate)(locale, "service.log.show.empty");
}
function formatIssueLogList(issueIds) {
    return issueIds.join("\n");
}
function splitLogLines(text) {
    if (text.length === 0) {
        return [];
    }
    const lines = text.split(/\r?\n/);
    if (lines[lines.length - 1] === "") {
        lines.pop();
    }
    return lines;
}
function mergeContextWindows(windows) {
    if (windows.length === 0) {
        return [];
    }
    const sortedWindows = [...windows].sort((left, right) => left.start - right.start || left.end - right.end);
    const mergedWindows = [];
    const firstWindow = sortedWindows[0];
    if (firstWindow === undefined) {
        return [];
    }
    let currentWindow = firstWindow;
    for (let index = 1; index < sortedWindows.length; index += 1) {
        const nextWindow = sortedWindows[index];
        if (nextWindow === undefined) {
            continue;
        }
        if (nextWindow.start <= currentWindow.end + 1) {
            currentWindow = {
                start: currentWindow.start,
                end: Math.max(currentWindow.end, nextWindow.end),
            };
            continue;
        }
        mergedWindows.push(currentWindow);
        currentWindow = nextWindow;
    }
    mergedWindows.push(currentWindow);
    return mergedWindows;
}
