"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.I18nAgent = void 0;
const AICore_1 = require("../../core/ai/AICore");
const fs = __importStar(require("fs-extra"));
const path = __importStar(require("path"));
class I18nAgent {
    constructor() {
        this.name = "I18nAgent";
        this.description = "Validates internationalization completeness across features and locales.";
        this.personality = "A polyglot QA engineer who ensures every user-facing string speaks every language.";
        this.llmProvider = "github-models";
        this.expertise = ["Internationalization", "Localization", "Locale Management", "String Extraction"];
    }
    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 {};
    }
    findLocaleFiles() {
        const locales = {};
        const localeDirs = [
            path.join(process.cwd(), "locales"),
            path.join(process.cwd(), "src", "locales"),
            path.join(process.cwd(), "public", "locales"),
            path.join(process.cwd(), "i18n"),
            path.join(process.cwd(), "src", "i18n"),
        ];
        for (const dir of localeDirs) {
            if (fs.pathExistsSync(dir)) {
                const entries = fs.readdirSync(dir, { withFileTypes: true });
                for (const entry of entries) {
                    if (entry.isFile() && (entry.name.endsWith(".json") || entry.name.endsWith(".yml") || entry.name.endsWith(".yaml"))) {
                        const locale = entry.name.replace(/\.(json|ya?ml)$/, "");
                        try {
                            const content = fs.readFileSync(path.join(dir, entry.name), "utf-8");
                            locales[locale] = JSON.parse(content);
                        }
                        catch {
                            locales[locale] = {};
                        }
                    }
                }
            }
        }
        return locales;
    }
    findHardcodedStrings(filePath) {
        try {
            const content = fs.readFileSync(filePath, "utf-8");
            const strings = [];
            const jsxText = content.match(/>([^<]{10,})<\/[a-z]/g);
            if (jsxText) {
                for (const match of jsxText) {
                    const text = match.replace(/^>/, "").replace(/<\/[a-z]+>$/, "").trim();
                    if (text.length > 3 && !text.startsWith("{") && !text.startsWith("`")) {
                        strings.push(text);
                    }
                }
            }
            const placeholderText = content.match(/placeholder="([^"]{5,})"/g);
            if (placeholderText) {
                for (const match of placeholderText) {
                    const text = match.replace(/placeholder="/, "").replace(/"$/, "");
                    strings.push(text);
                }
            }
            const labelText = content.match(/label="([^"]{5,})"/g);
            if (labelText) {
                for (const match of labelText) {
                    const text = match.replace(/label="/, "").replace(/"$/, "");
                    strings.push(text);
                }
            }
            return strings;
        }
        catch {
            return [];
        }
    }
    async run(input) {
        const context = this.getContextJson();
        const features = context?.features || [];
        const localeFiles = this.findLocaleFiles();
        const locales = input.locales || Object.keys(localeFiles);
        const sourceDirs = [path.join(process.cwd(), "src")];
        const missingKeys = [];
        const featuresWithI18n = new Set();
        const targetFeatures = input.featureIds
            ? features.filter((f) => input.featureIds.includes(f.id))
            : features;
        for (const feature of targetFeatures) {
            const featureSrc = sourceDirs.map((d) => path.join(d, feature.id)).filter((d) => fs.pathExistsSync(d));
            for (const dir of featureSrc) {
                try {
                    const walk = (d) => {
                        const entries = fs.readdirSync(d, { withFileTypes: true });
                        for (const entry of entries) {
                            const fullPath = path.join(d, entry.name);
                            if (entry.isDirectory() && !entry.name.startsWith(".")) {
                                walk(fullPath);
                            }
                            else if (entry.isFile() && (entry.name.endsWith(".tsx") || entry.name.endsWith(".ts"))) {
                                const strings = this.findHardcodedStrings(fullPath);
                                for (const str of strings) {
                                    const key = `${feature.id}.${str.substring(0, 30).replace(/\s+/g, "_").toLowerCase()}`;
                                    const missingForLocale = [];
                                    for (const locale of locales) {
                                        const localeData = localeFiles[locale] || {};
                                        let found = false;
                                        const searchIn = (obj, depth = 0) => {
                                            if (depth > 3)
                                                return false;
                                            for (const [, val] of Object.entries(obj)) {
                                                if (typeof val === "string" && val === str)
                                                    return true;
                                                if (typeof val === "object" && val !== null) {
                                                    if (searchIn(val, depth + 1))
                                                        return true;
                                                }
                                            }
                                            return false;
                                        };
                                        if (!searchIn(localeData)) {
                                            missingForLocale.push(locale);
                                        }
                                    }
                                    if (missingForLocale.length > 0 && missingForLocale.length < locales.length) {
                                        missingKeys.push({
                                            featureId: feature.id,
                                            key,
                                            defaultLocaleValue: str,
                                            missingLocales: missingForLocale,
                                            sourceFile: path.relative(process.cwd(), fullPath),
                                        });
                                    }
                                    else if (missingForLocale.length === 0) {
                                        featuresWithI18n.add(feature.id);
                                    }
                                }
                            }
                        }
                    };
                    walk(dir);
                }
                catch { }
            }
        }
        const localeCoverage = {};
        for (const locale of locales) {
            const localeData = localeFiles[locale] || {};
            const keyCount = Object.keys(localeData).length;
            localeCoverage[locale] = keyCount;
        }
        const recommendations = [];
        if (missingKeys.length > 0) {
            recommendations.push(`${missingKeys.length} hardcoded strings found without locale entries. Extract them into locale files.`);
        }
        if (Object.keys(localeFiles).length === 0) {
            recommendations.push("No locale files found. Create an i18n system with at least one locale file.");
        }
        if (featuresWithI18n.size === 0 && targetFeatures.length > 0) {
            recommendations.push("No features have i18n coverage. Add translation keys before shipping.");
        }
        try {
            const aiCore = this.getAICore();
            const result = await aiCore.generateStructuredText(`You are an i18n specialist. ${targetFeatures.length} features analyzed.
${missingKeys.length} untranslated strings found. Locales: ${locales.join(", ")}.
Suggest 2-3 actions to improve internationalization.`, '{ "suggestions": ["string"] }');
            recommendations.push(...result.suggestions);
        }
        catch { }
        return {
            totalFeatures: targetFeatures.length,
            featuresWithI18n: featuresWithI18n.size,
            missingKeys,
            localeCoverage,
            recommendations,
        };
    }
    async validate(input) {
        return true;
    }
}
exports.I18nAgent = I18nAgent;
//# sourceMappingURL=I18nAgent.js.map