/**
 * Vigthoria CLI — Workspace Hash Cache
 *
 * Persists SHA-256 hashes of workspace files in .vigthoria/file-hashes.json.
 * Allows the CLI to sort files by change status before sending them to V3:
 *   - Changed/new files → sent first (highest budget priority)
 *   - Unchanged files → sent last (trimmed by budget if token limit reached)
 */
import { createHash } from 'node:crypto';
import fs from 'node:fs';
import path from 'node:path';
const CACHE_SUBDIR = '.vigthoria';
const CACHE_FILENAME = 'file-hashes.json';
function getCachePath(workspacePath) {
    return path.join(workspacePath, CACHE_SUBDIR, CACHE_FILENAME);
}
function hashFile(absPath) {
    try {
        return createHash('sha256').update(fs.readFileSync(absPath)).digest('hex');
    }
    catch {
        return '';
    }
}
function loadCache(workspacePath) {
    try {
        return JSON.parse(fs.readFileSync(getCachePath(workspacePath), 'utf-8'));
    }
    catch {
        return {};
    }
}
function persistCache(workspacePath, hashes) {
    try {
        const cacheDir = path.join(workspacePath, CACHE_SUBDIR);
        if (!fs.existsSync(cacheDir))
            fs.mkdirSync(cacheDir, { recursive: true });
        fs.writeFileSync(getCachePath(workspacePath), JSON.stringify(hashes, null, 2), 'utf-8');
    }
    catch { /* non-fatal */ }
}
/**
 * Partition file paths into changed and unchanged sets.
 *
 * @param workspacePath  Absolute project root.
 * @param relativePaths  Workspace-relative (or absolute) file paths to check.
 */
export function getChangedFiles(workspacePath, relativePaths) {
    const cache = loadCache(workspacePath);
    const changed = [];
    const unchanged = [];
    for (const rel of relativePaths) {
        const abs = path.isAbsolute(rel) ? rel : path.join(workspacePath, rel);
        const key = path.relative(workspacePath, abs).replace(/\\/g, '/');
        const currentHash = hashFile(abs);
        if (!currentHash || cache[key] !== currentHash) {
            changed.push(rel);
        }
        else {
            unchanged.push(rel);
        }
    }
    return { changed, unchanged, total: relativePaths.length };
}
/**
 * Write current hashes for the given files into the persistent cache.
 * Call this after an agent run completes successfully.
 */
export function updateWorkspaceCache(workspacePath, relativePaths) {
    if (!workspacePath || !fs.existsSync(workspacePath))
        return;
    const cache = loadCache(workspacePath);
    for (const rel of relativePaths) {
        const abs = path.isAbsolute(rel) ? rel : path.join(workspacePath, rel);
        const key = path.relative(workspacePath, abs).replace(/\\/g, '/');
        const hash = hashFile(abs);
        if (hash)
            cache[key] = hash;
    }
    persistCache(workspacePath, cache);
}
/**
 * Return a human-readable summary of changes since last cache update.
 */
export function summarizeChanges(workspacePath, relativePaths) {
    const { changed, unchanged, total } = getChangedFiles(workspacePath, relativePaths);
    return `${changed.length} changed, ${unchanged.length} unchanged of ${total} files tracked`;
}
