#!/usr/bin/env npx tsx
/**
 * Memory-hub smoke: dryrun (always) + optional pgvector when PGVECTOR_TEST_URL is set.
 *
 * SAFETY: this script must NEVER touch a developer's real ~/.priority-forge/team-hub.json.
 * We set PF_HUB_CONFIG_DIR to a per-run tmp directory before importing the hub package.
 */

import * as fs from 'fs';
import * as os from 'os';
import * as path from 'path';

// CRITICAL: set tmp config dir BEFORE importing the hub package so any
// loadTeamHubConfig() call later in this process targets the smoke sandbox,
// not the developer's real ~/.priority-forge/team-hub.json. The hub package
// reads PF_HUB_CONFIG_DIR lazily on every config call, so static imports are
// safe — but keep the env writes above any priority-forge-hub import.
const SMOKE_CONFIG_DIR = fs.mkdtempSync(path.join(os.tmpdir(), 'pf-hub-smoke-'));
process.env.PF_HUB_CONFIG_DIR = SMOKE_CONFIG_DIR;
process.env.MEMHUB_DRYRUN_LOG = path.join(SMOKE_CONFIG_DIR, 'xmem-dryrun.jsonl');

import {
  applyHubConfigureParams,
  dispatchXmemTool,
  DryrunMemoryHub,
  resetMemoryHubCache,
} from 'priority-forge-hub';

const TEAM = 'smoke-team';
const AGENT = 'smoke-agent';

async function smokeDryrunDirect(): Promise<void> {
  const dryrunPath = process.env.MEMHUB_DRYRUN_LOG!;
  if (fs.existsSync(dryrunPath)) fs.unlinkSync(dryrunPath);

  applyHubConfigureParams({
    pulse: { emit: true, userId: AGENT },
    memory: { enabled: true, backend: 'dryrun', teamId: TEAM, agentId: AGENT },
    orchestration: { enabled: true },
  });
  resetMemoryHubCache();

  const hub = new DryrunMemoryHub();
  const event = {
    eventId: '00000000-0000-4000-8000-000000000001',
    teamId: TEAM,
    agentId: AGENT,
    workspaceId: 'default',
    eventType: 'task_created' as const,
    timestamp: new Date().toISOString(),
    payload: { taskId: 'SMOKE-1', task: 'hub smoke task', project: 'smoke' },
    summary: `${AGENT} created SMOKE-1 hub smoke`,
    metadata: {},
  };
  const w = await hub.write(event);
  if (!w.accepted) throw new Error('dryrun write not accepted');

  const read = await hub.read({ teamId: TEAM, limit: 10 });
  if (read.length < 1) throw new Error('dryrun read empty');

  const search = await hub.search(TEAM, 'hub smoke', 5);
  if (search.length < 1) throw new Error('dryrun search empty');

  const status = await dispatchXmemTool('hub_status', {});
  const warnings = (status as { warnings?: string[] }).warnings ?? [];
  console.log('[hub-memory-smoke] dryrun direct OK', { events: read.length, warnings });

  const candidates = await dispatchXmemTool('xmem_list_decay_candidates', { teamId: TEAM });
  console.log('[hub-memory-smoke] decay candidates', candidates);
}

async function main(): Promise<void> {
  await smokeDryrunDirect();
  const pgUrl = process.env.PGVECTOR_TEST_URL;
  if (pgUrl) {
    applyHubConfigureParams({
      memory: {
        enabled: true,
        backend: 'pgvector',
        teamId: TEAM,
        agentId: AGENT,
        pgvector: { connectionString: pgUrl },
      },
      orchestration: { enabled: true },
    });
    resetMemoryHubCache();
    const health = await dispatchXmemTool('hub_status', {});
    console.log('[hub-memory-smoke] pgvector health', health);
  } else {
    console.log('[hub-memory-smoke] skip pgvector (set PGVECTOR_TEST_URL to run)');
  }
}

main()
  .then(() => {
    try {
      fs.rmSync(SMOKE_CONFIG_DIR, { recursive: true, force: true });
    } catch {
      /* ignore */
    }
  })
  .catch((err) => {
    console.error('[hub-memory-smoke] FAILED', err);
    try {
      fs.rmSync(SMOKE_CONFIG_DIR, { recursive: true, force: true });
    } catch {
      /* ignore */
    }
    process.exit(1);
  });
