"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.TruEvalToolController = 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 parseEvaluationFilters(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.datasetRecordId && typeof raw.datasetRecordId === 'string') {
        filters.datasetRecordId = raw.datasetRecordId;
    }
    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);
    }
    if (raw.success !== undefined) {
        if (typeof raw.success === 'boolean') {
            filters.success = raw.success;
        }
        else if (raw.success === 'true' || raw.success === '1') {
            filters.success = true;
        }
        else if (raw.success === 'false' || raw.success === '0') {
            filters.success = false;
        }
    }
    return filters;
}
class TruEvalToolController {
    /**
     * 3.7 search_evaluations(filter, time_range, sort, page)
     * GET /api/argus/tools/search-evaluations
     *
     * NOTE: This uses the eval_results table (Postgres) and focuses on core filters:
     * - projectId, applicationId, sessionId, traceId, evalId, datasetRecordId
     * - scoreMin, scoreMax, success
     */
    static async searchEvaluations(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 = parseEvaluationFilters(rawFilters);
            const pageNum = Number(page) || 1;
            const sizeNum = Number(pageSize) || 50;
            const offset = (pageNum - 1) * sizeNum;
            const conditions = [];
            // Functional evaluations: is_redteam = 0
            conditions.push((0, drizzle_orm_1.eq)(tables_1.evalResultsTable.isRedteam, 0));
            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.datasetRecordId) {
                conditions.push((0, drizzle_orm_1.eq)(tables_1.evalResultsTable.datasetRecordId, filters.datasetRecordId));
            }
            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));
            }
            if (filters.success !== undefined) {
                conditions.push((0, drizzle_orm_1.eq)(tables_1.evalResultsTable.success, filters.success ? 1 : 0));
            }
            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 === 'latencyMs') {
                        orderByExpr =
                            order === 'asc'
                                ? (0, drizzle_orm_1.sql) `${tables_1.evalResultsTable.latencyMs} ASC`
                                : (0, drizzle_orm_1.sql) `${tables_1.evalResultsTable.latencyMs} 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);
            // Page of evaluations
            const evaluations = 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: {
                    evaluations,
                    page: pageNum,
                    pageSize: sizeNum,
                    total,
                },
            });
        }
        catch (error) {
            logger_1.default.error(`search_evaluations error: ${error}`);
            res.status(500).json({
                success: false,
                message: error instanceof Error ? error.message : 'Internal server error',
            });
        }
    }
    /**
     * 3.7 get_evaluation(evaluation_id)
     * GET /api/argus/tools/get-evaluation
     */
    static async getEvaluation(req, res) {
        try {
            const { evaluationId } = req.query;
            if (!evaluationId || typeof evaluationId !== 'string') {
                res.status(400).json({
                    success: false,
                    message: 'evaluationId 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, evaluationId), (0, drizzle_orm_1.eq)(tables_1.evalResultsTable.isRedteam, 0)))
                .limit(1);
            if (!rows.length) {
                res.status(404).json({
                    success: false,
                    message: 'Evaluation not found',
                });
                return;
            }
            res.json({
                success: true,
                data: rows[0],
            });
        }
        catch (error) {
            logger_1.default.error(`get_evaluation error: ${error}`);
            res.status(500).json({
                success: false,
                message: error instanceof Error ? error.message : 'Internal server error',
            });
        }
    }
    /**
     * 3.7 get_entity_evaluation_rollup(entity={session|trace|span}, id, group_by?)
     * GET /api/argus/tools/get-entity-evaluation-rollup
     *
     * For now we support entity=session|trace. Span-level rollups are not implemented yet.
     */
    static async getEntityEvaluationRollup(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, 0)];
            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 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_evaluation_rollup error: ${error}`);
            res.status(500).json({
                success: false,
                message: error instanceof Error ? error.message : 'Internal server error',
            });
        }
    }
}
exports.TruEvalToolController = TruEvalToolController;
//# sourceMappingURL=truEvalToolController.js.map