"use strict";
/**
 * test_royal_stack_golden.ts — Story 7.3
 *
 * Golden end-to-end test for v1.2 "Royal Stack".
 *
 * Asserts that the three pillars (Workflow + Squad/Skill Creators + Autonomy)
 * cooperate inside a single CLI session against an isolated working tree.
 *
 * Sequence (all under a temp directory rooted at .artifacts/test_royal_stack/):
 *   1. Build a tiny squad via SquadCreator (rendered from dist-templates/).
 *   2. Build a tiny skill via SkillCreator.
 *   3. Validate both via the CLI.
 *   4. List built-in workflows via the CLI — assert 4 are present.
 *   5. Validate one of the built-in workflows.
 *   6. Run a workflow in dry-run mode and assert the state file is persisted.
 *   7. Acquire and release a distributed lock to prove autonomy primitives work.
 *
 * Budget: under 60 seconds, no network calls, no LLM spend.
 */
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
    var ownKeys = function(o) {
        ownKeys = Object.getOwnPropertyNames || function (o) {
            var ar = [];
            for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
            return ar;
        };
        return ownKeys(o);
    };
    return function (mod) {
        if (mod && mod.__esModule) return mod;
        var result = {};
        if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
        __setModuleDefault(result, mod);
        return result;
    };
})();
Object.defineProperty(exports, "__esModule", { value: true });
const child_process_1 = require("child_process");
const fs = __importStar(require("fs"));
const path = __importStar(require("path"));
const os = __importStar(require("os"));
const CLI = path.join(process.cwd(), 'dist', 'index.js');
function cli(args, env) {
    const r = (0, child_process_1.spawnSync)('node', [CLI, ...args], {
        encoding: 'utf-8',
        timeout: 30000,
        env: { ...process.env, ...(env || {}) },
    });
    return { ok: r.status === 0, status: r.status, stdout: r.stdout || '', stderr: r.stderr || '' };
}
function parseJson(stdout) {
    // CLI prints surrounding chatter; pluck the first {...} block.
    const m = stdout.match(/\{[\s\S]*\}\s*$/);
    if (!m)
        throw new Error(`No JSON found in stdout:\n${stdout.slice(0, 400)}`);
    return JSON.parse(m[0]);
}
function makeTempDir(prefix) {
    const root = fs.mkdtempSync(path.join(os.tmpdir(), prefix));
    return root;
}
function assertTrue(cond, label) {
    if (!cond)
        throw new Error(`ASSERT_FAILED[${label}]`);
}
function main() {
    const sandboxRoot = makeTempDir('openlife-royal-stack-');
    console.log(`[golden] sandbox: ${sandboxRoot}`);
    // Per-test catalog + state isolation via env overrides.
    const env = {
        OPENLIFE_STATE_DIR: path.join(sandboxRoot, '.openlife'),
        OPENLIFE_SQUAD_ROOT: path.join(sandboxRoot, '.catalog', 'squads'),
        OPENLIFE_SKILL_ROOT: path.join(sandboxRoot, '.catalog', 'skills'),
    };
    fs.mkdirSync(env.OPENLIFE_STATE_DIR, { recursive: true });
    fs.mkdirSync(env.OPENLIFE_SQUAD_ROOT, { recursive: true });
    fs.mkdirSync(env.OPENLIFE_SKILL_ROOT, { recursive: true });
    try {
        // === Pillar 1: SquadCreator + SkillCreator (in-process — these aren't yet
        // exposed via the CLI under sandbox env in a single shot; we call the
        // classes directly to keep the test hermetic and fast.) ===
        const { SquadCreator } = require(path.join(process.cwd(), 'dist', 'orchestrator', 'SquadCreator.js'));
        const { SkillCreator } = require(path.join(process.cwd(), 'dist', 'orchestrator', 'SkillCreator.js'));
        const sc = new SquadCreator({ catalogRoot: env.OPENLIFE_SQUAD_ROOT });
        const squadResult = sc.create({
            id: 'rs-golden-squad',
            name: 'royal-stack-golden',
            description: 'Sentinel squad for the Royal Stack golden test.',
            version: '1.0.0',
            agents: [
                { id: 'agent-one', role: 'planner', description: 'Plans the work.' },
            ],
            tasks: [
                { id: 'task-one', title: 'Discover', description: 'Discover the scope.' },
            ],
        });
        assertTrue(squadResult.ok, 'SquadCreator.create ok');
        console.log(`[golden] squad created at ${squadResult.squadDir}`);
        const squadValidation = sc.validate('rs-golden-squad');
        assertTrue(squadValidation.ok, 'SquadCreator.validate ok');
        const skc = new SkillCreator({ catalogRoot: env.OPENLIFE_SKILL_ROOT });
        const skillResult = skc.create({
            id: 'rs-golden-skill',
            name: 'royal-stack-golden-skill',
            description: 'Sentinel skill for the Royal Stack golden test.',
            whenToUse: ['When validating the Royal Stack pipeline'],
            procedure: ['Run the test', 'Inspect the artifacts'],
        });
        assertTrue(skillResult.ok, 'SkillCreator.create ok');
        console.log(`[golden] skill created at ${skillResult.filePath}`);
        // === Pillar 2: Workflow list/validate/run (via CLI, hits real WorkflowEngine) ===
        const listResult = cli(['workflow', 'list'], env);
        assertTrue(listResult.ok, `workflow list ok (status=${listResult.status})`);
        const listPayload = parseJson(listResult.stdout);
        assertTrue(listPayload.ok && Array.isArray(listPayload.workflows), 'workflow list payload shape');
        assertTrue(listPayload.workflows.length >= 4, `workflow list >= 4 (got ${listPayload.workflows.length})`);
        console.log(`[golden] workflow list: ${listPayload.workflows.map((w) => w.id).join(', ')}`);
        const targetWorkflow = listPayload.workflows[0];
        const validateResult = cli(['workflow', 'validate', targetWorkflow.filePath], env);
        assertTrue(validateResult.ok, `workflow validate ${targetWorkflow.id} ok`);
        const runResult = cli(['workflow', 'run', targetWorkflow.filePath, '--dry-run'], env);
        assertTrue(runResult.ok, `workflow run --dry-run ok (status=${runResult.status})`);
        const runPayload = parseJson(runResult.stdout);
        assertTrue(runPayload.ok, 'workflow run payload ok');
        const runId = runPayload.state?.runId;
        assertTrue(typeof runId === 'string' && runId.length > 0, 'runId present');
        console.log(`[golden] workflow run ${targetWorkflow.id} → runId=${runId} state=${runPayload.state?.status}`);
        // Confirm state file was persisted under sandbox .openlife/
        const stateFile = path.join(env.OPENLIFE_STATE_DIR, 'workflows', `${runId}.json`);
        assertTrue(fs.existsSync(stateFile), `workflow state file persisted at ${stateFile}`);
        const statusResult = cli(['workflow', 'status', runId], env);
        assertTrue(statusResult.ok, 'workflow status ok');
        // === Pillar 3: Autonomy primitives (DistributedLock in-process) ===
        const { DistributedLock } = require(path.join(process.cwd(), 'dist', 'orchestrator', 'util', 'DistributedLock.js'));
        const lock = new DistributedLock({ stateDir: env.OPENLIFE_STATE_DIR });
        const acquired = lock.acquire('rs-golden-lock', 5000);
        assertTrue(acquired.ok, 'lock acquire ok');
        const reacquired = lock.acquire('rs-golden-lock', 5000);
        assertTrue(!reacquired.ok, 'second lock acquire blocked while held');
        lock.release(acquired.lockId); // returns void; throws on failure
        // Peek confirms the lock is gone.
        assertTrue(lock.peek('rs-golden-lock') === null, 'lock peek empty after release');
        const reacquiredAfterRelease = lock.acquire('rs-golden-lock', 5000);
        assertTrue(reacquiredAfterRelease.ok, 'lock re-acquirable after release');
        lock.release(reacquiredAfterRelease.lockId);
        console.log('[golden] all three pillars cooperate.');
        console.log('TEST_ROYAL_STACK_GOLDEN_OK');
    }
    finally {
        try {
            fs.rmSync(sandboxRoot, { recursive: true, force: true });
        }
        catch { /* ignore */ }
    }
}
try {
    main();
}
catch (err) {
    console.error('[golden] FAILED:', err instanceof Error ? err.message : err);
    process.exit(1);
}
