/**
 * studiograph reset — single destructive verb family.
 *
 * Subcommands:
 *   reset entities    — local. Wipes repo dirs + populate-cache + staging
 *                       + legacy private/ (today's pre-C5 `reset` behavior).
 *                       Stale-cache caveat: leaves the local LanceDB vector
 *                       index, Yjs snapshots, and any *.db WAL state alone.
 *                       The next `serve` boot does an incremental reindex
 *                       (A1) which catches the deleted files; stale Yjs
 *                       state is harmless for fresh-on-disk repos.
 *   reset sessions    — local. Wipes `~/.studiograph/sessions/`.
 *   reset memory      — local. Wipes `~/.studiograph/memory/`.
 *   reset --remote    — server-side reset for THE CALLING USER. POSTs to
 *                       `/api/reset` which scopes to the bearer-token's
 *                       userId: wipes that user's sessions, memory,
 *                       onboarding flag, and meeting-capture settings.
 *                       Other users' state is
 *                       untouched — the wire shape of `/api/reset` doesn't
 *                       expose a workspace-wide nuke. Auth via sg_ token.
 *
 * Why one verb, four nouns: pre-C5 had `reset` (entities, local) AND
 * `clear` (sessions/memory, local + remote) AND `clear --remote --reset`
 * (the server nuke). Three commands for the same destructive verb family.
 * Codex review surfaced the overlap; cli-owner-audit §3.3 collapsed them.
 */
import { Command } from 'commander';
import { existsSync, rmSync, readdirSync, statSync } from 'fs';
import { homedir } from 'os';
import { join, relative } from 'path';
import { confirm, intro, outro, isCancel, cancel, log } from '@clack/prompts';
import { Workspace } from '../../core/workspace.js';
import { getStudiographToken } from '../../core/user-config.js';
const STUDIOGRAPH_DIR = join(homedir(), '.studiograph');
// ── reset entities ──────────────────────────────────────────────────────────
async function runResetEntities(opts) {
    const workspacePath = process.cwd();
    const workspace = new Workspace(workspacePath);
    if (!workspace.isWorkspace()) {
        console.error('Not in a Studiograph workspace. Nothing to reset.');
        process.exit(1);
    }
    const config = await workspace.loadConfig();
    const repos = config.repos ?? [];
    if (repos.length === 0) {
        console.log('No repos registered in workspace config. Nothing to reset.');
        return;
    }
    // Collect directories that will be removed
    const toRemove = [];
    for (const repo of repos) {
        const repoPath = join(workspacePath, repo.path);
        if (!existsSync(repoPath))
            continue;
        toRemove.push({ name: repo.name, path: repoPath, entityCount: countEntities(repoPath) });
    }
    if (toRemove.length === 0) {
        console.log('All repo directories already removed. Nothing to reset.');
        return;
    }
    if (!opts.yes) {
        intro('Reset entities');
        console.log('This will remove all entity data:\n');
        let totalEntities = 0;
        for (const item of toRemove) {
            const rel = relative(workspacePath, item.path);
            console.log(`  ${rel.padEnd(30)} ${item.entityCount} entities`);
            totalEntities += item.entityCount;
        }
        console.log(`\n  Total: ${totalEntities} entities across ${toRemove.length} repos`);
        console.log('  Preserved: .studiograph/ (config, team, migrations)');
        console.log('  Stale leftovers: vector index + Yjs state. The next `serve`');
        console.log('  boot rebuilds the index incrementally (A1).');
        const proceed = await confirm({ message: 'Are you sure you want to reset?' });
        if (isCancel(proceed) || !proceed) {
            cancel('Reset cancelled.');
            process.exit(0);
        }
    }
    for (const item of toRemove) {
        rmSync(item.path, { recursive: true, force: true });
        console.log(`  Removed ${item.name} (${item.entityCount} entities)`);
    }
    // Clear caches that point at the now-deleted files.
    const populateCachePath = join(workspacePath, '.studiograph', 'populate-cache');
    if (existsSync(populateCachePath)) {
        rmSync(populateCachePath, { recursive: true, force: true });
        console.log('  Cleared populate cache');
    }
    const stagingPath = join(workspacePath, '.studiograph', 'staging');
    if (existsSync(stagingPath)) {
        rmSync(stagingPath, { recursive: true, force: true });
        console.log('  Cleared staging');
    }
    // Remove legacy private graph if present.
    const privatePath = join(workspacePath, 'private');
    if (existsSync(privatePath)) {
        rmSync(privatePath, { recursive: true, force: true });
        console.log('  Removed legacy private graph');
    }
    outro('Workspace entities reset. Re-run sync or create entries to repopulate.');
}
// ── reset sessions / memory ─────────────────────────────────────────────────
function clearLocalDir(dirPath, ext) {
    if (!existsSync(dirPath))
        return 0;
    const files = readdirSync(dirPath).filter((f) => f.endsWith(ext));
    for (const f of files)
        rmSync(join(dirPath, f));
    return files.length;
}
function runResetSessions() {
    const count = clearLocalDir(join(STUDIOGRAPH_DIR, 'sessions'), '.json');
    console.log(`Cleared ${count} session${count === 1 ? '' : 's'}`);
}
function runResetMemory() {
    const count = clearLocalDir(join(STUDIOGRAPH_DIR, 'memory'), '.md');
    console.log(`Cleared ${count} memory file${count === 1 ? '' : 's'}`);
}
// ── reset --remote ──────────────────────────────────────────────────────────
async function runResetRemote(opts) {
    const workspace = new Workspace();
    if (!workspace.isWorkspace()) {
        console.error('Not in a Studiograph workspace. Cannot resolve server URL.');
        process.exit(1);
    }
    const config = await workspace.loadConfig();
    const serverUrl = config.server_url?.replace(/\/+$/, '');
    if (!serverUrl) {
        console.error('No server URL configured. `reset --remote` requires a workspace cloned via `studiograph clone <url>`.');
        process.exit(1);
    }
    const token = opts.token?.trim() || process.env.STUDIOGRAPH_TOKEN?.trim() || getStudiographToken(serverUrl);
    if (!token) {
        console.error(`No API token for ${serverUrl}. Run \`studiograph admin token issue ${serverUrl}\` to mint one, or pass --token / STUDIOGRAPH_TOKEN.`);
        process.exit(1);
    }
    if (!opts.yes) {
        intro('Reset remote user state');
        log.warn(`This will wipe YOUR sessions + memory on ${serverUrl} AND reset YOUR onboarding flag and meeting-capture settings. Other users on this workspace are unaffected — the API endpoint is per-user.`);
        const proceed = await confirm({ message: 'Continue?' });
        if (isCancel(proceed) || !proceed) {
            cancel('Reset cancelled.');
            process.exit(0);
        }
    }
    const res = await fetch(`${serverUrl}/api/reset`, {
        method: 'POST',
        headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
        body: '{}',
    });
    if (!res.ok) {
        const body = (await res.json().catch(() => ({})));
        console.error(`Reset failed (${res.status}): ${body.error || res.statusText}`);
        process.exit(1);
    }
    const result = (await res.json());
    const c = result.cleared ?? { sessions: 0, memory: 0 };
    outro(`Cleared ${c.sessions} session${c.sessions === 1 ? '' : 's'} and ${c.memory} memory file${c.memory === 1 ? '' : 's'} on ${serverUrl}${result.dbStateReset ? ' (+ DB state)' : ''}.`);
}
// ── Command wiring ──────────────────────────────────────────────────────────
export const resetCommand = new Command('reset').description('Reset workspace state (entities / sessions / memory / remote)');
resetCommand
    .command('entities')
    .description('Wipe all entity data (repo dirs + populate-cache + staging). Local only.')
    .option('--yes', 'Skip confirmation prompt')
    .action(runResetEntities);
