"use strict";
/**
 * QASubAgent Implementation
 *
 * Specialized sub-agent for quality assurance and code validation.
 * Uses Claude Sonnet for analytical capabilities.
 */
Object.defineProperty(exports, "__esModule", { value: true });
exports.QASubAgent = void 0;
const hybridAIClient_1 = require("../../utils/hybridAIClient");
const subAgentPersonalities_1 = require("../../constants/subAgentPersonalities");
class QASubAgent {
    constructor() {
        this.name = "QASubAgent";
        this.description = "Meticulous QA engineer with expertise in code review and quality assurance";
        const personality = (0, subAgentPersonalities_1.getSubAgentPersonality)(this.name);
        if (!personality) {
            throw new Error(`Personality not found for ${this.name}`);
        }
        this.personality = personality.systemPrompt;
        this.llmProvider = personality.llmProvider;
        this.expertise = personality.expertise;
        this.ai = new hybridAIClient_1.HybridAIClient();
    }
    async run(input) {
        const { code, component, standards } = input;
        try {
            // 1. Run static checks in parallel
            const [tsCheck, reactCheck, a11yCheck, perfCheck, secCheck] = await Promise.all([
                this.checkTypeScriptCompliance(code, component),
                this.checkReactBestPractices(code, component),
                this.checkAccessibility(code, component),
                this.checkPerformance(code, component),
                this.checkSecurity(code, component),
            ]);
            const staticIssues = [
                ...tsCheck.issues,
                ...reactCheck.issues,
                ...a11yCheck.issues,
                ...perfCheck.issues,
                ...secCheck.issues,
            ];
            const staticDeductions = tsCheck.scoreDeduction +
                reactCheck.scoreDeduction +
                a11yCheck.scoreDeduction +
                perfCheck.scoreDeduction +
                secCheck.scoreDeduction;
            // 2. Use hybrid AI for comprehensive QA analysis
            const prompt = this.buildQAPrompt(code, component, standards, staticIssues);
            const { text: aiResponse } = await this.ai.generateText(prompt);
            // Parse AI response for issues and score
            const analysis = this.parseAIResponse(aiResponse);
            // Merge issues and subtract static deductions
            const mergedIssues = [...staticIssues, ...analysis.issues];
            const finalScore = Math.max(0, analysis.score - staticDeductions);
            return {
                isValid: finalScore >= 70,
                issues: mergedIssues,
                score: finalScore,
            };
        }
        catch (error) {
            throw new Error(`QA validation failed: ${error instanceof Error ? error.message : "Unknown error"}`);
        }
    }
    async validate(input) {
        return !!(input.code && input.component);
    }
    async getStatus() {
        return {
            name: this.name,
            status: "idle",
            errorCount: 0,
            successCount: 0,
        };
    }
    async checkTypeScriptCompliance(code, component) {
        const issues = [];
        let scoreDeduction = 0;
        // Check for proper TypeScript usage
        if (!code.includes("interface") && !code.includes("type")) {
            issues.push({
                type: "warning",
                message: "Component lacks proper TypeScript interface definitions",
                severity: "medium",
            });
            scoreDeduction += 10;
        }
        if (code.includes("any")) {
            issues.push({
                type: "warning",
                message: 'Usage of "any" type detected - consider using more specific types',
                severity: "low",
            });
            scoreDeduction += 5;
        }
        if (!code.includes("Props")) {
            issues.push({
                type: "suggestion",
                message: "Consider adding a Props interface for better type safety",
                severity: "low",
            });
            scoreDeduction += 2;
        }
        return { issues, scoreDeduction };
    }
    async checkReactBestPractices(code, component) {
        const issues = [];
        let scoreDeduction = 0;
        // Check for React best practices
        if (!code.includes('"use client"') && code.includes("useState")) {
            issues.push({
                type: "error",
                message: 'Client component missing "use client" directive',
                severity: "high",
            });
            scoreDeduction += 15;
        }
        if (code.includes("console.log")) {
            issues.push({
                type: "warning",
                message: "Console.log statements should be removed in production code",
                severity: "medium",
            });
            scoreDeduction += 5;
        }
        if (!code.includes("className") && code.includes("<div")) {
            issues.push({
                type: "suggestion",
                message: "Consider adding className prop for styling flexibility",
                severity: "low",
            });
            scoreDeduction += 2;
        }
        return { issues, scoreDeduction };
    }
    async checkAccessibility(code, component) {
        const issues = [];
        let scoreDeduction = 0;
        // Check for accessibility features
        if (code.includes("<button") && !code.includes("aria-")) {
            issues.push({
                type: "suggestion",
                message: "Consider adding ARIA attributes for better accessibility",
                severity: "low",
            });
            scoreDeduction += 3;
        }
        if (code.includes("<img") && !code.includes("alt=")) {
            issues.push({
                type: "warning",
                message: "Images should have alt attributes for accessibility",
                severity: "medium",
            });
            scoreDeduction += 8;
        }
        return { issues, scoreDeduction };
    }
    async checkPerformance(code, component) {
        const issues = [];
        let scoreDeduction = 0;
        // Check for performance considerations
        if (code.includes("useEffect") && !code.includes("[]")) {
            issues.push({
                type: "suggestion",
                message: "Consider adding dependency array to useEffect for better performance",
                severity: "low",
            });
            scoreDeduction += 3;
        }
        if (code.includes("map(") && code.includes("key=")) {
            // This is good - no deduction
        }
        else if (code.includes("map(")) {
            issues.push({
                type: "warning",
                message: "Array.map() should include key prop for React optimization",
                severity: "medium",
            });
            scoreDeduction += 8;
        }
        return { issues, scoreDeduction };
    }
    async checkSecurity(code, component) {
        const issues = [];
        let scoreDeduction = 0;
        // Check for security concerns
        if (code.includes("dangerouslySetInnerHTML")) {
            issues.push({
                type: "warning",
                message: "dangerouslySetInnerHTML can be a security risk - ensure content is sanitized",
                severity: "high",
            });
            scoreDeduction += 12;
        }
        if (code.includes("eval(")) {
            issues.push({
                type: "error",
                message: "eval() usage detected - this is a security vulnerability",
                severity: "high",
            });
            scoreDeduction += 20;
        }
        return { issues, scoreDeduction };
    }
    /**
     * Build QA prompt for Ollama
     */
    buildQAPrompt(code, component, standards, staticIssues = []) {
        const componentInfo = typeof component === "string" ? component : JSON.stringify(component);
        const standardsText = standards?.join(", ") ||
            "React, TypeScript, accessibility, performance, security";
        const staticIssuesText = staticIssues.length > 0
            ? `\nHere are some automatically detected issues to review and confirm:\n` +
                staticIssues.map(i => `- [${i.type.toUpperCase()}] ${i.message} (severity: ${i.severity})`).join("\n")
            : "";
        return `[mycontext] Plan: plan → generate → QA → docs → preview (→ checks)\nYou are a meticulous QA engineer specializing in React/TypeScript code review. Analyze the following component for quality issues.

Component Information:
${componentInfo}

Component Code:
\`\`\`tsx
${code}
\`\`\`

Standards to check: ${standardsText}
${staticIssuesText}

Analyze the code and return a JSON response with this exact structure:
{
  "score": number (0-100),
  "issues": [
    {
      "type": "error" | "warning" | "suggestion",
      "message": "string",
      "severity": "high" | "medium" | "low"
    }
  ]
}

Focus on:
- TypeScript compliance and type safety
- React best practices and patterns
- Accessibility (ARIA, semantic HTML, keyboard navigation)
- Performance (hooks usage, memoization, dependencies)
- Security (XSS prevention, input validation)
- Code structure and maintainability

Return only the JSON response:`;
    }
    /**
     * Parse AI response for QA analysis
     */
    parseAIResponse(aiResponse) {
        try {
            // Try to extract JSON from the response
            const jsonMatch = aiResponse.match(/\{[\s\S]*\}/);
            if (!jsonMatch) {
                throw new Error("No JSON found in AI response");
            }
            const parsed = JSON.parse(jsonMatch[0]);
            // Validate the parsed response
            if (typeof parsed.score !== "number" || !Array.isArray(parsed.issues)) {
                throw new Error("Invalid response structure");
            }
            return {
                score: Math.max(0, Math.min(100, parsed.score)),
                issues: parsed.issues.map((issue) => ({
                    type: issue.type || "suggestion",
                    message: issue.message || "Unknown issue",
                    severity: issue.severity || "medium",
                })),
            };
        }
        catch (error) {
            // Fallback to basic analysis if AI response parsing fails
            console.warn("Failed to parse AI response, using fallback analysis:", error);
            const fallbackIssues = [
                {
                    type: "warning",
                    message: "AI analysis failed, using basic validation",
                    severity: "medium",
                },
            ];
            return {
                score: 70, // Default passing score
                issues: fallbackIssues,
            };
        }
    }
}
exports.QASubAgent = QASubAgent;
//# sourceMappingURL=QASubAgent.js.map