/**
 * Runtime Verification Scanner
 *
 * Orchestrates app launching, golden path testing, and runtime verification.
 * This is the entry point for M7 runtime verification capabilities.
 *
 * @module scanners/runtime
 */
import { logger } from "../../logger.js";
import { detectFramework, launchApp, stopApp, } from "./app-launcher.js";
import { runAllFlows, } from "./golden-path-runner.js";
export * from "./types.js";
export { detectFramework, launchApp, stopApp, stopAllApps, getRunningApps, } from "./app-launcher.js";
export { discoverFlows, runFlow, runAllFlows, generateSampleFlow, loadFlow, } from "./golden-path-runner.js";
export { isPlaywrightAvailable, launchBrowser, closeBrowser, runFlowWithPlaywright, } from "./playwright-executor.js";
/**
 * Calculate runtime verification score
 */
function calculateScore(goldenPathResults) {
    const goldenPathsTotal = goldenPathResults.length;
    const goldenPathsPassed = goldenPathResults.filter((r) => r.success).length;
    // Calculate overall score (0-100)
    let overallScore = 0;
    if (goldenPathsTotal > 0) {
        // Golden paths are weighted by priority
        const priorityWeights = { critical: 3, high: 2, medium: 1.5, low: 1 };
        let weightedPassed = 0;
        let totalWeight = 0;
        for (const result of goldenPathResults) {
            // Infer priority from flow name or default to medium
            const priority = "medium"; // TODO: Store priority in result
            const weight = priorityWeights[priority];
            totalWeight += weight;
            if (result.success) {
                weightedPassed += weight;
            }
        }
        if (totalWeight > 0) {
            overallScore = Math.round((weightedPassed / totalWeight) * 100);
        }
    }
    else {
        // No flows defined - partial score
        overallScore = 50; // Neutral score when no flows
    }
    return {
        goldenPathsPassed,
        goldenPathsTotal,
        visualRegressionsPassed: 0, // TODO: Implement visual regression
        visualRegressionsTotal: 0,
        apiTestsPassed: 0, // Counted within golden paths for now
        apiTestsTotal: 0,
        overallScore,
    };
}
/**
 * Run full runtime verification
 *
 * 1. Detect framework
 * 2. Launch the app
 * 3. Run golden path flows
 * 4. Calculate score
 * 5. Stop the app
 */
export async function runRuntimeVerification(projectPath, options = {}) {
    const startTime = Date.now();
    const { port, timeout = 60000, priority, stopAfter = true } = options;
    logger.info("runtime.verification_started", { projectPath });
    // Step 1: Detect framework
    const detection = await detectFramework(projectPath);
    logger.info("runtime.framework_detected", {
        framework: detection.framework,
        confidence: detection.confidence,
    });
    // Step 2: Launch the app
    const launchConfig = {
        projectPath,
        framework: detection.framework,
        port: port || detection.port,
        timeout,
    };
    const launchResult = await launchApp(launchConfig);
    if (!launchResult.success) {
        return {
            success: false,
            framework: detection.framework,
            appUrl: launchResult.url,
            duration: Date.now() - startTime,
            goldenPaths: [],
            visualRegressions: [],
            score: {
                goldenPathsPassed: 0,
                goldenPathsTotal: 0,
                visualRegressionsPassed: 0,
                visualRegressionsTotal: 0,
                apiTestsPassed: 0,
                apiTestsTotal: 0,
                overallScore: 0,
            },
            error: launchResult.error || "App failed to start",
        };
    }
    logger.info("runtime.app_launched", {
        url: launchResult.url,
        startupTime: launchResult.startupTime,
    });
    // Step 3: Run golden path flows
    let goldenPathResults = [];
    try {
        goldenPathResults = await runAllFlows(projectPath, launchResult.url, {
            priority,
        });
    }
    catch (error) {
        logger.error("runtime.golden_path_error", {
            error: error.message,
        });
    }
    // Step 4: Calculate score
    const score = calculateScore(goldenPathResults);
    // Step 5: Stop the app
    if (stopAfter) {
        await stopApp(projectPath, launchResult.port);
    }
    const result = {
        success: score.overallScore >= 70, // Threshold for "passing"
        framework: detection.framework,
        appUrl: launchResult.url,
        duration: Date.now() - startTime,
        goldenPaths: goldenPathResults,
        visualRegressions: [], // TODO: Implement
        score,
    };
    logger.info("runtime.verification_completed", {
        success: result.success,
        score: score.overallScore,
        duration: result.duration,
    });
    return result;
}
/**
 * Quick health check - just launch and verify app starts
 */
export async function quickHealthCheck(projectPath, options = {}) {
    const { port, timeout = 30000 } = options;
    const detection = await detectFramework(projectPath);
    const launchResult = await launchApp({
        projectPath,
        framework: detection.framework,
        port: port || detection.port,
        timeout,
    });
    // Always stop after health check
    if (launchResult.pid) {
        await stopApp(projectPath, launchResult.port);
    }
    return {
        healthy: launchResult.success && launchResult.healthStatus === "healthy",
        url: launchResult.url,
        startupTime: launchResult.startupTime,
        error: launchResult.error,
    };
}
//# sourceMappingURL=index.js.map