"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ArchitectureEngine = void 0;
const cell_store_1 = require("../walls/06-memory/stores/cell-store");
const RX = {
    reactImport: /from\s+['"]react['"]/i,
    rhf: /from\s+['"]react-hook-form['"]/i,
    formik: /from\s+['"]formik['"]/i,
    context: /\b(?:createContext|useContext)\s*\(/g,
    hooks: /\buse(?:State|Effect|Reducer|Callback|Memo|Ref|Context|Query|Mutation|Form|Navigate|Params|Location|Theme|Auth)\w*\s*\(/g,
    hoc: /\(?\w+\s*\(?\s*\w+\s*\)\s*\(?\s*\w+/,
    renderProps: /\brender\s*=\s*\{|children\s*=\s*\{.*\bfunction\b/,
    barrel: /export\s+\*\s+from\s+/g,
    directImport: /import\s+\{[\s\S]*?\}\s+from\s+['"]\.\./g,
    typesColocated: /interface\s+\w+|type\s+\w+\s*=/g,
    repository: /\brepository\b|\bRepo\b|\.find\b|\.save\b|\.delete\b/i,
    service: /\bservice\b|\bservice\.\w+|\.service\b/i,
    controller: /\.(?:get|post|put|delete|patch)\s*\(/g,
    errorObj: /\{[\s\S]{0,100}error[\s\S]{0,100}message[\s\S]{0,100}\}/i,
    errorString: /['"][\w\s]+error['"]|res\.(?:status|json)\s*\([^)]*['"]/i,
    statusCode: /\b(?:status|code)\s*:\s*\d{3}/g,
    middleware: /\.(?:use|useAsync|useErrorHandler)\s*\(/g,
    middlewareRoute: /router\.(?:use|get|post)\s*\([^)]*,\s*(?:async\s*)?\(/g,
    validation: /\b(?:validate|parse|safeParse|check)\s*\(/g,
};
class ArchitectureEngine {
    store;
    data;
    constructor(cellDir) {
        this.store = new cell_store_1.CellStore(cellDir);
        this.data = this.store.read('architecture.json', 'personal') || {
            version: 1, updated: Date.now(),
            frontend: {
                componentStructure: { atomic: 0, feature: 0, page: 0, unknown: 0 },
                formHandling: { rhf: 0, formik: 0, custom: 0, none: 0, topPattern: 'unknown' },
                compositionStyle: { hooks: 0, hoc: 0, renderProps: 0, topPattern: 'unknown' },
                propsDrilling: { directProps: 0, contextUsage: 0, drillingThreshold: 0 },
                customHooks: { total: 0, files: 0, ratio: 0 },
            },
            backend: {
                errorResponse: { errorObject: 0, errorString: 0, statusCodes: 0, format: 'unknown' },
                middlewarePatterns: { global: 0, route: 0, errorHandler: 0 },
                validationPlacement: { controller: 0, service: 0, middleware: 0, topPattern: 'unknown' },
                repositoryPattern: { repository: 0, directDb: 0, ratio: 0 },
                serviceLayer: { service: 0, controller: 0, ratio: 0 },
            },
            projectStructure: {
                folderByFeature: 0, folderByType: 0, hybrid: 0,
                barrelExports: 0, directImports: 0,
                typesCollocated: 0, typesCentral: 0,
            },
            componentStructure: { atomic: 0, feature: 0, page: 0, singleFile: 0, topPattern: 'unknown' },
            configPlacement: { configFile: 0, inline: 0, envFile: 0, constantsFile: 0, constantsInline: 0, utilsFile: 0, utilsInline: 0 },
        };
    }
    analyze(code, filePath) {
        if (!code || code.length < 20)
            return { detected: 0 };
        let detected = 0;
        detected += this.analyzeFrontend(code);
        detected += this.analyzeBackend(code);
        detected += this.analyzeStructure(code, filePath);
        detected += this.analyzeComponentStructure(code, filePath);
        detected += this.analyzeConfigPlacement(code);
        if (detected > 0) {
            this.data.updated = Date.now();
            this.store.write('architecture.json', this.data, 'personal');
        }
        return { detected };
    }
    analyzeFrontend(code) {
        if (!RX.reactImport.test(code) && !code.includes('<') && !code.includes('/>'))
            return 0;
        let found = 0;
        // Form handling
        if (RX.rhf.test(code)) {
            this.data.frontend.formHandling.rhf++;
            found++;
        }
        if (RX.formik.test(code)) {
            this.data.frontend.formHandling.formik++;
            found++;
        }
        if (code.includes('onChange') || code.includes('onSubmit')) {
            this.data.frontend.formHandling.custom++;
            found++;
        }
        // Composition style
        const hookCount = (code.match(RX.hooks) || []).length;
        if (hookCount > 0) {
            this.data.frontend.compositionStyle.hooks += hookCount;
            found++;
        }
        if (RX.hoc.test(code)) {
            this.data.frontend.compositionStyle.hoc++;
        }
        if (RX.renderProps.test(code)) {
            this.data.frontend.compositionStyle.renderProps++;
        }
        // Props drilling vs context
        const props = (code.match(/\{\s*\w+\s*}/g) || []).length;
        const ctx = (code.match(RX.context) || []).length;
        if (props > 0 || ctx > 0) {
            this.data.frontend.propsDrilling.directProps += props;
            this.data.frontend.propsDrilling.contextUsage += ctx;
            const total = this.data.frontend.propsDrilling.directProps + this.data.frontend.propsDrilling.contextUsage;
            this.data.frontend.propsDrilling.drillingThreshold = total > 0
                ? Math.round(this.data.frontend.propsDrilling.directProps / total * 100) : 0;
            found++;
        }
        return found;
    }
    analyzeBackend(code) {
        if (!RX.controller.test(code))
            return 0;
        let found = 0;
        // Error response format
        if (RX.errorObj.test(code)) {
            this.data.backend.errorResponse.errorObject++;
            found++;
        }
        if (RX.errorString.test(code)) {
            this.data.backend.errorResponse.errorString++;
            found++;
        }
        const sc = (code.match(RX.statusCode) || []).length;
        if (sc > 0) {
            this.data.backend.errorResponse.statusCodes += sc;
            found++;
        }
        // Middleware
        if (RX.middleware.test(code)) {
            this.data.backend.middlewarePatterns.global++;
            found++;
        }
        if (RX.middlewareRoute.test(code)) {
            this.data.backend.middlewarePatterns.route++;
            found++;
        }
        if (code.includes('ErrorHandler') || code.includes('errorHandler') || code.includes('error handler')) {
            this.data.backend.middlewarePatterns.errorHandler++;
            found++;
        }
        // Validation placement
        if (RX.validation.test(code) && RX.controller.test(code)) {
            this.data.backend.validationPlacement.controller++;
            found++;
        }
        if (RX.validation.test(code) && code.includes('service')) {
            this.data.backend.validationPlacement.service++;
            found++;
        }
        return found;
    }
    analyzeStructure(code, filePath) {
        const barrels = (code.match(RX.barrel) || []).length;
        const directImports = (code.match(RX.directImport) || []).length;
        if (barrels > 0) {
            this.data.projectStructure.barrelExports += barrels;
        }
        if (directImports > 0) {
            this.data.projectStructure.directImports += directImports;
        }
        const types = (code.match(RX.typesColocated) || []).length;
        if (types > 0) {
            this.data.projectStructure.typesCollocated += types;
        }
        return (barrels + directImports + types) > 0 ? 1 : 0;
    }
    analyzeComponentStructure(code, filePath) {
        if (!filePath)
            return 0;
        const name = filePath.replace(/\\/g, '/');
        if (name.includes('/atoms/') || name.includes('/ui/') || name.includes('/components/'))
            this.data.componentStructure.atomic++;
        else if (name.includes('/features/') || name.includes('/modules/'))
            this.data.componentStructure.feature++;
        else if (name.includes('/pages/') || name.includes('/screens/'))
            this.data.componentStructure.page++;
        else
            this.data.componentStructure.singleFile++;
        const vals = [this.data.componentStructure.atomic, this.data.componentStructure.feature, this.data.componentStructure.page, this.data.componentStructure.singleFile];
        const labels = ['atomic', 'feature', 'page', 'single-file'];
        this.data.componentStructure.topPattern = labels[vals.indexOf(Math.max(...vals))];
        return 1;
    }
    analyzeConfigPlacement(code) {
        if (/config\.(ts|js|json)/i.test(code) || /\b(?:config|configuration|settings)\s*[:=]/i.test(code))
            this.data.configPlacement.configFile++;
        if (/\bprocess\.env\./i.test(code) || /import\.meta\.env\./i.test(code))
            this.data.configPlacement.envFile++;
        if (/\bconst\s+(?:CONFIG|APP_\w+|DEFAULT_\w+)\s*=/i.test(code))
            this.data.configPlacement.constantsFile++;
        if (/\b(?:utils|helpers|common)\//i.test(code) || /\bfrom\s+['"][^'"]*\/(?:utils|helpers|common)['"]/i.test(code))
            this.data.configPlacement.utilsFile++;
        return 1;
    }
    getSummary() {
        const lines = [];
        if (this.data.frontend.compositionStyle.hooks === 0 && this.data.backend.middlewarePatterns.global === 0 && this.data.componentStructure.atomic === 0 && this.data.configPlacement.configFile === 0)
            return lines;
        if (this.data.frontend.compositionStyle.hooks > 0 || this.data.componentStructure.topPattern !== 'unknown') {
            const total = this.data.frontend.compositionStyle.hooks + this.data.frontend.compositionStyle.hoc + this.data.frontend.compositionStyle.renderProps;
            lines.push(`Frontend: ${this.data.frontend.compositionStyle.hooks} hooks, ${total > 0 ? this.data.componentStructure.topPattern + ' structure' : ''}`);
        }
        if (this.data.backend.middlewarePatterns.global > 0 || this.data.backend.errorResponse.errorObject > 0)
            lines.push(`Backend: ${this.data.backend.middlewarePatterns.global} middleware, ${this.data.backend.errorResponse.errorObject} error objects`);
        if (this.data.projectStructure.barrelExports > 0 || this.data.projectStructure.directImports > 0)
            lines.push(`Structure: ${this.data.projectStructure.barrelExports} barrel exports, ${this.data.projectStructure.directImports} direct imports`);
        if (this.data.configPlacement.configFile > 0 || this.data.configPlacement.envFile > 0)
            lines.push(`Config: ${this.data.configPlacement.configFile} files, ${this.data.configPlacement.envFile} env vars`);
        return lines;
    }
}
exports.ArchitectureEngine = ArchitectureEngine;
//# sourceMappingURL=architecture-engine.js.map