/**
 * source-isolation.ts
 *
 * Promptfoo custom assertion: verifies that the agentic provider only
 * fetched documentation from the configured allowed origins.
 *
 * Compiled to dist/assertions/source-isolation.js and referenced via
 * file:// in generated Promptfoo configs.
 *
 * The assertion is diagnostic-only — flagged `metadata.scoring: false` so it
 * stays out of `assertion-pass-rate`. It surfaces as an advisory pass/fail
 * signal in results (D0083; before that this was a `weight: 0` sentinel).
 *
 * @see docs/archive/exec-plans/source-aware-eval-isolation.md (Phase 3b)
 */
import { isAllowedOrigin } from "../sources.js";
/**
 * Analyze doc page visits and compute an isolation score.
 *
 * The isolation score is the fraction of doc-fetching requests that went
 * to an allowed origin. A score of 1.0 means perfect isolation.
 *
 * @param docPageVisits - Classified doc page visit records
 * @param allowedOrigins - Origin patterns (glob-capable)
 * @returns Isolation report with score and breakdown
 */
export function analyzeSourceIsolation(docPageVisits, allowedOrigins) {
    if (allowedOrigins.length === 0 || docPageVisits.length === 0) {
        return {
            blocked: 0,
            isolationScore: 1.0,
            offOrigin: 0,
            offOriginUrls: [],
            onOrigin: docPageVisits.length,
            originBreakdown: {},
            total: docPageVisits.length,
        };
    }
    let onOrigin = 0;
    let offOrigin = 0;
    const offOriginUrls = [];
    const originBreakdown = {};
    for (const visit of docPageVisits) {
        try {
            const hostname = new URL(visit.url).hostname.replace(/^www\./, "");
            originBreakdown[hostname] = (originBreakdown[hostname] || 0) + 1;
            if (isAllowedOrigin(visit.url, allowedOrigins)) {
                onOrigin++;
            }
            else {
                offOrigin++;
                offOriginUrls.push(visit.url);
            }
        }
        catch {
            offOrigin++;
            offOriginUrls.push(visit.url);
        }
    }
    const total = onOrigin + offOrigin;
    const isolationScore = total > 0 ? onOrigin / total : 1.0;
    return {
        blocked: 0, // Blocked requests aren't in docPageVisits — they're caught earlier
        isolationScore,
        offOrigin,
        offOriginUrls,
        onOrigin,
        originBreakdown,
        total,
    };
}
// ---------------------------------------------------------------------------
// Promptfoo assertion entry point
// ---------------------------------------------------------------------------
/**
 * Promptfoo custom assertion function.
 *
 * Called by Promptfoo for each test case when referenced as:
 *   type: javascript
 *   value: file://dist/assertions/source-isolation.js
 *   metadata: { scoring: false }
 *
 * @param output - The model's text output (unused)
 * @param context - Promptfoo assertion context with provider metadata
 */
export default function (_output, context) {
    const behavior = context.providerResponse?.metadata?.agentBehavior;
    if (!behavior) {
        return { pass: true, reason: "No agent behavior recorded", score: 1 };
    }
    const docVisits = behavior.docPageVisits ?? [];
    if (docVisits.length === 0) {
        return { pass: true, reason: "No doc page visits recorded", score: 1 };
    }
    // Read allowed origins from env (set by pipeline.ts)
    const originsEnv = process.env.DOC_ALLOWED_ORIGINS;
    const allowedOrigins = originsEnv
        ? originsEnv
            .split(",")
            .map((o) => o.trim())
            .filter(Boolean)
        : [];
    if (allowedOrigins.length === 0) {
        return {
            pass: true,
            reason: `No origin sandboxing configured (${docVisits.length} doc visits)`,
            score: 1,
        };
    }
    const report = analyzeSourceIsolation(docVisits, allowedOrigins);
    return {
        pass: report.offOrigin === 0,
        reason: report.offOrigin === 0
            ? `All doc fetches on-origin (${report.onOrigin} visits, origins: ${allowedOrigins.join(", ")})`
            : `${report.offOrigin} off-origin doc fetch(es): ${report.offOriginUrls.join(", ")}`,
        score: report.isolationScore,
    };
}