resetCommand
    .command('sessions')
    .description('Wipe local agent sessions (~/.studiograph/sessions/).')
    .action(runResetSessions);
resetCommand
    .command('memory')
    .description('Wipe local agent memory (~/.studiograph/memory/).')
    .action(runResetMemory);
// `reset --remote` is a top-level flag on the parent rather than a separate
// subcommand so the destructive operation reads naturally ("reset --remote",
// not "reset remote"). Mirrors how `git reset --hard` works.
resetCommand
    .option('--remote', 'Reset your server-side state: your sessions + memory + DB-backed flags (onboarding, meeting-capture). Per-user — other users on this workspace are unaffected.')
    .option('--yes', 'Skip confirmation prompt')
    .option('--token <token>', 'sg_ API token (also reads STUDIOGRAPH_TOKEN). Used with --remote.')
    .action(async function (opts) {
    if (opts.remote) {
        await runResetRemote(opts);
        return;
    }
    // No subcommand + no --remote: print usage and exit non-zero so scripts
    // don't accidentally treat a bare `studiograph reset` as a success.
    console.error('Specify a target: `reset entities`, `reset sessions`, `reset memory`, or `reset --remote`.');
    console.error('Run `studiograph reset --help` for details.');
    process.exit(1);
});
// ── Internals ───────────────────────────────────────────────────────────────
function countEntities(dir) {
    let count = 0;
    try {
        const entries = readdirSync(dir);
        for (const entry of entries) {
            const full = join(dir, entry);
            try {
                const stat = statSync(full);
                if (stat.isDirectory()) {
                    count += countEntities(full);
                }
                else if (entry.endsWith('.md')) {
                    count++;
                }
            }
            catch { /* skip inaccessible entries */ }
        }
    }
    catch { /* skip inaccessible directories */ }
    return count;
}
//# sourceMappingURL=reset.js.map