"use strict";
/**
 * test_agent_discovery — v1.11.0 regression suite.
 *
 * Asserts:
 *   1. cwd-local manifest takes precedence over home-scoped manifest
 *   2. Staleness classification matches HEARTBEAT_FRESH/STALE thresholds
 *   3. Missing manifest returns liveness='missing'
 *   4. Malformed manifest is skipped (treated as missing)
 */
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 AgentDiscovery_1 = require("./cli/AgentDiscovery");
const GatewayManifest_1 = require("./orchestrator/util/GatewayManifest");
function assert(cond, msg) {
    if (!cond)
        throw new Error(`assertion failed: ${msg}`);
}
function mkTmp() {
    return fs.mkdtempSync(path.join(os.tmpdir(), 'discovery-test-'));
}
function rmTmp(dir) {
    try {
        fs.rmSync(dir, { recursive: true, force: true });
    }
    catch { /* ignore */ }
}
function writeManifest(dir, refreshedAt, token = 'a'.repeat(64)) {
    fs.mkdirSync(dir, { recursive: true });
    const file = path.join(dir, GatewayManifest_1.MANIFEST_FILENAME);
    fs.writeFileSync(file, JSON.stringify({
        schemaVersion: 1,
        host: '127.0.0.1',
        port: 3000,
        token,
        pid: process.pid,
        profile: 'autonomous',
        startedAt: refreshedAt,
        refreshedAt,
        telegram: { enabled: false },
    }, null, 2));
}
function scenarioCwdPrecedence() {
    const tmpHome = mkTmp();
    const tmpCwd = mkTmp();
    const prevHome = process.env.HOME;
    const prevState = process.env.OPENLIFE_STATE_DIR;
    try {
        process.env.HOME = tmpHome;
        process.env.OPENLIFE_STATE_DIR = path.join(tmpCwd, '.openlife');
        writeManifest(path.join(tmpHome, '.openlife'), new Date().toISOString(), 'h'.repeat(64));
        writeManifest(process.env.OPENLIFE_STATE_DIR, new Date().toISOString(), 'c'.repeat(64));
        const info = (0, AgentDiscovery_1.discover)();
        assert(info.alive === true, 'must be alive');
        assert(info.source === 'cwd', `expected source=cwd got ${info.source}`);
        assert(info.manifest.token === 'c'.repeat(64), 'must pick cwd manifest');
    }
    finally {
        if (prevHome === undefined)
            delete process.env.HOME;
        else
            process.env.HOME = prevHome;
        if (prevState === undefined)
            delete process.env.OPENLIFE_STATE_DIR;
        else
            process.env.OPENLIFE_STATE_DIR = prevState;
        rmTmp(tmpHome);
        rmTmp(tmpCwd);
    }
    console.log('✅ scenario 1: cwd takes precedence over home');
}
function scenarioStaleness() {
    const tmpHome = mkTmp();
    const prevHome = process.env.HOME;
    const prevState = process.env.OPENLIFE_STATE_DIR;
    try {
        process.env.HOME = tmpHome;
        delete process.env.OPENLIFE_STATE_DIR;
        // Fresh
        writeManifest(path.join(tmpHome, '.openlife'), new Date().toISOString());
        let info = (0, AgentDiscovery_1.discover)();
        assert(info.liveness === 'fresh', `expected fresh, got ${info.liveness}`);
        // Stale (60-300s)
        const staleTs = new Date(Date.now() - (AgentDiscovery_1.HEARTBEAT_FRESH_S + 30) * 1000).toISOString();
        writeManifest(path.join(tmpHome, '.openlife'), staleTs);
        info = (0, AgentDiscovery_1.discover)();
        assert(info.liveness === 'stale', `expected stale, got ${info.liveness}`);
        assert(info.alive === true, 'stale is still alive');
        // Dead (>300s)
        const deadTs = new Date(Date.now() - (AgentDiscovery_1.HEARTBEAT_STALE_S + 60) * 1000).toISOString();
        writeManifest(path.join(tmpHome, '.openlife'), deadTs);
        info = (0, AgentDiscovery_1.discover)();
        assert(info.liveness === 'dead', `expected dead, got ${info.liveness}`);
        assert(info.alive === false, 'dead is NOT alive');
    }
    finally {
        if (prevHome === undefined)
            delete process.env.HOME;
        else
            process.env.HOME = prevHome;
        if (prevState !== undefined)
            process.env.OPENLIFE_STATE_DIR = prevState;
        rmTmp(tmpHome);
    }
    console.log('✅ scenario 2: staleness classification fresh→stale→dead');
}
function scenarioMissing() {
    const tmpHome = mkTmp();
    const tmpCwd = mkTmp();
    const prevHome = process.env.HOME;
    const prevState = process.env.OPENLIFE_STATE_DIR;
    try {
        process.env.HOME = tmpHome;
        process.env.OPENLIFE_STATE_DIR = path.join(tmpCwd, '.openlife');
        const info = (0, AgentDiscovery_1.discover)();
        assert(info.liveness === 'missing', `expected missing, got ${info.liveness}`);
        assert(info.alive === false, 'missing is not alive');
        assert(info.manifest === null, 'missing has null manifest');
    }
    finally {
        if (prevHome === undefined)
            delete process.env.HOME;
        else
            process.env.HOME = prevHome;
        if (prevState === undefined)
            delete process.env.OPENLIFE_STATE_DIR;
        else
            process.env.OPENLIFE_STATE_DIR = prevState;
        rmTmp(tmpHome);
        rmTmp(tmpCwd);
    }
    console.log('✅ scenario 3: missing manifest reports liveness=missing');
}
function scenarioMalformed() {
    const tmpHome = mkTmp();
    const prevHome = process.env.HOME;
    const prevState = process.env.OPENLIFE_STATE_DIR;
    try {
        process.env.HOME = tmpHome;
        delete process.env.OPENLIFE_STATE_DIR;
        const dir = path.join(tmpHome, '.openlife');
        fs.mkdirSync(dir, { recursive: true });
        fs.writeFileSync(path.join(dir, GatewayManifest_1.MANIFEST_FILENAME), '{ not valid json');
        const info = (0, AgentDiscovery_1.discover)();
        assert(info.liveness === 'missing', 'malformed manifest must be treated as missing');
    }
    finally {
        if (prevHome === undefined)
            delete process.env.HOME;
        else
            process.env.HOME = prevHome;
        if (prevState !== undefined)
            process.env.OPENLIFE_STATE_DIR = prevState;
        rmTmp(tmpHome);
    }
    console.log('✅ scenario 4: malformed manifest treated as missing');
}
try {
    scenarioCwdPrecedence();
    scenarioStaleness();
    scenarioMissing();
    scenarioMalformed();
    console.log('TEST_AGENT_DISCOVERY_OK');
}
catch (err) {
    console.error('TEST_AGENT_DISCOVERY_FAIL', err);
    process.exit(1);
}
