"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.getRedteamReportMetrics = void 0;
const drizzle_orm_1 = require("drizzle-orm");
const database_1 = require("../../../database");
const tables_1 = require("../../../database/tables");
const logger_1 = __importDefault(require("../../../logger"));
const database_2 = require("../../../util/database");
const redteam_report_shared_1 = require("./redteam-report-shared");
function getRiskCategorySeverityMap(plugins) {
    const out = {};
    for (const p of plugins || []) {
        const id = typeof p === 'string' ? p : p?.id;
        const sev = typeof p === 'object' && p !== null ? p?.severity : undefined;
        if (id && sev && ['low', 'medium', 'high', 'critical'].includes(String(sev))) {
            out[String(id)] = String(sev);
        }
    }
    return out;
}
const getRedteamReportMetrics = async (req, res) => {
    try {
        const { resultId } = req.params;
        if (!resultId) {
            res.status(400).json({ error: 'resultId is required' });
            return;
        }
        const db = await (0, database_1.getDb)();
        const rows = await db
            .select({
            testRunId: tables_1.testRunsTable.id,
            evalId: tables_1.testRunsToEvalsTable.evalId,
        })
            .from(tables_1.testRunsTable)
            .leftJoin(tables_1.testRunsToEvalsTable, (0, drizzle_orm_1.eq)(tables_1.testRunsTable.id, tables_1.testRunsToEvalsTable.testRunId))
            .where((0, drizzle_orm_1.eq)(tables_1.testRunsTable.id, resultId))
            .limit(1);
        if (!rows.length) {
            res.status(404).json({ error: 'Redteam result not found' });
            return;
        }
        const evalId = rows[0]?.evalId;
        if (!evalId) {
            res.status(200).json({ data: { reportMetrics: null } });
            return;
        }
        let file = await (0, database_2.fetchEvalResultsFileFromDb)(evalId);
        if (!file) {
            file = await (0, database_2.readResult)(evalId);
        }
        if (!file?.result?.results?.results) {
            res.status(200).json({ data: { reportMetrics: null } });
            return;
        }
        const resultDetails = file.result;
        const allResults = resultDetails?.results?.results ?? [];
        const failuresByPlugin = {};
        const passesByPlugin = {};
        for (const r of allResults) {
            const pluginId = (0, redteam_report_shared_1.getPluginIdFromResult)(r);
            if (!pluginId) {
                continue;
            }
            const isError = (0, redteam_report_shared_1.isErrorFailureReason)(r?.failureReason);
            const isPass = Boolean(r?.gradingResult?.pass);
            const wrapped = (0, redteam_report_shared_1.wrapRowForMetricsPayload)(r);
            if (isPass) {
                passesByPlugin[pluginId] = passesByPlugin[pluginId] || [];
                passesByPlugin[pluginId].push(wrapped);
            }
            else if (!isError) {
                failuresByPlugin[pluginId] = failuresByPlugin[pluginId] || [];
                failuresByPlugin[pluginId].push(wrapped);
            }
        }
        const strategyStats = {};
        for (const pluginTests of Object.values(failuresByPlugin)) {
            for (const test of pluginTests) {
                const strategyId = (0, redteam_report_shared_1.getStrategyIdFromTest)(test);
                strategyStats[strategyId] = strategyStats[strategyId] || { pass: 0, total: 0 };
                strategyStats[strategyId].pass += 1;
                strategyStats[strategyId].total += 1;
            }
        }
        for (const pluginTests of Object.values(passesByPlugin)) {
            for (const test of pluginTests) {
                const strategyId = (0, redteam_report_shared_1.getStrategyIdFromTest)(test);
                strategyStats[strategyId] = strategyStats[strategyId] || { pass: 0, total: 0 };
                strategyStats[strategyId].total += 1;
            }
        }
        const categoryStats = allResults.reduce((acc, row) => {
            const pluginId = (0, redteam_report_shared_1.getPluginIdFromResult)(row)?.replace(/^trusys:redteam:/, '');
            if (!pluginId) {
                return acc;
            }
            acc[pluginId] = acc[pluginId] || { pass: 0, total: 0, passWithFilter: 0, errors: 0 };
            acc[pluginId].total++;
            const moderationFailedButOtherPassed = row?.gradingResult?.componentResults?.some((cr) => cr?.assertion?.type === 'moderation' && !cr?.pass);
            if (row?.success) {
                acc[pluginId].pass++;
                acc[pluginId].passWithFilter++;
            }
            else if (moderationFailedButOtherPassed) {
                acc[pluginId].passWithFilter++;
            }
            if (row?.gradingResult == null && (0, redteam_report_shared_1.isErrorFailureReason)(row?.failureReason)) {
                acc[pluginId].errors++;
            }
            return acc;
        }, {});
        const plugins = resultDetails?.config?.redteam?.plugins || [];
        const severityMap = getRiskCategorySeverityMap(plugins);
        const severityLevels = ['low', 'medium', 'high', 'critical'];
        const severityCounts = severityLevels.reduce((acc, severity) => {
            acc[severity] = allResults
                .map((row) => {
                const pluginId = (0, redteam_report_shared_1.getPluginIdFromResult)(row);
                if (!pluginId) {
                    return 0;
                }
                if (severityMap[pluginId] === severity && row?.gradingResult?.pass === false) {
                    return 1;
                }
                return 0;
            })
                .reduce((a, b) => a + b, 0);
            return acc;
        }, {});
        res.json({
            data: {
                reportMetrics: {
                    failuresByPlugin,
                    passesByPlugin,
                    strategyStats,
                    categoryStats,
                    severityCounts,
                },
            },
        });
    }
    catch (error) {
        logger_1.default.error(`Error building redteam report metrics: ${error}`);
        res.status(500).json({ error: 'Failed to fetch redteam report metrics' });
    }
};
exports.getRedteamReportMetrics = getRedteamReportMetrics;
//# sourceMappingURL=get-redteam-report-metrics.js.map