"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.TruScoutToolController = 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"));
function parseSecurityFilters(raw) {
    if (!raw || typeof raw !== 'object') {
        return {};
    }
    const filters = {};
    if (raw.applicationId && typeof raw.applicationId === 'string') {
        filters.applicationId = raw.applicationId;
    }
    if (raw.sessionId && typeof raw.sessionId === 'string') {
        filters.sessionId = raw.sessionId;
    }
    if (raw.traceId && typeof raw.traceId === 'string') {
        filters.traceId = raw.traceId;
    }
    if (raw.evalId && typeof raw.evalId === 'string') {
        filters.evalId = raw.evalId;
    }
    if (raw.scoreMin !== undefined && !Number.isNaN(Number(raw.scoreMin))) {
        filters.scoreMin = Number(raw.scoreMin);
    }
    if (raw.scoreMax !== undefined && !Number.isNaN(Number(raw.scoreMax))) {
        filters.scoreMax = Number(raw.scoreMax);
    }
    return filters;
}
class TruScoutToolController {
    /**
     * 3.8 search_security_findings(filter, time_range, sort, page)
     * GET /api/argus/tools/search-security-findings
     *
     * We model security findings as red-team evaluation results (is_redteam = 1).
     */
    static async searchSecurityFindings(req, res) {
        try {
            const { projectId, filters: filtersStr, sort: sortStr, page = '1', pageSize = '50', } = req.query;
            const db = await (0, database_1.getDb)();
            let rawFilters = {};
            if (filtersStr) {
                if (typeof filtersStr === 'string') {
                    try {
                        rawFilters = JSON.parse(filtersStr);
                    }
                    catch {
                        rawFilters = {};
                    }
                }
                else {
                    rawFilters = filtersStr;
                }
            }
            const filters = parseSecurityFilters(rawFilters);
            const pageNum = Number(page) || 1;
            const sizeNum = Number(pageSize) || 50;
            const offset = (pageNum - 1) * sizeNum;
            const conditions = [];
            // Security findings: is_redteam = 1
            conditions.push((0, drizzle_orm_1.eq)(tables_1.evalResultsTable.isRedteam, 1));
            if (projectId && typeof projectId === 'string') {
                conditions.push((0, drizzle_orm_1.eq)(tables_1.evalResultsTable.projectId, projectId));
            }
            if (filters.applicationId) {
                conditions.push((0, drizzle_orm_1.eq)(tables_1.evalResultsTable.applicationId, filters.applicationId));
            }
            if (filters.sessionId) {
                conditions.push((0, drizzle_orm_1.eq)(tables_1.evalResultsTable.sessionId, filters.sessionId));
            }
            if (filters.traceId) {
                conditions.push((0, drizzle_orm_1.eq)(tables_1.evalResultsTable.traceId, filters.traceId));
            }
            if (filters.evalId) {
                conditions.push((0, drizzle_orm_1.eq)(tables_1.evalResultsTable.evalId, filters.evalId));
            }
            if (filters.scoreMin !== undefined) {
                conditions.push((0, drizzle_orm_1.gte)(tables_1.evalResultsTable.score, filters.scoreMin));
            }
            if (filters.scoreMax !== undefined) {
                conditions.push((0, drizzle_orm_1.lte)(tables_1.evalResultsTable.score, filters.scoreMax));
            }
            const whereClause = conditions.length ? (0, drizzle_orm_1.and)(...conditions) : undefined;
            // Sorting
            let orderByExpr = (0, drizzle_orm_1.desc)(tables_1.evalResultsTable.createdAt);
            if (sortStr && typeof sortStr === 'string') {
                try {
                    const parsed = JSON.parse(sortStr);
                    const field = parsed.field;
                    const order = parsed.order || 'desc';
                    if (field === 'score') {
                        orderByExpr = order === 'asc' ? (0, drizzle_orm_1.sql) `${tables_1.evalResultsTable.score} ASC` : (0, drizzle_orm_1.sql) `${tables_1.evalResultsTable.score} DESC`;
                    }
                    else if (field === 'createdAt') {
                        orderByExpr =
                            order === 'asc'
                                ? (0, drizzle_orm_1.sql) `${tables_1.evalResultsTable.createdAt} ASC`
                                : (0, drizzle_orm_1.sql) `${tables_1.evalResultsTable.createdAt} DESC`;
                    }
                }
                catch {
                    // ignore sort parsing errors, fall back to default
                }
            }
            // Total count
            const totalResult = await db
                .select({ count: (0, drizzle_orm_1.sql) `count(*)` })
                .from(tables_1.evalResultsTable)
                .where(whereClause ?? (0, drizzle_orm_1.sql) `TRUE`);
            const total = Number(totalResult[0]?.count ?? 0);
            const findings = await db
                .select()
                .from(tables_1.evalResultsTable)
                .where(whereClause ?? (0, drizzle_orm_1.sql) `TRUE`)
                .orderBy(orderByExpr)
                .limit(sizeNum)
                .offset(offset);
            res.json({
                success: true,
                data: {
                    findings,
                    page: pageNum,
                    pageSize: sizeNum,
                    total,
                },
            });
        }
        catch (error) {
            logger_1.default.error(`search_security_findings error: ${error}`);
            res.status(500).json({
                success: false,
                message: error instanceof Error ? error.message : 'Internal server error',
            });
        }
    }
    /**
     * 3.8 get_security_finding(finding_id)
     * GET /api/argus/tools/get-security-finding
     */
    static async getSecurityFinding(req, res) {
        try {
            const { findingId } = req.query;
            if (!findingId || typeof findingId !== 'string') {
                res.status(400).json({
                    success: false,
                    message: 'findingId is required in query parameters',
                });
                return;
            }
            const db = await (0, database_1.getDb)();
            const rows = await db
                .select()
                .from(tables_1.evalResultsTable)
                .where((0, drizzle_orm_1.and)((0, drizzle_orm_1.eq)(tables_1.evalResultsTable.id, findingId), (0, drizzle_orm_1.eq)(tables_1.evalResultsTable.isRedteam, 1)))
                .limit(1);
            if (!rows.length) {
                res.status(404).json({
                    success: false,
                    message: 'Security finding not found',
                });
                return;
            }
            res.json({
                success: true,
                data: rows[0],
            });
        }
        catch (error) {
            logger_1.default.error(`get_security_finding error: ${error}`);
            res.status(500).json({
                success: false,
                message: error instanceof Error ? error.message : 'Internal server error',
            });
        }
    }
    /**
     * 3.8 get_entity_security_rollup(entity, id, group_by?)
     * GET /api/argus/tools/get-entity-security-rollup
     *
     * For now we support entity=session|trace. Returns simple counts and average score.
     */
    static async getEntitySecurityRollup(req, res) {
        try {
            const { entity, id } = req.query;
            if (!entity || !id || typeof entity !== 'string' || typeof id !== 'string') {
                res.status(400).json({
                    success: false,
                    message: 'entity and id are required in query parameters',
                });
                return;
            }
            const db = await (0, database_1.getDb)();
            const conditions = [(0, drizzle_orm_1.eq)(tables_1.evalResultsTable.isRedteam, 1)];
            const lower = entity.toLowerCase();
            if (lower === 'session') {
                conditions.push((0, drizzle_orm_1.eq)(tables_1.evalResultsTable.sessionId, id));
            }
            else if (lower === 'trace') {
                conditions.push((0, drizzle_orm_1.eq)(tables_1.evalResultsTable.traceId, id));
            }
            else {
                res.status(400).json({
                    success: false,
                    message: 'Only entity=session or trace is supported for security rollups currently.',
                });
                return;
            }
            const whereClause = (0, drizzle_orm_1.and)(...conditions);
            const rows = await db
                .select({
                avgScore: (0, drizzle_orm_1.sql) `avg(${tables_1.evalResultsTable.score})`,
                count: (0, drizzle_orm_1.sql) `count(*)`,
            })
                .from(tables_1.evalResultsTable)
                .where(whereClause);
            const { avgScore, count } = rows[0] ?? { avgScore: 0, count: 0 };
            res.json({
                success: true,
                data: {
                    entity: lower,
                    id,
                    averageScore: Number(avgScore ?? 0),
                    total: Number(count ?? 0),
                    breakdown: [],
                },
            });
        }
        catch (error) {
            logger_1.default.error(`get_entity_security_rollup error: ${error}`);
            res.status(500).json({
                success: false,
                message: error instanceof Error ? error.message : 'Internal server error',
            });
        }
    }
}
exports.TruScoutToolController = TruScoutToolController;
//# sourceMappingURL=truScoutToolController.js.map