#!/usr/bin/env node
/**
 * audit-relink — read-only CLI that reports tab↔JSONL relink state for a CTM DB.
 *
 * Usage:
 *   node scripts/audit-relink.js                       # first default DB found
 *   node scripts/audit-relink.js /path/to/task-manager.db
 *   node scripts/audit-relink.js /path/to/task-manager.db --json
 *
 * Opens the DB in readonly mode so it is safe to run against a live CTM.
 */

'use strict';

const fs = require('fs');
const path = require('path');
const Database = require('better-sqlite3');
const { auditRelink } = require('../lib/relink-audit');

const DEFAULT_DB_CANDIDATES = [
  path.join(process.env.HOME || '', '.walle/data/task-manager.db'),
  path.join(process.env.HOME || '', '.claude-task-manager/task-manager.db'),
];

function resolveDbPath(argv) {
  const explicit = argv.find(a => !a.startsWith('-'));
  if (explicit) return explicit;
  for (const p of DEFAULT_DB_CANDIDATES) {
    if (p && fs.existsSync(p)) return p;
  }
  throw new Error('No DB path provided and no default DB found. Pass a path as the first argument.');
}

function pad(s, w) { s = String(s || ''); return s.length >= w ? s : s + ' '.repeat(w - s.length); }

function printTable(tabs) {
  const cols = [
    { k: 'ctm', w: 10, label: 'CTM tab' },
    { k: 'label', w: 22, label: 'Label' },
    { k: 'verdict', w: 14, label: 'Verdict' },
    { k: 'startup', w: 10, label: 'Resume→' },
    { k: 'args', w: 10, label: 'Args→' },
    { k: 'details', w: 50, label: 'Details' },
  ];
  const header = cols.map(c => pad(c.label, c.w)).join(' ');
  console.log(header);
  console.log('-'.repeat(header.length));
  for (const t of tabs) {
    const row = {
      ctm: (t.ctm_session_id || '').slice(0, 8),
      label: (t.label || '').slice(0, 22),
      verdict: t.verdict,
      startup: (t.startup_agent_id || '').slice(0, 8),
      args: (t.args_resume_id || '').slice(0, 8),
      details: t.details && t.details.reason ? t.details.reason : '',
    };
    console.log(cols.map(c => pad(row[c.k], c.w)).join(' '));
  }
}

function main() {
  const argv = process.argv.slice(2);
  const asJson = argv.includes('--json');
  const dbPath = resolveDbPath(argv);

  if (!fs.existsSync(dbPath)) {
    console.error(`DB not found: ${dbPath}`);
    process.exit(1);
  }

  const db = new Database(dbPath, { readonly: true });
  try {
    const result = auditRelink({ db });
    if (asJson) {
      console.log(JSON.stringify(result, null, 2));
      return;
    }
    console.log(`# Relink audit: ${dbPath}`);
    console.log('');
    console.log(`Summary:`);
    console.log(`  total        : ${result.summary.total}`);
    console.log(`  clean        : ${result.summary.clean}`);
    console.log(`  cross_linked : ${result.summary.cross_linked}  ⚠️`);
    console.log(`  stale        : ${result.summary.stale}`);
    console.log(`  orphan       : ${result.summary.orphan}`);
    console.log(`  unclassified : ${result.summary.unclassified}`);
    console.log('');
    printTable(result.tabs);

    if (result.summary.cross_linked > 0) {
      console.log('');
      console.log('--- cross_linked details ---');
      for (const t of result.tabs.filter(x => x.verdict === 'cross_linked')) {
        console.log(`\n${t.ctm_session_id}  "${t.label}"`);
        console.log(`  tab cwd     : ${t.cwd}`);
        console.log(`  startup→    : ${t.startup_agent_id}`);
        for (const a of t.agents) {
          const flag = a.is_startup_target ? ' ← startup target' : '';
          const cwdFlag = a.header_cwd && !a.cwd_matches_tab ? ' ⚠ wrong cwd' : '';
          console.log(`  agent ${a.agent_session_id.slice(0,8)}  size=${a.file_size_on_disk || a.file_size}  cwd=${a.header_cwd || '?'}${flag}${cwdFlag}`);
        }
      }
    }
  } finally {
    db.close();
  }
}

main();
