// Re-derive the stored tree shape for every cached share snapshot, from the folder rows already in
// Postgres — no peer contact, so it works with everyone offline and is deterministic.
//
// Written for the backfill when the tree columns were added, but kept because it's the answer to any
// future change in tree shape: it runs the SAME buildTree + finishSoulseekBrowse the sidecar's ingest
// runs, so there's no second implementation to drift.
//
//   bun scripts/rebuild-soulseek-tree.ts

import type { BrowsedFile } from 'officerdb';
import { eq, asc } from 'drizzle-orm';
import { db, finishSoulseekBrowse } from 'officerdb';
// soulseek is a plugin, so its tables are commented out of officerdb's schema aggregator —
// import them from the feature directly.
import { soulseekBrowseSnapshots, soulseekBrowseDirs } from 'officerdb/soulseek/schema';
import { buildTree } from '../src/servers/sidecar/slskd/browse';

const snapshots = await db
  .select({
    id: soulseekBrowseSnapshots.id,
    userId: soulseekBrowseSnapshots.userId,
    username: soulseekBrowseSnapshots.username,
    status: soulseekBrowseSnapshots.status,
  })
  .from(soulseekBrowseSnapshots)
  .orderBy(asc(soulseekBrowseSnapshots.id));

console.log(`${snapshots.length} snapshot(s) to rebuild`);

for (const snap of snapshots) {
  const started = Date.now();
  const rows = await db
    .select({ name: soulseekBrowseDirs.name, files: soulseekBrowseDirs.files })
    .from(soulseekBrowseDirs)
    .where(eq(soulseekBrowseDirs.snapshotId, snap.id));

  if (!rows.length) {
    console.log(`  #${snap.id} ${snap.username}: no folder rows, skipped`);
    continue;
  }

  const tree = buildTree(rows.map((r) => ({ name: r.name, files: r.files as BrowsedFile[] })));
  await finishSoulseekBrowse(snap.id, tree);
  const roots = tree.filter((t) => t.parentPath === null);
  console.log(
    `  #${snap.id} ${snap.username}: ${rows.length} -> ${tree.length} rows ` +
      `(+${tree.length - rows.length} synthesized), ${roots.length} root(s), ` +
      `${roots.reduce((n, r) => n + r.subtreeFileCount, 0)} files, ${Date.now() - started}ms`,
  );
}

process.exit(0);
