"use strict";
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
    return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var SyntaxValidationService_1;
Object.defineProperty(exports, "__esModule", { value: true });
exports.SyntaxValidationService = void 0;
const common_1 = require("@nestjs/common");
const path = require("path");
const fs_1 = require("fs");
const web_tree_sitter_1 = require("web-tree-sitter");
let SyntaxValidationService = SyntaxValidationService_1 = class SyntaxValidationService {
    constructor() {
        this.logger = new common_1.Logger(SyntaxValidationService_1.name);
        this.parserCache = new Map();
        this.grammarMap = {
            '.js': 'tree-sitter-javascript.wasm',
            '.jsx': 'tree-sitter-javascript.wasm',
            '.ts': 'tree-sitter-typescript.wasm',
            '.tsx': 'tree-sitter-tsx.wasm',
            '.json': 'tree-sitter-json.wasm',
            '.html': 'tree-sitter-html.wasm',
            '.css': 'tree-sitter-css.wasm',
            '.py': 'tree-sitter-python.wasm',
            '.rs': 'tree-sitter-rust.wasm',
            '.toml': 'tree-sitter-toml.wasm',
            '.yaml': 'tree-sitter-yaml.wasm',
            '.yml': 'tree-sitter-yaml.wasm',
            '.sh': 'tree-sitter-bash.wasm',
        };
        this.grammarDir = (() => {
            const prodPath = path.resolve(__dirname, '../../bin/grammar/');
            if ((0, fs_1.existsSync)(prodPath)) {
                return prodPath;
            }
            const devPath = path.resolve(__dirname, '../bin/grammar/');
            if ((0, fs_1.existsSync)(devPath)) {
                return devPath;
            }
            console.warn(`[SyntaxValidationService] Grammar directory not found. Looked for ${prodPath} and ${devPath}. Syntax validation may not function correctly.`);
            return prodPath;
        })();
    }
    async validate(filePath, content) {
        const ext = path.extname(filePath).toLowerCase();
        if (!this.grammarMap[ext]) {
            return null;
        }
        try {
            const parser = await this.getParser(ext);
            if (!parser) {
                this.logger.warn(`Could not load parser for extension "${ext}".`);
                return null;
            }
            const tree = parser.parse(content);
            if (tree.rootNode.hasError) {
                const errors = this.collectSyntaxErrors(tree, content);
                return {
                    filePath,
                    errors,
                };
            }
            return null;
        }
        catch (error) {
            this.logger.error(`Error during syntax validation for ${filePath}: ${error.message}`, error.stack);
            return null;
        }
    }
    async getParser(extension) {
        if (this.parserCache.has(extension)) {
            return this.parserCache.get(extension);
        }
        const grammarFile = this.grammarMap[extension];
        if (!grammarFile) {
            return null;
        }
        try {
            const grammarPath = path.join(this.grammarDir, grammarFile);
            await web_tree_sitter_1.Parser.init();
            const parser = new web_tree_sitter_1.Parser();
            const language = await web_tree_sitter_1.Language.load(grammarPath);
            parser.setLanguage(language);
            this.parserCache.set(extension, parser);
            this.logger.log(`Loaded Tree-sitter parser for "${extension}"`);
            return parser;
        }
        catch (error) {
            this.logger.error(`Failed to load grammar for "${extension}": ${error.message}`, error.stack);
            return null;
        }
    }
    collectSyntaxErrors(tree, content) {
        const errors = [];
        const lines = content.split('\n');
        function findErrorNodes(node) {
            if (node.isError || node.isMissing) {
                const line = node.startPosition.row;
                const col = node.startPosition.column;
                const codeLine = lines[line] || '';
                errors.push({
                    line: line + 1,
                    column: col + 1,
                    message: node.isError
                        ? 'Syntax error detected at this location.'
                        : 'Missing syntax element at this location.',
                    codeSnippet: codeLine.trim(),
                });
            }
            for (let i = 0; i < node.childCount; i++) {
                const child = node.child(i);
                if (child) {
                    findErrorNodes(child);
                }
            }
        }
        findErrorNodes(tree.rootNode);
        return errors;
    }
    formatErrors(validationError) {
        const { filePath, errors } = validationError;
        if (errors.length === 0) {
            return '';
        }
        let message = `Syntax corruption detected in "${filePath}":\n\n`;
        message += `Found ${errors.length} syntax error(s):\n\n`;
        errors.forEach((err, index) => {
            message += `${index + 1}. Line ${err.line}, Column ${err.column}\n`;
            message += `   Code: ${err.codeSnippet}\n`;
            message += `   Issue: ${err.message}\n\n`;
        });
        return message;
    }
    clearCache() {
        this.parserCache.clear();
        this.logger.log('Syntax validation parser cache cleared.');
    }
};
exports.SyntaxValidationService = SyntaxValidationService;
exports.SyntaxValidationService = SyntaxValidationService = SyntaxValidationService_1 = __decorate([
    (0, common_1.Injectable)()
], SyntaxValidationService);
//# sourceMappingURL=syntax-validation.service.js.map