"use strict";
// src/test_catalog_promotion.ts
// Phase 6: CatalogPromotion records execution outcomes and auto-promotes a
// draft catalog agent to active once it clears the success/score threshold.
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 fs = __importStar(require("fs"));
const os = __importStar(require("os"));
const path = __importStar(require("path"));
const CatalogPromotion_1 = require("./orchestrator/CatalogPromotion");
const PerformanceScorecard_1 = require("./orchestrator/PerformanceScorecard");
let passed = 0;
let failed = 0;
function check(label, ok, detail) {
    if (ok) {
        console.log(`  ✓ ${label}`);
        passed++;
    }
    else {
        console.error(`  ✗ ${label}${detail ? ` — ${detail}` : ''}`);
        failed++;
    }
}
function makeDraftAgent(root, id, status = 'draft') {
    const dir = path.join(root, '.catalog', 'agents', id);
    fs.mkdirSync(dir, { recursive: true });
    fs.writeFileSync(path.join(dir, 'AGENT.md'), `---\nid: ${id}\nname: ${id}\nrole: specialist\nstatus: ${status}\n---\n\n# ${id}\n\nTest agent.\n`, 'utf-8');
}
function statusOf(root, id) {
    const f = path.join(root, '.catalog', 'agents', id, 'AGENT.md');
    const m = fs.readFileSync(f, 'utf-8').match(/^status:\s*(\S+)/m);
    return m?.[1] ?? null;
}
async function main() {
    console.log('test_catalog_promotion: starting\n');
    const tmp = fs.mkdtempSync(path.join(os.tmpdir(), 'openlife-promo-'));
    const prevRoots = process.env.OPENLIFE_AGENT_ROOTS;
    const prevCwd = process.cwd();
    // Point both the agent roots AND the scorecard (cwd-based) at the temp dir.
    process.env.OPENLIFE_AGENT_ROOTS = path.join(tmp, '.catalog', 'agents');
    process.chdir(tmp);
    try {
        makeDraftAgent(tmp, 'fresh-draft');
        makeDraftAgent(tmp, 'active-already', 'active');
        const promo = new CatalogPromotion_1.CatalogPromotion({ minSuccesses: 3, minScore: 4, scorecard: new PerformanceScorecard_1.PerformanceScorecard() });
        console.log('[1] draft with no track record is not promoted');
        const r0 = promo.maybePromote('fresh-draft');
        check('no_track_record before any run', r0.promoted === false && r0.reason === 'no_track_record', r0.reason);
        console.log('\n[2] below threshold stays draft');
        promo.recordOutcome('fresh-draft', true); // 1 success
        const r1 = promo.maybePromote('fresh-draft');
        check('still draft after 1 success', r1.promoted === false && r1.reason === 'below_threshold', r1.reason);
        check('disk status still draft', statusOf(tmp, 'fresh-draft') === 'draft');
        console.log('\n[3] clearing threshold promotes draft → active');
        promo.recordExecution('fresh-draft', true); // 2
        promo.recordExecution('fresh-draft', true); // 3 → should trip promotion inside recordExecution
        check('disk status flipped to active', statusOf(tmp, 'fresh-draft') === 'active');
        console.log('\n[4] promotion is idempotent');
        const r2 = promo.maybePromote('fresh-draft');
        check('re-promote is no-op (already_active)', r2.promoted === false && r2.reason === 'already_active', r2.reason);
        console.log('\n[5] already-active agent is never re-promoted');
        promo.recordOutcome('active-already', true);
        promo.recordOutcome('active-already', true);
        promo.recordOutcome('active-already', true);
        const r3 = promo.maybePromote('active-already');
        check('already_active reason', r3.promoted === false && r3.reason === 'already_active', r3.reason);
        console.log('\n[6] unknown / non-catalog agent → not_a_catalog_agent');
        const r4 = promo.maybePromote('__ghost__');
        check('ghost → not_a_catalog_agent', r4.promoted === false && r4.reason === 'not_a_catalog_agent', r4.reason);
        console.log('\n[7] path traversal rejected');
        const r5 = promo.maybePromote('../../etc');
        check('traversal → not_a_catalog_agent', r5.promoted === false && r5.reason === 'not_a_catalog_agent');
        console.log('\n[8] failures do not promote');
        makeDraftAgent(tmp, 'failing-draft');
        promo.recordExecution('failing-draft', false);
        promo.recordExecution('failing-draft', false);
        promo.recordExecution('failing-draft', false);
        check('failing draft stays draft', statusOf(tmp, 'failing-draft') === 'draft');
    }
    finally {
        process.chdir(prevCwd);
        if (prevRoots === undefined)
            delete process.env.OPENLIFE_AGENT_ROOTS;
        else
            process.env.OPENLIFE_AGENT_ROOTS = prevRoots;
        try {
            fs.rmSync(tmp, { recursive: true, force: true });
        }
        catch { /* ignore */ }
    }
    console.log('');
    console.log(`Results: ${passed} passed, ${failed} failed`);
    if (failed > 0) {
        console.error('TEST_CATALOG_PROMOTION_FAIL');
        process.exit(1);
    }
    console.log('✅ test_catalog_promotion: all checks passed');
}
main().catch(err => { console.error(err); process.exit(1); });
