"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.SECURITY_EVAL_SCOPE_SQL = void 0;
exports.chLit = chLit;
exports.buildSecurityDenormWhereSql = buildSecurityDenormWhereSql;
exports.buildPluginCategoryCaseSql = buildPluginCategoryCaseSql;
exports.buildSecurityCategoryVolumeSqlDenorm = buildSecurityCategoryVolumeSqlDenorm;
exports.buildSecurityVulnerabilitiesOverTimeSqlDenorm = buildSecurityVulnerabilitiesOverTimeSqlDenorm;
exports.buildSecurityTestSuitePluginStatsSqlDenorm = buildSecurityTestSuitePluginStatsSqlDenorm;
const metadata_1 = require("../../../redteam/constants/metadata");
const types_1 = require("./types");
function chLit(value) {
    return value.replace(/'/g, "''");
}
exports.SECURITY_EVAL_SCOPE_SQL = `(
  (trace_id IS NOT NULL AND trace_id NOT IN ('', 'null'))
  OR (session_id IS NOT NULL AND session_id NOT IN ('', 'null'))
)`;
/** application_id + is_redteam + optional created_at bounds (already formatted). */
function buildSecurityDenormWhereSql(applicationId, start, end) {
    const parts = [
        `application_id = '${chLit(applicationId)}'`,
        'is_redteam = 1',
    ];
    if (start) {
        parts.push(`created_at >= '${chLit(start)}'`);
    }
    if (end) {
        parts.push(`created_at <= '${chLit(end)}'`);
    }
    parts.push(`trace_id IS NOT NULL AND trace_id NOT IN ('', 'null')`);
    return parts.join(' AND ');
}
/** Map plugin_id → top-level risk category label for GROUP BY in ClickHouse. */
function buildPluginCategoryCaseSql(column = 'plugin_id') {
    const branches = [];
    for (const [category, plugins] of Object.entries(metadata_1.riskCategories)) {
        if (!Array.isArray(plugins) || plugins.length === 0) {
            continue;
        }
        const list = plugins.map((p) => `'${chLit(String(p))}'`).join(', ');
        branches.push(`${column} IN (${list}), '${chLit(category)}'`);
    }
    if (branches.length === 0) {
        return "''";
    }
    return `multiIf(${branches.join(', ')}, '')`;
}
function buildSecurityCategoryVolumeSqlDenorm(whereCore) {
    const categoryExpr = buildPluginCategoryCaseSql('plugin_id');
    return `
SELECT
  category AS label,
  errors,
  failures,
  errors + failures AS value
FROM (
  SELECT
    ${categoryExpr} AS category,
    countIf(failure_reason = 2) AS errors,
    countIf(component_pass = 0 AND failure_reason != 2) AS failures
  FROM ${types_1.EVAL_RESULT_COMPONENTS_TABLE}
  WHERE ${whereCore}
    AND trace_id IS NOT NULL AND trace_id NOT IN ('', 'null')
    AND plugin_id != ''
    AND component_pass = 0
  GROUP BY category
)
WHERE category != ''
ORDER BY value DESC
`.trim();
}
/** Pass/fail component counts per time bucket; empty buckets via WITH FILL; percentages in SQL. */
function buildSecurityVulnerabilitiesOverTimeSqlDenorm(whereCore, bucket) {
    return `
WITH
  toDateTime('${chLit(bucket.rangeStart)}') AS range_start,
  toDateTime('${chLit(bucket.rangeEnd)}') AS range_end,
  ${bucket.fillFromExpr} AS fill_from,
  ${bucket.fillToExpr} AS fill_to
SELECT
  bucket,
  pass_count AS passCount,
  fail_count AS failCount,
  if(pass_count + fail_count > 0, round(pass_count / (pass_count + fail_count) * 100, 2), 0) AS pass,
  if(pass_count + fail_count > 0, round(fail_count / (pass_count + fail_count) * 100, 2), 0) AS fail
FROM (
  SELECT
    ${bucket.bucketExpression} AS bucket,
    countIf(component_pass = 1) AS pass_count,
    countIf(component_pass = 0 AND failure_reason != 2) AS fail_count
  FROM ${types_1.EVAL_RESULT_COMPONENTS_TABLE}
  WHERE ${whereCore}
    AND trace_id IS NOT NULL AND trace_id NOT IN ('', 'null')
    AND created_at >= range_start
    AND created_at <= range_end
  GROUP BY bucket
  ORDER BY bucket ASC
  WITH FILL
    FROM fill_from
    TO fill_to
    STEP ${bucket.fillStep}
)
ORDER BY bucket ASC
`.trim();
}
/** Per-plugin probe stats (one row per plugin_id); moderation joined in SQL. */
function buildSecurityTestSuitePluginStatsSqlDenorm(whereCore) {
    return `
SELECT
  plugin_id,
  count() AS total,
  countIf(grading_pass = 1) AS pass,
  countIf(grading_pass = 0 AND failure_reason != 2) AS failures,
  countIf(failure_reason = 2) AS errors,
  countIf(grading_pass = 1 OR (grading_pass = 0 AND moderation_fail = 1)) AS pass_with_filter,
  min(eval_id) AS sample_eval_id
FROM (
  SELECT
    a.eval_result_id,
    a.eval_id,
    a.plugin_id,
    a.grading_pass,
    a.failure_reason,
    max(if(c.assertion_type = 'moderation' AND c.component_pass = 0, 1, 0)) AS moderation_fail
  FROM ${types_1.EVAL_RESULTS_ANALYTICS_TABLE} AS a
  LEFT JOIN ${types_1.EVAL_RESULT_COMPONENTS_TABLE} AS c
    ON c.eval_result_id = a.eval_result_id
    AND c.is_redteam = 1
  WHERE ${whereCore}
    AND trace_id IS NOT NULL AND trace_id NOT IN ('', 'null')
  GROUP BY
    a.eval_result_id,
    a.eval_id,
    a.plugin_id,
    a.grading_pass,
    a.failure_reason
)
WHERE plugin_id != ''
GROUP BY plugin_id
ORDER BY plugin_id
`.trim();
}
//# sourceMappingURL=securityQueryHelpers.js.map