/**
 * Claude Code session reader
 *
 * Reads Claude Code's sessions-index.json and individual .jsonl session files
 * to extract session metadata and last assistant responses.
 */
import { existsSync, readdirSync, readFileSync, statSync } from 'node:fs';
import { join } from 'node:path';
import { getClaudeProjectSessionsDir } from '../config/project/sessionStore.js';
function buildEntryFromJsonlFile(sessionsDir, fileName) {
    const fullPath = join(sessionsDir, fileName);
    const sessionId = fileName.replace(/\.jsonl$/, '');
    if (!sessionId || sessionId === fileName) {
        return null;
    }
    let firstPrompt = '';
    let messageCount = 0;
    let gitBranch = '';
    let isSidechain = false;
    try {
        const content = readFileSync(fullPath, 'utf-8');
        const lines = content.split('\n').filter((line) => line.trim().length > 0);
        for (const line of lines) {
            let record;
            try {
                record = JSON.parse(line);
            }
            catch {
                continue;
            }
            if (record.type === 'user' || record.type === 'assistant') {
                messageCount += 1;
            }
            if (!gitBranch && typeof record.gitBranch === 'string') {
                gitBranch = record.gitBranch;
            }
            if (record.isSidechain === true) {
                isSidechain = true;
            }
            if (!firstPrompt && record.type === 'user' && Array.isArray(record.message?.content)) {
                const textBlock = record.message.content.find((block) => block.type === 'text' && typeof block.text === 'string');
                if (textBlock?.text) {
                    firstPrompt = textBlock.text.trim();
                }
            }
        }
    }
    catch {
        return null;
    }
    const modified = statSync(fullPath).mtime.toISOString();
    return {
        sessionId,
        firstPrompt: firstPrompt || sessionId,
        modified,
        messageCount,
        gitBranch,
        isSidechain,
        fullPath,
    };
}
function loadSessionIndexFromJsonl(sessionsDir) {
    if (!existsSync(sessionsDir)) {
        return [];
    }
    const jsonlFiles = readdirSync(sessionsDir)
        .filter((name) => name.endsWith('.jsonl'));
    return jsonlFiles
        .map((fileName) => buildEntryFromJsonlFile(sessionsDir, fileName))
        .filter((entry) => entry !== null)
        .filter((entry) => !entry.isSidechain)
        .sort((a, b) => new Date(b.modified).getTime() - new Date(a.modified).getTime());
}
/**
 * Load the session index for a project directory.
 *
 * Reads ~/.claude/projects/{encoded-path}/sessions-index.json,
 * filters out sidechain sessions, and sorts by modified descending.
 */
export function loadSessionIndex(projectDir) {
    const sessionsDir = getClaudeProjectSessionsDir(projectDir);
    const indexPath = join(sessionsDir, 'sessions-index.json');
    if (!existsSync(indexPath)) {
        return loadSessionIndexFromJsonl(sessionsDir);
    }
    const content = readFileSync(indexPath, 'utf-8');
    let index;
    try {
        index = JSON.parse(content);
    }
    catch {
        return loadSessionIndexFromJsonl(sessionsDir);
    }
    if (!index.entries || !Array.isArray(index.entries)) {
        return loadSessionIndexFromJsonl(sessionsDir);
    }
    return index.entries
        .filter((entry) => !entry.isSidechain)
        .sort((a, b) => new Date(b.modified).getTime() - new Date(a.modified).getTime());
}
/**
 * Extract the last assistant text response from a session JSONL file.
 *
 * Reads the file and scans from the end to find the last `type: "assistant"`
 * record with a text content block. Returns the truncated text.
 */
export function extractLastAssistantResponse(sessionFilePath, maxLength) {
    if (!existsSync(sessionFilePath)) {
        return null;
    }
    const content = readFileSync(sessionFilePath, 'utf-8');
    const lines = content.split('\n').filter((line) => line.trim());
    for (let i = lines.length - 1; i >= 0; i--) {
        const line = lines[i];
        if (!line)
            continue;
        let record;
        try {
            record = JSON.parse(line);
        }
        catch {
            continue;
        }
        if (record.type !== 'assistant' || !record.message?.content) {
            continue;
        }
        const textBlocks = record.message.content.filter((block) => block.type === 'text');
        if (textBlocks.length === 0) {
            continue;
        }
        const fullText = textBlocks.map((b) => b.text).join('\n');
        if (fullText.length <= maxLength) {
            return fullText;
        }
        return fullText.slice(0, maxLength) + '…';
    }
    return null;
}
//# sourceMappingURL=session-reader.js.map