"use strict";
// src/test_deploy_adapters.ts
// v1.18.0 — Deploy adapters regression. Real `vercel`/`railway` CLIs are
// NOT spawned. We test: registry, autoDetect from filesystem markers,
// preflight emits correct issues.
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 DeployAdapter_1 = require("./orchestrator/deploy/DeployAdapter");
const VercelAdapter_1 = require("./orchestrator/deploy/VercelAdapter");
const RailwayAdapter_1 = require("./orchestrator/deploy/RailwayAdapter");
function assert(cond, msg) {
    if (!cond)
        throw new Error(`assertion failed: ${msg}`);
}
function mkDir() { return fs.mkdtempSync(path.join(os.tmpdir(), 'deploy-test-')); }
function rm(d) { try {
    fs.rmSync(d, { recursive: true, force: true });
}
catch { /* */ } }
function scenarioRegistryDefaults() {
    DeployAdapter_1.DeployRegistry._resetForTests();
    const list = DeployAdapter_1.DeployRegistry.list();
    for (const expected of ['vercel', 'railway']) {
        assert(list.includes(expected), `${expected} should be registered`);
    }
    console.log('✅ scenario 1: registry has vercel + railway defaults');
}
async function scenarioAutoDetectVercel() {
    const dir = mkDir();
    try {
        fs.writeFileSync(path.join(dir, 'vercel.json'), '{"framework":"nextjs"}');
        // Auto-detect respects markers. May still return null if neither CLI is on PATH.
        const detected = await DeployAdapter_1.DeployRegistry.autoDetect(dir);
        // The runtime environment determines whether the CLI is available;
        // we just assert detection logic doesn't crash and is consistent.
        if (detected) {
            assert(detected === 'vercel' || detected === 'railway', `unexpected provider: ${detected}`);
        }
    }
    finally {
        rm(dir);
    }
    console.log('✅ scenario 2: autoDetect reads vercel.json marker without crashing');
}
async function scenarioAutoDetectRailway() {
    const dir = mkDir();
    try {
        fs.writeFileSync(path.join(dir, 'railway.toml'), 'project = "demo"\n');
        const detected = await DeployAdapter_1.DeployRegistry.autoDetect(dir);
        if (detected) {
            assert(detected === 'vercel' || detected === 'railway', `unexpected: ${detected}`);
        }
    }
    finally {
        rm(dir);
    }
    console.log('✅ scenario 3: autoDetect reads railway.toml marker without crashing');
}
async function scenarioAutoDetectNoMarker() {
    const dir = mkDir();
    try {
        // No vercel.json, no railway.toml — autoDetect may still pick a provider
        // whose CLI is on PATH, or return null. We just verify no crash.
        const detected = await DeployAdapter_1.DeployRegistry.autoDetect(dir);
        assert(detected === null || ['vercel', 'railway'].includes(detected), 'returns null or known provider');
    }
    finally {
        rm(dir);
    }
    console.log('✅ scenario 4: autoDetect with no markers returns null OR available provider');
}
async function scenarioVercelPreflightUnlinked() {
    const dir = mkDir();
    try {
        const adapter = new VercelAdapter_1.VercelAdapter();
        const pre = await adapter.preflight({ cwd: dir });
        // No .vercel/project.json → at least one warning about project_not_linked
        const hasUnlinked = pre.issues.some(i => i.message === 'project_not_linked');
        assert(hasUnlinked, `expected project_not_linked warning, got ${JSON.stringify(pre.issues)}`);
        // Empty dir without errors should still be ok=true (just warnings)
        assert(pre.ok, `ok with only warnings, got ${pre.ok}`);
    }
    finally {
        rm(dir);
    }
    console.log('✅ scenario 5: VercelAdapter.preflight detects unlinked project');
}
async function scenarioVercelPreflightInvalidJson() {
    const dir = mkDir();
    try {
        fs.writeFileSync(path.join(dir, 'vercel.json'), '{not valid json');
        const adapter = new VercelAdapter_1.VercelAdapter();
        const pre = await adapter.preflight({ cwd: dir });
        const hasError = pre.issues.some(i => i.severity === 'error' && i.message.startsWith('vercel_json_invalid'));
        assert(hasError, `expected vercel_json_invalid error, got ${JSON.stringify(pre.issues)}`);
        assert(!pre.ok, 'preflight not ok on fatal issue');
    }
    finally {
        rm(dir);
    }
    console.log('✅ scenario 6: VercelAdapter.preflight surfaces invalid vercel.json as error');
}
async function scenarioRailwayPreflightNoConfig() {
    const dir = mkDir();
    try {
        const adapter = new RailwayAdapter_1.RailwayAdapter();
        const pre = await adapter.preflight({ cwd: dir });
        const hasWarning = pre.issues.some(i => i.message === 'no_railway_config');
        assert(hasWarning, `expected no_railway_config warning, got ${JSON.stringify(pre.issues)}`);
    }
    finally {
        rm(dir);
    }
    console.log('✅ scenario 7: RailwayAdapter.preflight detects missing config');
}
async function scenarioRailwayRollbackRequiresId() {
    // v1.18.1 — rollback is now natively supported, but requires --to <id>.
    // Without it, we emit an actionable error pointing to `railway status`.
    const adapter = new RailwayAdapter_1.RailwayAdapter();
    const r = await adapter.rollback({});
    assert(!r.ok, 'rollback without --to fails');
    assert(r.error?.includes('rollback_requires_id'), `expected rollback_requires_id, got ${r.error}`);
    console.log('✅ scenario 8: RailwayAdapter.rollback requires --to <id> (v1.18.1 native rollback)');
}
async function scenarioCloudflareAndFlyRegistered() {
    // v1.18.1 — Cloudflare + Fly adapters are now part of the default registry.
    // eslint-disable-next-line @typescript-eslint/no-var-requires
    const { DeployRegistry } = await Promise.resolve().then(() => __importStar(require('./orchestrator/deploy/DeployAdapter')));
    DeployRegistry._resetForTests();
    const list = DeployRegistry.list();
    for (const expected of ['vercel', 'railway', 'cloudflare', 'fly']) {
        assert(list.includes(expected), `${expected} registered`);
    }
    console.log('✅ scenario 9: registry has all 4 adapters (vercel, railway, cloudflare, fly)');
}
async function scenarioCloudflarePreflightNoConfig() {
    // v1.18.1 — CloudflareAdapter.preflight detects missing wrangler.toml.
    // eslint-disable-next-line @typescript-eslint/no-var-requires
    const { CloudflareAdapter } = await Promise.resolve().then(() => __importStar(require('./orchestrator/deploy/CloudflareAdapter')));
    const adapter = new CloudflareAdapter();
    const dir = mkDir();
    try {
        const pre = await adapter.preflight({ cwd: dir });
        const hasWarning = pre.issues.some(i => i.message === 'no_wrangler_config');
        assert(hasWarning, `expected no_wrangler_config, got ${JSON.stringify(pre.issues)}`);
    }
    finally {
        rm(dir);
    }
    console.log('✅ scenario 10: CloudflareAdapter.preflight detects missing wrangler.toml');
}
async function scenarioFlyPreflightNoToml() {
    // eslint-disable-next-line @typescript-eslint/no-var-requires
    const { FlyAdapter } = await Promise.resolve().then(() => __importStar(require('./orchestrator/deploy/FlyAdapter')));
    const adapter = new FlyAdapter();
    const dir = mkDir();
    try {
        const pre = await adapter.preflight({ cwd: dir });
        const hasWarning = pre.issues.some(i => i.message === 'no_fly_toml');
        assert(hasWarning, `expected no_fly_toml, got ${JSON.stringify(pre.issues)}`);
    }
    finally {
        rm(dir);
    }
    console.log('✅ scenario 11: FlyAdapter.preflight detects missing fly.toml');
}
// v1.19.0 — promote scenarios. We can't spawn the real CLIs in CI (they
// require auth + a linked project), so we assert the graceful-failure
// contract: each adapter's promote() must return a DeployResult shape,
// never throw, and surface a recognizable error code when the CLI is
// missing or the call fails.
async function scenarioVercelPromoteShape() {
    const adapter = new VercelAdapter_1.VercelAdapter();
    const r = await adapter.promote({ to: 'production', timeoutMs: 3_000 });
    assert(typeof r.ok === 'boolean', 'returns DeployResult with ok boolean');
    assert(r.provider === 'vercel', `provider tagged: ${r.provider}`);
    assert(typeof r.durationMs === 'number', 'durationMs is numeric');
    // In an unlinked dir without auth, CLI fails or is absent — error must surface.
    if (!r.ok) {
        assert(typeof r.error === 'string' && r.error.length > 0, `error message present: ${r.error}`);
    }
    console.log('✅ scenario 12: VercelAdapter.promote returns DeployResult contract');
}
async function scenarioRailwayPromoteShape() {
    const adapter = new RailwayAdapter_1.RailwayAdapter();
    const r = await adapter.promote({ to: 'production', timeoutMs: 3_000 });
    assert(typeof r.ok === 'boolean', 'returns DeployResult with ok boolean');
    assert(r.provider === 'railway', `provider tagged: ${r.provider}`);
    if (!r.ok) {
        assert(typeof r.error === 'string', `error present: ${r.error}`);
    }
    console.log('✅ scenario 13: RailwayAdapter.promote returns DeployResult contract');
}
async function scenarioCloudflarePromoteShape() {
    // eslint-disable-next-line @typescript-eslint/no-var-requires
    const { CloudflareAdapter } = await Promise.resolve().then(() => __importStar(require('./orchestrator/deploy/CloudflareAdapter')));
    const adapter = new CloudflareAdapter();
    const r = await adapter.promote({ to: 'production', timeoutMs: 3_000 });
    assert(typeof r.ok === 'boolean', 'returns DeployResult');
    assert(r.provider === 'cloudflare', `provider tagged: ${r.provider}`);
    console.log('✅ scenario 14: CloudflareAdapter.promote returns DeployResult contract');
}
async function scenarioFlyPromoteShape() {
    // eslint-disable-next-line @typescript-eslint/no-var-requires
    const { FlyAdapter } = await Promise.resolve().then(() => __importStar(require('./orchestrator/deploy/FlyAdapter')));
    const adapter = new FlyAdapter();
    // Fly's promote convention: `to` IS the target app name.
    const r = await adapter.promote({ to: 'myapp-prod', timeoutMs: 3_000 });
    assert(typeof r.ok === 'boolean', 'returns DeployResult');
    assert(r.provider === 'fly', `provider tagged: ${r.provider}`);
    console.log('✅ scenario 15: FlyAdapter.promote returns DeployResult contract');
}
(async () => {
    try {
        scenarioRegistryDefaults();
        await scenarioAutoDetectVercel();
        await scenarioAutoDetectRailway();
        await scenarioAutoDetectNoMarker();
        await scenarioVercelPreflightUnlinked();
        await scenarioVercelPreflightInvalidJson();
        await scenarioRailwayPreflightNoConfig();
        await scenarioRailwayRollbackRequiresId();
        await scenarioCloudflareAndFlyRegistered();
        await scenarioCloudflarePreflightNoConfig();
        await scenarioFlyPreflightNoToml();
        await scenarioVercelPromoteShape();
        await scenarioRailwayPromoteShape();
        await scenarioCloudflarePromoteShape();
        await scenarioFlyPromoteShape();
        console.log('TEST_DEPLOY_ADAPTERS_OK');
    }
    catch (err) {
        console.error('TEST_DEPLOY_ADAPTERS_FAIL', err);
        process.exit(1);
    }
})();
