#!/usr/bin/env node
/**
 * Guard 6: Dreaming Phase Guard
 * Prevents dreaming phase proliferation beyond 3 phases.
 * 
 * → Architecture Freeze v2 (PR-1): docs/architecture-freeze-v2.md
 * → Current: light, deep, rem | Legacy: rem → to be replaced by promote
 * 
 * Currently allowed phases: light, deep, rem
 * After PR-5: will be reduced to collect, promote
 * 
 * FAIL: new dreaming phase appears (count > 3)
 * PASS: phase count <= 3
 */

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

const OPENCLAW_HOME = process.env.OPENCLAW_HOME || "/opt/homebrew/lib/node_modules/openclaw";
const EXTENSIONS_DIR = join(OPENCLAW_HOME, "dist", "extensions");

const PHASE_LIMIT = 3; // Current baseline
const POST_PR5_LIMIT = 2; // After PR-5: collect + promote

function guardDreamingPhases() {
  const issues = [];
  let foundPhases = [];
  let source = "none";

  // Check memory-core plugin config schema
  const memoryCorePath = join(EXTENSIONS_DIR, "memory-core", "openclaw.plugin.json");
  if (existsSync(memoryCorePath)) {
    try {
      const plugin = JSON.parse(readFileSync(memoryCorePath, "utf8"));
      const dreaming = plugin.configSchema?.properties?.dreaming;
      if (dreaming) {
        const phases = dreaming.properties?.phases?.properties;
        if (phases) {
          foundPhases = Object.keys(phases);
          source = "memory-core/openclaw.plugin.json → configSchema.properties.dreaming.properties.phases";
        }
      }
    } catch (e) {
      issues.push({ level: "ERROR", msg: `Could not parse memory-core plugin.json: ${e.message}` });
    }
  }

  // Also check active-memory for dreaming references
  const activeMemoryPath = join(EXTENSIONS_DIR, "active-memory", "openclaw.plugin.json");
  if (existsSync(activeMemoryPath)) {
    try {
      const plugin = JSON.parse(readFileSync(activeMemoryPath, "utf8"));
      // Check if active-memory references phases
      const configKeys = Object.keys(plugin.configSchema?.properties || {});
      if (configKeys.includes("dreaming")) {
        // Active memory has dreaming config too
      }
    } catch {}
  }

  console.log("");
  console.log("═══════════════════════════════════════");
  console.log("  Guard 6: Dreaming Phase Guard");
  console.log("═══════════════════════════════════════");
  console.log("");

  if (foundPhases.length === 0) {
    console.log("  No dreaming phases found in plugin config schemas.");
    console.log("  (This may indicate a config schema location change.)");
    issues.push({ level: "WARN", msg: "Could not locate dreaming phases in config schema" });
  } else {
    console.log(`  Source: ${source}`);
    console.log(`  Dreaming phases: ${foundPhases.join(", ")}`);
    console.log(`  Phase count: ${foundPhases.length}`);
    console.log(`  Current limit: ${PHASE_LIMIT} (light, deep, rem)`);
    console.log(`  Post-PR5 limit: ${POST_PR5_LIMIT} (collect, promote)`);

    if (foundPhases.length > PHASE_LIMIT) {
      issues.push({
        level: "FAIL",
        msg: `Dreaming phase count ${foundPhases.length} exceeds limit ${PHASE_LIMIT}`
      });
    } else {
      console.log(`\n  Phase details:`);
      for (const phase of foundPhases) {
        console.log(`    • ${phase}`);
      }
    }
  }

  console.log("");
  for (const issue of issues) {
    console.log(`  [${issue.level}] ${issue.msg}`);
  }

  if (issues.filter(i => i.level === "FAIL").length === 0) {
    console.log("  ✓ PASS: dreaming phase count within allowed limit");
    console.log(`  (After PR-5, limit will be reduced from ${PHASE_LIMIT} → ${POST_PR5_LIMIT})`);
    process.exit(0);
  } else {
    console.log("  ✗ FAIL: dreaming phase count exceeded");
    process.exit(1);
  }
}

guardDreamingPhases();
