import { existsSync, readdirSync, statSync } from "node:fs";
import { join } from "node:path";

import { BRAIN_INBOX_REL, BRAIN_PREFERENCES_REL, BRAIN_RETIRED_REL } from "../brain/paths.ts";
import type { ActivityWindow } from "./activity-git.ts";

export interface VaultDelta {
  readonly newSignals: number;
  readonly newPreferences: number;
  readonly newRetired: number;
  readonly total: number;
}

function countInWindow(dir: string, win: ActivityWindow): number {
  if (!existsSync(dir)) return 0;
  // Mirror the defensive shape from activity-mtime: readdirSync /
  // statSync can race with concurrent writers (dream pass, signal
  // import) and would otherwise crash the nightly cron with an
  // unhandled ENOENT/EPERM.
  let entries: string[];
  try {
    entries = readdirSync(dir);
  } catch {
    return 0;
  }
  let n = 0;
  for (const name of entries) {
    const p = join(dir, name);
    let st;
    try {
      st = statSync(p);
    } catch {
      continue;
    }
    if (!st.isFile()) continue;
    if (st.mtimeMs >= win.startUtc.getTime() && st.mtimeMs < win.endUtc.getTime()) n += 1;
  }
  return n;
}

export function vaultDelta(vault: string, win: ActivityWindow): VaultDelta {
  const newSignals = countInWindow(join(vault, BRAIN_INBOX_REL), win);
  const newPreferences = countInWindow(join(vault, BRAIN_PREFERENCES_REL), win);
  const newRetired = countInWindow(join(vault, BRAIN_RETIRED_REL), win);
  return {
    newSignals,
    newPreferences,
    newRetired,
    total: newSignals + newPreferences + newRetired,
  };
}
