import { glob } from 'glob';
import { readFile, readdir, stat, access } from 'fs/promises';
import { constants } from 'fs';
import { join, basename } from 'path';
async function fileExists(path) {
    try {
        await access(path, constants.F_OK);
        return true;
    }
    catch {
        return false;
    }
}
/**
 * Scan .workflow directory for active and archived sessions
 * @param workflowDir - Path to .workflow directory
 * @returns Active and archived sessions
 */
export async function scanSessions(workflowDir) {
    const result = {
        active: [],
        archived: [],
        hasReviewData: false
    };
    if (!await fileExists(workflowDir)) {
        return result;
    }
    // Scan active sessions
    const activeDir = join(workflowDir, 'active');
    if (await fileExists(activeDir)) {
        const activeSessions = await findWfsSessions(activeDir);
        const activeSessionDataPromises = activeSessions.map(async (sessionName) => {
            const sessionPath = join(activeDir, sessionName);
            const sessionData = await readSessionData(sessionPath);
            if (sessionData) {
                // Check for review data
                if (await fileExists(join(sessionPath, '.review'))) {
                    result.hasReviewData = true;
                }
                return {
                    ...sessionData,
                    path: sessionPath,
                    isActive: true
                };
            }
            return null;
        });
        const activeSessionData = (await Promise.all(activeSessionDataPromises)).filter((s) => s !== null);
        result.active.push(...activeSessionData);
    }
    // Scan archived sessions
    const archivesDir = join(workflowDir, 'archives');
    if (await fileExists(archivesDir)) {
        const archivedSessions = await findWfsSessions(archivesDir);
        const archivedSessionDataPromises = archivedSessions.map(async (sessionName) => {
            const sessionPath = join(archivesDir, sessionName);
            const sessionData = await readSessionData(sessionPath);
            if (sessionData) {
                return {
                    ...sessionData,
                    path: sessionPath,
                    isActive: false
                };
            }
            return null;
        });
        const archivedSessionData = (await Promise.all(archivedSessionDataPromises)).filter((s) => s !== null);
        result.archived.push(...archivedSessionData);
    }
    // Sort by creation date (newest first)
    result.active.sort((a, b) => new Date(b.created || 0).getTime() - new Date(a.created || 0).getTime());
    result.archived.sort((a, b) => {
        const aDate = a.archived_at || a.created || 0;
        const bDate = b.archived_at || b.created || 0;
        return new Date(bDate).getTime() - new Date(aDate).getTime();
    });
    return result;
}
/**
 * Find WFS-* directories in a given path
 * @param dir - Directory to search
 * @returns Array of session directory names
 */
async function findWfsSessions(dir) {
    try {
        // Use glob for cross-platform pattern matching
        const sessions = await glob('WFS-*/', {
            cwd: dir,
            absolute: false
        });
        // Remove trailing slashes from directory names
        return sessions.map(s => s.replace(/\/$/, ''));
    }
    catch {
        // Fallback: manual directory listing
        try {
            const entries = await readdir(dir, { withFileTypes: true });
            return entries
                .filter(e => e.isDirectory() && e.name.startsWith('WFS-'))
                .map(e => e.name);
        }
        catch {
            return [];
        }
    }
}
/**
 * Parse timestamp from session name
 * Supports formats: WFS-xxx-20251128172537 or WFS-xxx-20251120-170640
 * @param sessionName - Session directory name
 * @returns ISO date string or null
 */
