"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.ArgusController = void 0;
const argusService_1 = require("../../services/argus/argusService");
const domainRegistry_1 = require("../../services/argus/domain/domainRegistry");
const types_1 = require("../../services/argus/types");
const truPulseAdapter_1 = require("../../services/argus/domain/adapters/truPulseAdapter");
const pulseService_1 = require("../../services/pulseService");
const logger_1 = __importDefault(require("../../../logger"));
const database_1 = require("../../../database");
const tables_1 = require("../../../database/tables");
const drizzle_orm_1 = require("drizzle-orm");
const crypto_1 = require("crypto");
const extractDraftSecurityConfigPayload_1 = require("../../../util/argus/extractDraftSecurityConfigPayload");
// Initialize service (singleton)
let argusService = null;
/**
 * Get or create Argus service
 * MCP client is always enabled inside ArgusService; no env-based config here.
 */
function getArgusService() {
    if (!argusService) {
        const domainRegistry = new domainRegistry_1.DomainRegistry();
        // Register TruPulse domain
        const truPulseAdapter = new truPulseAdapter_1.TruPulseAdapter();
        domainRegistry.register({
            domain: types_1.ArgusDomain.TRU_PULSE,
            displayName: 'TruPulse',
            description: 'Handles traces, spans, and sessions',
            adapter: truPulseAdapter,
            service: pulseService_1.pulseService,
        });
        domainRegistry.register({
            domain: types_1.ArgusDomain.TRU_GUARD,
            displayName: 'TruGuard',
            description: 'Guardrails dashboard — validator executions and policies',
            adapter: truPulseAdapter,
            service: pulseService_1.pulseService,
        });
        domainRegistry.register({
            domain: types_1.ArgusDomain.TRU_EVAL,
            displayName: 'TruEval',
            description: 'Functional evaluation — test run results (eval_results)',
            adapter: truPulseAdapter,
            service: pulseService_1.pulseService,
        });
        domainRegistry.register({
            domain: types_1.ArgusDomain.TRU_SCOUT,
            displayName: 'TruScout',
            description: 'Security / red team evaluation — eval_results (is_redteam)',
            adapter: truPulseAdapter,
            service: pulseService_1.pulseService,
        });
        domainRegistry.register({
            domain: types_1.ArgusDomain.SECURITY_CONFIG,
            displayName: 'Security config',
            description: 'Draft red team security configurations (UI-equivalent JSON, no telemetry SQL)',
            adapter: truPulseAdapter,
            service: pulseService_1.pulseService,
        });
        argusService = new argusService_1.ArgusService(domainRegistry);
    }
    return argusService;
}
class ArgusController {
    /**
     * POST /api/{domain}/argus/ask
     * Main query endpoint
     */
    static async ask(req, res) {
        try {
            const { query, filters: rawFilters = {}, responseFormat = 'text', projectId, orgId, threadId, chatGroupId, contextSource, } = req.body;
            const { domain } = req.params;
            if (!query) {
                res.status(400).json({
                    success: false,
                    message: 'Query is required',
                });
                return;
            }
            // Map route param to domain enum
            const domainEnum = ArgusController.mapRouteToDomain(domain);
            if (!domainEnum) {
                res.status(400).json({
                    success: false,
                    message: `Invalid domain: ${domain}`,
                });
                return;
            }
            // Get user context
            const userId = req.auth?.payload?.sub || req.auth?.payload?.id;
            const username = req.auth?.payload?.email;
            // Normalize and sanitize filters
            let filters = rawFilters;
            // If filters is a JSON string, try to parse it
            if (typeof filters === 'string') {
                try {
                    filters = JSON.parse(filters);
                }
                catch {
                    filters = {};
                }
            }
            // Ensure filters is a plain object. Keep chatHistory when present — Argus agent uses it for follow-ups.
            if (!filters || typeof filters !== 'object' || Array.isArray(filters)) {
                filters = {};
            }
            else {
                const { chatHistory, ...rest } = filters;
                filters = {
                    ...rest,
                    ...(Array.isArray(chatHistory) ? { chatHistory } : {}),
                };
            }
            // Security-config: on the first user query, enrich with application details from DB
            // so Argus can draft applicationDefinition/plugins/strategies using real metadata.
            if (domainEnum === types_1.ArgusDomain.SECURITY_CONFIG) {
                const applicationIdRaw = filters?.applicationId;
                const applicationId = typeof applicationIdRaw === 'string' && applicationIdRaw.trim() ? applicationIdRaw.trim() : null;
                const chatHistory = Array.isArray(filters?.chatHistory) ? filters.chatHistory : [];
                // Client sends the current user message inside chatHistory, so "first turn" is one user message and no prior assistant.
                const isFirstTurn = chatHistory.length <= 1 &&
                    !chatHistory.some((m) => m && m.role === 'assistant');
                if (applicationId && isFirstTurn && !filters?.applicationDetails) {
                    try {
                        const db = (0, database_1.getDb)();
                        const rows = await db
                            .select({
                            id: tables_1.applicationsTable.id,
                            name: tables_1.applicationsTable.name,
                            description: tables_1.applicationsTable.description,
                            useCase: tables_1.applicationsTable.useCase,
                            providerType: tables_1.applicationsTable.provider_type,
                            isAgentic: tables_1.applicationsTable.isAgentic,
                            enableEncryption: tables_1.applicationsTable.enableEncryption,
                        })
                            .from(tables_1.applicationsTable)
                            .where((0, drizzle_orm_1.and)((0, drizzle_orm_1.eq)(tables_1.applicationsTable.id, applicationId), ...(projectId ? [(0, drizzle_orm_1.eq)(tables_1.applicationsTable.projectId, String(projectId))] : [])))
                            .limit(1);
                        if (rows.length > 0) {
                            filters.applicationDetails = rows[0];
                        }
                    }
                    catch (e) {
                        logger_1.default.warn(`Argus securityconfig: failed to load applicationDetails for ${applicationId}: ${e}`);
                    }
                }
                // Always load current config from DB (when scoped to a securityConfigId),
                // and inject it into filters so the agent/tool can update the current config.
                const securityConfigIdRaw = filters?.securityConfigId;
                const securityConfigId = typeof securityConfigIdRaw === 'string' && securityConfigIdRaw.trim()
                    ? securityConfigIdRaw.trim()
                    : null;
                if (securityConfigId) {
                    try {
                        const db = (0, database_1.getDb)();
                        const rows = await db
                            .select({
                            config: tables_1.securityConfigTable.config,
                            projectId: tables_1.securityConfigTable.projectId,
                        })
                            .from(tables_1.securityConfigTable)
                            .where((0, drizzle_orm_1.and)((0, drizzle_orm_1.eq)(tables_1.securityConfigTable.id, securityConfigId), ...(projectId ? [(0, drizzle_orm_1.eq)(tables_1.securityConfigTable.projectId, String(projectId))] : [])))
                            .limit(1);
                        if (rows.length > 0 && rows[0]?.config && typeof rows[0].config === 'object') {
                            filters.currentConfig = rows[0].config;
                            const lockedTarget = rows[0].config?.target;
                            if (lockedTarget && typeof lockedTarget === 'object') {
                                filters.lockedTarget = lockedTarget;
                                // Also help the model by always providing target in the top-level filters.
                                filters.target = lockedTarget;
                            }
                        }
                    }
                    catch (e) {
                        logger_1.default.warn(`Argus securityconfig: failed to load currentConfig for ${securityConfigId}: ${e}`);
                    }
                }
            }
            // Call Argus service
            const service = getArgusService();
            const response = await service.ask(domainEnum, query, filters, {
                userId,
                projectId,
                orgId,
                responseFormat,
                threadId,
                username,
                chatGroupId,
                contextSource,
            });
            // Security-config: if Argus returned a config payload, persist it immediately
            // so the next turn's "current config" matches what the assistant returned.
            if (domainEnum === types_1.ArgusDomain.SECURITY_CONFIG) {
                const answerText = response?.answer;
                const payload = (0, extractDraftSecurityConfigPayload_1.extractDraftSecurityConfigPayload)({
                    answer: typeof answerText === 'string' ? answerText : undefined,
                    metadata: response?.metadata,
                });
                if (payload?.config && typeof payload.config === 'object' && response && typeof response === 'object') {
                    response.metadata = {
                        ...(response.metadata && typeof response.metadata === 'object'
                            ? response.metadata
                            : {}),
                        securityConfigUpdated: true,
                    };
                }
                const securityConfigIdRaw = filters?.securityConfigId;
                const securityConfigId = typeof securityConfigIdRaw === 'string' && securityConfigIdRaw.trim()
                    ? securityConfigIdRaw.trim()
                    : null;
                if (securityConfigId && payload?.config && typeof payload.config === 'object') {
                    const lockedTarget = filters?.lockedTarget ??
                        (filters?.currentConfig && typeof filters.currentConfig === 'object'
                            ? filters.currentConfig.target
                            : undefined);
                    const nextConfig = { ...payload.config };
                    if (lockedTarget && typeof lockedTarget === 'object') {
                        nextConfig.target = lockedTarget;
                    }
                    try {
                        const db = (0, database_1.getDb)();
                        await db
                            .update(tables_1.securityConfigTable)
                            .set({ config: nextConfig, updatedAt: new Date() })
                            .where((0, drizzle_orm_1.and)((0, drizzle_orm_1.eq)(tables_1.securityConfigTable.id, securityConfigId), ...(projectId ? [(0, drizzle_orm_1.eq)(tables_1.securityConfigTable.projectId, String(projectId))] : [])));
                    }
                    catch (e) {
                        logger_1.default.warn(`Argus securityconfig: failed to persist config for ${securityConfigId}: ${e}`);
                    }
                }
            }
            res.json({
                success: true,
                data: response,
            });
        }
        catch (error) {
            logger_1.default.error(`Argus ask error: ${error}`);
            logger_1.default.error(`Error type: ${error instanceof Error ? error.constructor.name : typeof error}`);
            logger_1.default.error(`Error stack: ${error instanceof Error ? error.stack : 'N/A'}`);
            const rawMessage = error instanceof Error ? error.message : String(error);
            let userMessage = "Argus couldn't process this query with the available data. Please try rephrasing or simplifying your request.";
            // Special-case very large message / payload errors to give a clearer hint
            if (rawMessage.includes("string too long") || rawMessage.includes("Invalid 'messages") || rawMessage.includes("maximum context length") || rawMessage.includes("resulted in") && rawMessage.includes("tokens")) {
                userMessage =
                    "This request is too large for Argus to process. Please shorten your query or reduce the amount of content and try again.";
            }
            else if (rawMessage.includes("500 status code") || rawMessage.includes("status code (no body)")) {
                userMessage =
                    "The AI service encountered a temporary error. Please try again in a moment. If the problem persists, try rephrasing your query.";
            }
            else if (rawMessage.includes("timeout") || rawMessage.includes("Timeout")) {
                userMessage =
                    "The query took too long to process. Please try simplifying your query or breaking it into smaller parts.";
            }
            else if (rawMessage.includes("rate limit") || rawMessage.includes("Rate limit")) {
                userMessage =
                    "The service is currently experiencing high demand. Please try again in a few moments.";
            }
            res.status(500).json({
                success: false,
                message: userMessage,
            });
        }
    }
    /**
     * GET /api/argus/history
     * Load previous Argus chat history for a given context
     * Can be used from traces, sessions, testruns, or global pages.
     */
    static async getHistory(req, res) {
        try {
            const { domain, traceId, sessionId, testRunId, applicationId, securityConfigId, contextSource, chatGroupId, projectId, limit, } = req.query;
            const db = (0, database_1.getDb)();
            const conditions = [];
            // Scope to current user
            const userId = req.auth?.payload?.sub || req.auth?.payload?.id;
            if (userId) {
                conditions.push((0, drizzle_orm_1.eq)(tables_1.argusChatHistoryTable.userId, userId));
            }
            if (projectId) {
                conditions.push((0, drizzle_orm_1.eq)(tables_1.argusChatHistoryTable.projectId, projectId));
            }
            if (domain) {
                conditions.push((0, drizzle_orm_1.eq)(tables_1.argusChatHistoryTable.type, domain));
            }
            if (contextSource) {
                // Back-compat: older chat rows may have NULL contextSource.
                // For certain scoped contexts (testruns/security configs), allow NULL so history still loads.
                if (testRunId || securityConfigId) {
                    conditions.push((0, drizzle_orm_1.or)((0, drizzle_orm_1.eq)(tables_1.argusChatHistoryTable.contextSource, contextSource), (0, drizzle_orm_1.isNull)(tables_1.argusChatHistoryTable.contextSource)));
                }
                else {
                    conditions.push((0, drizzle_orm_1.eq)(tables_1.argusChatHistoryTable.contextSource, contextSource));
                }
            }
            if (traceId) {
                conditions.push((0, drizzle_orm_1.eq)(tables_1.argusChatHistoryTable.traceId, traceId));
            }
            if (sessionId) {
                conditions.push((0, drizzle_orm_1.eq)(tables_1.argusChatHistoryTable.sessionId, sessionId));
            }
            if (testRunId) {
                conditions.push((0, drizzle_orm_1.eq)(tables_1.argusChatHistoryTable.testRunId, testRunId));
            }
            if (applicationId) {
                conditions.push((0, drizzle_orm_1.eq)(tables_1.argusChatHistoryTable.applicationId, applicationId));
            }
            if (securityConfigId) {
                conditions.push((0, drizzle_orm_1.eq)(tables_1.argusChatHistoryTable.securityConfigId, securityConfigId));
            }
            if (chatGroupId) {
                conditions.push((0, drizzle_orm_1.eq)(tables_1.argusChatHistoryTable.chatGroupId, chatGroupId));
            }
            const whereClause = conditions.length > 0 ? (0, drizzle_orm_1.and)(...conditions) : undefined;
            const limitNumber = limit ? Number(limit) : 20;
            const rows = await db
                .select()
                .from(tables_1.argusChatHistoryTable)
                .where(whereClause)
                .orderBy((0, drizzle_orm_1.desc)(tables_1.argusChatHistoryTable.createdAt))
                .limit(limitNumber);
            res.json({
                success: true,
                data: rows,
            });
        }
        catch (error) {
            logger_1.default.error(`Argus getHistory error: ${error}`);
            res.status(500).json({
                success: false,
                message: error instanceof Error ? error.message : 'Internal server error',
            });
        }
    }
    /**
     * GET /api/argus/search
     * Search chat history by query text or result text
     */
    static async searchHistory(req, res) {
        try {
            const { domain, searchText, projectId, contextSource, limit = 20, } = req.query;
            if (!searchText || typeof searchText !== 'string' || searchText.trim().length === 0) {
                res.status(400).json({
                    success: false,
                    message: 'searchText is required',
                });
                return;
            }
            const db = (0, database_1.getDb)();
            const userId = req.auth?.payload?.sub || req.auth?.payload?.id;
            const conditions = [];
            // Scope to current user
            if (userId) {
                conditions.push((0, drizzle_orm_1.eq)(tables_1.argusChatHistoryTable.userId, userId));
            }
            if (projectId) {
                conditions.push((0, drizzle_orm_1.eq)(tables_1.argusChatHistoryTable.projectId, projectId));
            }
            if (domain) {
                conditions.push((0, drizzle_orm_1.eq)(tables_1.argusChatHistoryTable.type, domain));
            }
            if (contextSource) {
                conditions.push((0, drizzle_orm_1.eq)(tables_1.argusChatHistoryTable.contextSource, contextSource));
            }
            // Search in both query and result fields
            const searchPattern = `%${searchText}%`;
            conditions.push((0, drizzle_orm_1.or)((0, drizzle_orm_1.ilike)(tables_1.argusChatHistoryTable.query, searchPattern), (0, drizzle_orm_1.ilike)(tables_1.argusChatHistoryTable.result, searchPattern)));
            const whereClause = (0, drizzle_orm_1.and)(...conditions);
            const limitNumber = Number(limit);
            const rows = await db
                .select()
                .from(tables_1.argusChatHistoryTable)
                .where(whereClause)
                .orderBy((0, drizzle_orm_1.desc)(tables_1.argusChatHistoryTable.createdAt))
                .limit(limitNumber);
            res.json({
                success: true,
                data: rows,
            });
        }
        catch (error) {
            logger_1.default.error(`Argus searchHistory error: ${error}`);
            res.status(500).json({
                success: false,
                message: error instanceof Error ? error.message : 'Internal server error',
            });
        }
    }
    /**
     * GET /api/argus/chats
     * Get list of previous chat conversations (grouped by threadId or context)
     */
    static async getChatList(req, res) {
        try {
            const { domain, projectId, traceId, sessionId, testRunId, applicationId, contextSource, limit = 10, offset = 0, } = req.query;
            const db = (0, database_1.getDb)();
            const userId = req.auth?.payload?.sub || req.auth?.payload?.id;
            const conditions = [];
            // Scope to current user
            if (userId) {
                conditions.push((0, drizzle_orm_1.eq)(tables_1.argusChatHistoryTable.userId, userId));
            }
            if (projectId) {
                conditions.push((0, drizzle_orm_1.eq)(tables_1.argusChatHistoryTable.projectId, projectId));
            }
            if (domain && domain !== 'undefined') {
                conditions.push((0, drizzle_orm_1.eq)(tables_1.argusChatHistoryTable.type, domain));
            }
            else {
                // Argus home chat list is domain-agnostic; exclude security-config drafting chats.
                conditions.push((0, drizzle_orm_1.sql) `${tables_1.argusChatHistoryTable.type} <> 'securityconfig'`);
            }
            if (contextSource) {
                if (testRunId) {
                    conditions.push((0, drizzle_orm_1.or)((0, drizzle_orm_1.eq)(tables_1.argusChatHistoryTable.contextSource, contextSource), (0, drizzle_orm_1.isNull)(tables_1.argusChatHistoryTable.contextSource)));
                }
                else {
                    conditions.push((0, drizzle_orm_1.eq)(tables_1.argusChatHistoryTable.contextSource, contextSource));
                }
            }
            if (traceId) {
                conditions.push((0, drizzle_orm_1.eq)(tables_1.argusChatHistoryTable.traceId, traceId));
            }
            if (sessionId) {
                conditions.push((0, drizzle_orm_1.eq)(tables_1.argusChatHistoryTable.sessionId, sessionId));
            }
            if (testRunId) {
                conditions.push((0, drizzle_orm_1.eq)(tables_1.argusChatHistoryTable.testRunId, testRunId));
            }
            if (applicationId) {
                conditions.push((0, drizzle_orm_1.eq)(tables_1.argusChatHistoryTable.applicationId, applicationId));
            }
            const whereClause = conditions.length > 0 ? (0, drizzle_orm_1.and)(...conditions) : undefined;
            const limitNumber = Math.min(100, Math.max(1, Number.parseInt(String(limit), 10) || 10));
            const offsetNumber = Math.max(0, Number.parseInt(String(offset), 10) || 0);
            // Group key: prefer explicit chat_group_id; fall back to legacy thread/context key.
            const groupKeyExpr = (0, drizzle_orm_1.sql) `coalesce(
        ${tables_1.argusChatHistoryTable.chatGroupId},
        ${tables_1.argusChatHistoryTable.threadId},
        ${tables_1.argusChatHistoryTable.traceId},
        ${tables_1.argusChatHistoryTable.sessionId},
        ${tables_1.argusChatHistoryTable.testRunId},
        ${tables_1.argusChatHistoryTable.applicationId},
        ${tables_1.argusChatHistoryTable.id}
      )`.as('group_key');
            const latestPerGroup = db
                .select({
                groupKey: groupKeyExpr,
                maxCreatedAt: (0, drizzle_orm_1.max)(tables_1.argusChatHistoryTable.createdAt).as('max_created_at'),
            })
                .from(tables_1.argusChatHistoryTable)
                .where(whereClause)
                .groupBy(groupKeyExpr)
                .as('latest_per_group');
            // Join back to the history table to fetch the latest row per group.
            const rows = await db
                .select({
                row: tables_1.argusChatHistoryTable,
                applicationName: tables_1.applicationsTable.name,
            })
                .from(tables_1.argusChatHistoryTable)
                .leftJoin(tables_1.applicationsTable, (0, drizzle_orm_1.eq)(tables_1.argusChatHistoryTable.applicationId, tables_1.applicationsTable.id))
                .innerJoin(latestPerGroup, (0, drizzle_orm_1.and)((0, drizzle_orm_1.eq)(tables_1.argusChatHistoryTable.createdAt, latestPerGroup.maxCreatedAt), (0, drizzle_orm_1.sql) `coalesce(
              ${tables_1.argusChatHistoryTable.chatGroupId},
              ${tables_1.argusChatHistoryTable.threadId},
              ${tables_1.argusChatHistoryTable.traceId},
              ${tables_1.argusChatHistoryTable.sessionId},
              ${tables_1.argusChatHistoryTable.testRunId},
              ${tables_1.argusChatHistoryTable.applicationId},
              ${tables_1.argusChatHistoryTable.id}
            ) = ${latestPerGroup.groupKey}`))
                .orderBy((0, drizzle_orm_1.desc)(tables_1.argusChatHistoryTable.createdAt))
                .offset(offsetNumber)
                .limit(limitNumber);
            res.json({
                success: true,
                data: rows.map((r) => ({
                    ...r.row,
                    applicationName: r.applicationName,
                })),
            });
        }
        catch (error) {
            logger_1.default.error(`Argus getChatList error: ${error}`);
            res.status(500).json({
                success: false,
                message: error instanceof Error ? error.message : 'Internal server error',
            });
        }
    }
    /**
     * POST /api/argus/chat-groups/new
     * Mark the previous group inactive and return a new chatGroupId for this context.
     */
    static async createNewChatGroup(req, res) {
        try {
            const { domain, projectId, traceId, sessionId, testRunId, applicationId, contextSource, previousChatGroupId, } = req.body;
            if (!projectId || typeof projectId !== 'string') {
                res.status(400).json({ success: false, message: 'projectId is required' });
                return;
            }
            if (!domain || typeof domain !== 'string') {
                res.status(400).json({ success: false, message: 'domain is required' });
                return;
            }
            if (!contextSource || typeof contextSource !== 'string') {
                res.status(400).json({ success: false, message: 'contextSource is required' });
                return;
            }
            const userId = req.auth?.payload?.sub || req.auth?.payload?.id;
            const db = (0, database_1.getDb)();
            if (previousChatGroupId && typeof previousChatGroupId === 'string') {
                const conditions = [
                    (0, drizzle_orm_1.eq)(tables_1.argusChatHistoryTable.projectId, projectId),
                    (0, drizzle_orm_1.eq)(tables_1.argusChatHistoryTable.type, domain),
                    (0, drizzle_orm_1.eq)(tables_1.argusChatHistoryTable.contextSource, contextSource),
                    (0, drizzle_orm_1.eq)(tables_1.argusChatHistoryTable.chatGroupId, previousChatGroupId),
                ];
                if (userId) {
                    conditions.push((0, drizzle_orm_1.eq)(tables_1.argusChatHistoryTable.userId, userId));
                }
                if (traceId) {
                    conditions.push((0, drizzle_orm_1.eq)(tables_1.argusChatHistoryTable.traceId, traceId));
                }
                if (sessionId) {
                    conditions.push((0, drizzle_orm_1.eq)(tables_1.argusChatHistoryTable.sessionId, sessionId));
                }
                if (testRunId) {
                    conditions.push((0, drizzle_orm_1.eq)(tables_1.argusChatHistoryTable.testRunId, testRunId));
                }
                if (applicationId) {
                    conditions.push((0, drizzle_orm_1.eq)(tables_1.argusChatHistoryTable.applicationId, applicationId));
                }
                await db
                    .update(tables_1.argusChatHistoryTable)
                    .set({ chatGroupStatus: 'inactive' })
                    .where((0, drizzle_orm_1.and)(...conditions));
            }
            const newChatGroupId = (0, crypto_1.randomUUID)();
            res.json({
                success: true,
                data: {
                    chatGroupId: newChatGroupId,
                    contextSource,
                },
            });
        }
        catch (error) {
            logger_1.default.error(`Argus createNewChatGroup error: ${error}`);
            res.status(500).json({
                success: false,
                message: error instanceof Error ? error.message : 'Internal server error',
            });
        }
    }
    /**
     * POST /api/argus/chat-groups/activate
     * Mark the given chatGroupId active (and others inactive) for this context scope.
     */
    static async activateChatGroup(req, res) {
        try {
            const { domain, projectId, traceId, sessionId, testRunId, applicationId, contextSource, chatGroupId, } = req.body;
            if (!projectId || typeof projectId !== 'string') {
                res.status(400).json({ success: false, message: 'projectId is required' });
                return;
            }
            if (!domain || typeof domain !== 'string') {
                res.status(400).json({ success: false, message: 'domain is required' });
                return;
            }
            if (!contextSource || typeof contextSource !== 'string') {
                res.status(400).json({ success: false, message: 'contextSource is required' });
                return;
            }
            if (!chatGroupId || typeof chatGroupId !== 'string') {
                res.status(400).json({ success: false, message: 'chatGroupId is required' });
                return;
            }
            const userId = req.auth?.payload?.sub || req.auth?.payload?.id;
            const db = (0, database_1.getDb)();
            const baseConditions = [
                (0, drizzle_orm_1.eq)(tables_1.argusChatHistoryTable.projectId, projectId),
                (0, drizzle_orm_1.eq)(tables_1.argusChatHistoryTable.type, domain),
                (0, drizzle_orm_1.eq)(tables_1.argusChatHistoryTable.contextSource, contextSource),
            ];
            if (userId) {
                baseConditions.push((0, drizzle_orm_1.eq)(tables_1.argusChatHistoryTable.userId, userId));
            }
            if (traceId) {
                baseConditions.push((0, drizzle_orm_1.eq)(tables_1.argusChatHistoryTable.traceId, traceId));
            }
            if (sessionId) {
                baseConditions.push((0, drizzle_orm_1.eq)(tables_1.argusChatHistoryTable.sessionId, sessionId));
            }
            if (testRunId) {
                baseConditions.push((0, drizzle_orm_1.eq)(tables_1.argusChatHistoryTable.testRunId, testRunId));
            }
            if (applicationId) {
                baseConditions.push((0, drizzle_orm_1.eq)(tables_1.argusChatHistoryTable.applicationId, applicationId));
            }
            // Mark all other groups inactive (best-effort)
            await db
                .update(tables_1.argusChatHistoryTable)
                .set({ chatGroupStatus: 'inactive' })
                .where((0, drizzle_orm_1.and)(...baseConditions, (0, drizzle_orm_1.sql) `${tables_1.argusChatHistoryTable.chatGroupId} is not null`, (0, drizzle_orm_1.sql) `${tables_1.argusChatHistoryTable.chatGroupId} <> ${chatGroupId}`));
            // Mark this group active
            await db
                .update(tables_1.argusChatHistoryTable)
                .set({ chatGroupStatus: 'active' })
                .where((0, drizzle_orm_1.and)(...baseConditions, (0, drizzle_orm_1.eq)(tables_1.argusChatHistoryTable.chatGroupId, chatGroupId)));
            res.json({
                success: true,
                data: { chatGroupId, contextSource },
            });
        }
        catch (error) {
            logger_1.default.error(`Argus activateChatGroup error: ${error}`);
            res.status(500).json({
                success: false,
                message: error instanceof Error ? error.message : 'Internal server error',
            });
        }
    }
    /**
     * POST /api/argus/feedback
     * Save user feedback for an Argus assistant response.
     */
    static async submitFeedback(req, res) {
        try {
            const { chatId, feedback } = req.body;
            if (!chatId || typeof chatId !== 'string') {
                res.status(400).json({
                    success: false,
                    message: 'chatId is required',
                });
                return;
            }
            if (feedback !== 'up' && feedback !== 'down' && feedback !== null) {
                res.status(400).json({
                    success: false,
                    message: "feedback must be 'up', 'down', or null",
                });
                return;
            }
            const userId = req.auth?.payload?.sub || req.auth?.payload?.id;
            const db = (0, database_1.getDb)();
            const conditions = [(0, drizzle_orm_1.eq)(tables_1.argusChatHistoryTable.id, chatId)];
            if (userId) {
                conditions.push((0, drizzle_orm_1.eq)(tables_1.argusChatHistoryTable.userId, userId));
            }
            const rows = await db
                .select({
                id: tables_1.argusChatHistoryTable.id,
            })
                .from(tables_1.argusChatHistoryTable)
                .where((0, drizzle_orm_1.and)(...conditions))
                .limit(1);
            if (!rows.length) {
                res.status(404).json({
                    success: false,
                    message: 'Argus chat not found',
                });
                return;
            }
            const feedbackValue = feedback === 'up' ? 1 : feedback === 'down' ? -1 : null;
            const feedbackAtValue = feedback === null ? null : new Date();
            await db
                .update(tables_1.argusChatHistoryTable)
                .set({
                userFeedback: feedbackValue,
                userFeedbackAt: feedbackAtValue,
            })
                .where((0, drizzle_orm_1.and)(...conditions));
            res.json({
                success: true,
                data: {
                    chatId,
                    feedback,
                },
            });
        }
        catch (error) {
            logger_1.default.error(`Argus submitFeedback error: ${error}`);
            res.status(500).json({
                success: false,
                message: error instanceof Error ? error.message : 'Internal server error',
            });
        }
    }
    /**
     * Map route parameter to domain enum
     */
    static mapRouteToDomain(route) {
        const mapping = {
            trupulse: types_1.ArgusDomain.TRU_PULSE,
            trueval: types_1.ArgusDomain.TRU_EVAL,
            truscout: types_1.ArgusDomain.TRU_SCOUT,
            truguard: types_1.ArgusDomain.TRU_GUARD,
            securityconfig: types_1.ArgusDomain.SECURITY_CONFIG,
        };
        return mapping[route.toLowerCase()] || null;
    }
}
exports.ArgusController = ArgusController;
//# sourceMappingURL=argusController.js.map