"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
    var ownKeys = function(o) {
        ownKeys = Object.getOwnPropertyNames || function (o) {
            var ar = [];
            for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
            return ar;
        };
        return ownKeys(o);
    };
    return function (mod) {
        if (mod && mod.__esModule) return mod;
        var result = {};
        if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
        __setModuleDefault(result, mod);
        return result;
    };
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.FeatureCompletenessAgent = void 0;
const AICore_1 = require("../../core/ai/AICore");
const fs = __importStar(require("fs-extra"));
const path = __importStar(require("path"));
const DIMENSIONS = [
    "specification",
    "implementation",
    "testing",
    "documentation",
    "i18n",
    "accessibility",
    "security",
];
class FeatureCompletenessAgent {
    constructor() {
        this.name = "FeatureCompletenessAgent";
        this.description = "Evaluates feature completeness across specification, implementation, testing, and documentation dimensions.";
        this.personality = "A thorough QA lead who measures every dimension of feature readiness with precision.";
        this.llmProvider = "github-models";
        this.expertise = ["QA Engineering", "Feature Analysis", "Gap Detection", "Readiness Assessment"];
    }
    getAICore() {
        if (!this.ai) {
            try {
                this.ai = AICore_1.AICore.getInstance();
            }
            catch {
                this.ai = AICore_1.AICore.getInstance({
                    workingDirectory: process.cwd(),
                    fallbackEnabled: true,
                });
            }
        }
        return this.ai;
    }
    getContextJson() {
        try {
            const ctxPath = path.join(process.cwd(), ".mycontext", "context.json");
            if (fs.pathExistsSync(ctxPath)) {
                return fs.readJsonSync(ctxPath);
            }
        }
        catch { }
        return {};
    }
    scoreDimension(feature, dim) {
        const gaps = [];
        let score = 0;
        switch (dim) {
            case "specification":
                if (feature.acceptanceCriteria?.length > 0) {
                    score = Math.min(100, feature.acceptanceCriteria.length * 25);
                }
                else {
                    gaps.push("No acceptance criteria defined");
                }
                if (feature.dependencies)
                    score += 10;
                if (feature.description)
                    score += 10;
                break;
            case "implementation":
                if (feature.status === "completed")
                    score = 100;
                else if (feature.status === "in-progress")
                    score = 50;
                else
                    score = 0;
                if (feature.componentIds?.length)
                    score = Math.min(100, score + 10);
                if (feature.routeIds?.length)
                    score = Math.min(100, score + 10);
                if (score < 50)
                    gaps.push("Feature not yet implemented or in early stages");
                break;
            case "testing":
                if (feature.testIds?.length)
                    score = Math.min(100, feature.testIds.length * 20);
                else
                    gaps.push("No test IDs associated with feature");
                score = feature.status === "completed" ? Math.max(score, 60) : score;
                break;
            case "documentation":
                if (feature.description)
                    score += 30;
                if (feature.spec)
                    score += 40;
                if (feature.acceptanceCriteria?.length)
                    score += 30;
                if (!feature.description)
                    gaps.push("Missing feature description");
                if (!feature.spec)
                    gaps.push("Missing feature specification");
                break;
            case "i18n":
                gaps.push("i18n status: run semantics:extract to check for hardcoded strings");
                score = 30;
                break;
            case "accessibility":
                gaps.push("Accessibility: run doctor to validate a11y patterns");
                score = 20;
                break;
            case "security":
                if (feature.actionIds?.length) {
                    gaps.push("Security review recommended for feature with actions");
                    score = 40;
                }
                else {
                    score = 70;
                }
                break;
        }
        return { score: Math.min(100, score), gaps };
    }
    async run(input) {
        const context = this.getContextJson();
        const features = context?.features || [];
        const targetFeatures = input.featureIds
            ? features.filter((f) => input.featureIds.includes(f.id))
            : features;
        const featureScores = [];
        const recommendations = [];
        for (const feature of targetFeatures) {
            const dimensions = {};
            const allGaps = [];
            for (const dim of DIMENSIONS) {
                const result = this.scoreDimension(feature, dim);
                dimensions[dim] = result.score;
                allGaps.push(...result.gaps);
            }
            const overallScore = Math.round(Object.values(dimensions).reduce((a, b) => a + b, 0) / DIMENSIONS.length);
            featureScores.push({
                id: feature.id,
                name: feature.name || feature.id,
                overallScore,
                dimensions,
                gaps: allGaps,
            });
        }
        const avgCompleteness = featureScores.length > 0
            ? Math.round(featureScores.reduce((a, f) => a + f.overallScore, 0) / featureScores.length)
            : 0;
        const lowScorers = featureScores.filter((f) => f.overallScore < (input.minThreshold || 50));
        if (lowScorers.length > 0) {
            recommendations.push(`${lowScorers.length} features below threshold: ${lowScorers.map((f) => f.name).join(", ")}`);
        }
        try {
            const aiCore = this.getAICore();
            const result = await aiCore.generateStructuredText(`You are a QA lead evaluating feature completeness.
Average completeness: ${avgCompleteness}%.
Lowest features: ${featureScores.filter(f => f.overallScore < 50).map(f => f.name).join(", ") || "none"}.
Recommend 2-3 prioritized actions to improve readiness.`, '{ "recs": ["string"] }');
            recommendations.push(...result.recs);
        }
        catch { }
        return {
            totalFeatures: targetFeatures.length,
            features: featureScores,
            avgCompleteness,
            recommendations,
        };
    }
    async validate(input) {
        return true;
    }
}
exports.FeatureCompletenessAgent = FeatureCompletenessAgent;
//# sourceMappingURL=FeatureCompletenessAgent.js.map