function parseTimestampFromName(sessionName) {
    // Format: 14-digit timestamp (YYYYMMDDHHmmss)
    const match14 = sessionName.match(/(\d{14})$/);
    if (match14) {
        const ts = match14[1];
        return `${ts.slice(0, 4)}-${ts.slice(4, 6)}-${ts.slice(6, 8)}T${ts.slice(8, 10)}:${ts.slice(10, 12)}:${ts.slice(12, 14)}Z`;
    }
    // Format: 8-digit date + 6-digit time separated by hyphen (YYYYMMDD-HHmmss)
    const match8_6 = sessionName.match(/(\d{8})-(\d{6})$/);
    if (match8_6) {
        const d = match8_6[1];
        const t = match8_6[2];
        return `${d.slice(0, 4)}-${d.slice(4, 6)}-${d.slice(6, 8)}T${t.slice(0, 2)}:${t.slice(2, 4)}:${t.slice(4, 6)}Z`;
    }
    return null;
}
/**
 * Infer session type from session name pattern
 * @param sessionName - Session directory name
 * @returns Inferred type
 */
function inferTypeFromName(sessionName) {
    const name = sessionName.toLowerCase();
    if (name.includes('-review-') || name.includes('-code-review-')) {
        return 'review';
    }
    if (name.includes('-test-')) {
        return 'test';
    }
    if (name.includes('-docs-')) {
        return 'docs';
    }
    if (name.includes('-tdd-')) {
        return 'tdd';
    }
    return 'workflow';
}
/**
 * Read session data from workflow-session.json or create minimal from directory
 * @param sessionPath - Path to session directory
 * @returns Session data object or null if invalid
 */
async function readSessionData(sessionPath) {
    const sessionFile = join(sessionPath, 'workflow-session.json');
    const sessionName = basename(sessionPath);
    if (await fileExists(sessionFile)) {
        try {
            const data = JSON.parse(await readFile(sessionFile, 'utf8'));
            // Multi-level type detection: JSON type > workflow_type > infer from name
            let type = data.type || data.workflow_type || inferTypeFromName(sessionName);
            // Normalize workflow_type values
            if (type === 'test_session')
                type = 'test';
            if (type === 'implementation')
                type = 'workflow';
            return {
                id: data.session_id || sessionName,
                type,
                status: data.status || 'active',
                project: data.project || data.description || '',
                description: data.description || data.project || '',
                created: data.created_at || data.initialized_at || data.timestamp || '',
                updated: data.updated_at || data.created_at || '',
                path: sessionPath,
                isActive: true,
                archived_at: data.archived_at || null,
                workflow_type: data.workflow_type || null // Keep original for reference
            };
        }
        catch {
            // Fall through to minimal session
        }
    }
    // Fallback: create minimal session from directory info
    // Try to extract timestamp from session name first
    const timestampFromName = parseTimestampFromName(sessionName);
    const inferredType = inferTypeFromName(sessionName);
    try {
        const stats = await stat(sessionPath);
        const createdAt = timestampFromName || stats.birthtime.toISOString();
        return {
            id: sessionName,
            type: inferredType,
            status: 'active',
            project: '',
            description: '',
            created: createdAt,
            updated: createdAt,
            path: sessionPath,
            isActive: true,
            archived_at: null,
            workflow_type: null
        };
    }
    catch {
        // Even if stat fails, return with name-extracted data
        if (timestampFromName) {
            return {
                id: sessionName,
                type: inferredType,
                status: 'active',
                project: '',
                description: '',
                created: timestampFromName,
                updated: timestampFromName,
                path: sessionPath,
                isActive: true,
                archived_at: null,
                workflow_type: null
            };
        }
        return null;
    }
}
/**
 * Check if session has review data
 * @param sessionPath - Path to session directory
 * @returns True if review data exists
 */
export async function hasReviewData(sessionPath) {
    const reviewDir = join(sessionPath, '.review');
    return await fileExists(reviewDir);
}
/**
 * Get list of task files in session
 * @param sessionPath - Path to session directory
 * @returns Array of task file names
 */
export async function getTaskFiles(sessionPath) {
    const taskDir = join(sessionPath, '.task');
    if (!await fileExists(taskDir)) {
        return [];
    }
    try {
        return await glob('IMPL-*.json', { cwd: taskDir, absolute: false });
    }
    catch {
        return [];
    }
}
//# sourceMappingURL=session-scanner.js.map