// analyzer-linting/linter-checks.ts — Main linting analysis (all linter check definitions)
import { readFile } from 'node:fs/promises';
import { join } from 'node:path';
import { fileExists, hasAnyFile, collectDependencies } from '../detection-utils.js';
import { loadLinterRegistry, detectLinterConflictsFromRegistry } from './registry.js';
async function countRulesInConfig(projectPath, configFile) {
    try {
        const content = await readFile(join(projectPath, configFile), 'utf-8');
        const isJsonLike = configFile.endsWith('.json') ||
            configFile.endsWith('.jsonc') ||
            /\.(eslintrc|prettierrc|stylelintrc|markdownlint)$/.test(configFile) ||
            configFile === '.eslintrc' ||
            configFile === '.prettierrc' ||
            configFile === '.stylelintrc';
        if (isJsonLike) {
            try {
                const parsed = JSON.parse(content);
                const rules = parsed.rules ?? {};
                return Object.keys(rules).length;
            }
            catch {
                return 0;
            }
        }
        if (configFile.endsWith('.yml') || configFile.endsWith('.yaml')) {
            const lines = content.split('\n').filter((l) => /^\s+\w[\w-]+:\s/.test(l));
            return lines.length;
        }
        if (configFile.endsWith('.toml')) {
            const lines = content.split('\n').filter((l) => /^\w[\w-]+\s*=/.test(l));
            return lines.length;
        }
        if (configFile.endsWith('.js') ||
            configFile.endsWith('.mjs') ||
            configFile.endsWith('.cjs') ||
            configFile.endsWith('.ts')) {
            const matches = content.match(/'[\w-]+':\s*(?:'error'|'warn'|'off'|\[)/g);
            return matches?.length ?? 0;
        }
        return 0;
    }
    catch {
        return 0;
    }
}
async function findActualConfigFile(projectPath, configFiles) {
    for (const cfgFile of configFiles) {
        if (await fileExists(projectPath, cfgFile)) {
            return cfgFile;
        }
    }
    for (const cfgFile of configFiles) {
        if (cfgFile.includes('*')) {
            const prefix = cfgFile.replace('*', '');
            const variants = [
                prefix + 'js',
                prefix + 'cjs',
                prefix + 'mjs',
                prefix + 'ts',
                prefix + 'json',
                prefix + 'yml',
                prefix + 'yaml',
            ];
            for (const v of variants) {
                if (await fileExists(projectPath, v)) {
                    return v;
                }
            }
        }
    }
    return null;
}
const LINTER_CHECKS = [
    {
        tool: 'eslint',
        configFiles: [
            '.eslintrc',
            '.eslintrc.js',
            '.eslintrc.json',
            '.eslintrc.yml',
            '.eslintrc.yaml',
            '.eslintrc.cjs',
            'eslint.config.js',
            'eslint.config.mjs',
            'eslint.config.cjs',
            'eslint.config.ts',
        ],
        npmPkg: 'eslint',
    },
    { tool: 'biome', configFiles: ['biome.json', 'biome.jsonc'], npmPkg: '@biomejs/biome' },
    {
        tool: 'prettier',
        configFiles: [
            '.prettierrc',
            '.prettierrc.js',
            '.prettierrc.json',
            '.prettierrc.yml',
            '.prettierrc.yaml',
            '.prettierrc.cjs',
            '.prettierrc.toml',
            'prettier.config.js',
            'prettier.config.mjs',
            'prettier.config.cjs',
        ],
        npmPkg: 'prettier',
    },
    {
        tool: 'stylelint',
        configFiles: [
            '.stylelintrc',
            '.stylelintrc.js',
            '.stylelintrc.json',
            '.stylelintrc.yml',
            '.stylelintrc.yaml',
            '.stylelintrc.cjs',
            'stylelint.config.js',
            'stylelint.config.cjs',
            'stylelint.config.mjs',
        ],
        npmPkg: 'stylelint',
    },
    { tool: 'oxlint', configFiles: ['.oxlintrc.json', 'oxlint.config.js'], npmPkg: 'oxlint' },
    { tool: 'ruff', configFiles: ['ruff.toml', '.ruff.toml', 'pyproject.toml'] },
    { tool: 'pylint', configFiles: ['.pylintrc', 'pyproject.toml', 'setup.cfg'] },
    { tool: 'mypy', configFiles: ['mypy.ini', '.mypy.ini', 'pyproject.toml'] },
    { tool: 'black', configFiles: ['pyproject.toml', 'black.toml'] },
    { tool: 'isort', configFiles: ['.isort.cfg', 'pyproject.toml', 'setup.cfg'] },
    { tool: 'golangci-lint', configFiles: ['.golangci.yml', '.golangci.yaml', '.golangci.toml'] },
    { tool: 'gofmt', configFiles: [] },
    { tool: 'clippy', configFiles: ['clippy.toml', '.clippy.toml'] },
    { tool: 'rustfmt', configFiles: ['rustfmt.toml', '.rustfmt.toml'] },
    {
        tool: 'checkstyle',
        configFiles: ['checkstyle.xml', '.checkstyle.xml', 'config/checkstyle/checkstyle.xml'],
    },
    { tool: 'detekt', configFiles: ['detekt.yml', 'detekt.yaml', 'config/detekt/detekt.yml'] },
    { tool: 'ktlint', configFiles: ['.editorconfig'] },
    { tool: 'phpstan', configFiles: ['phpstan.neon', 'phpstan.neon.dist'] },
    { tool: 'php-cs-fixer', configFiles: ['.php-cs-fixer.php', '.php-cs-fixer.dist.php'] },
    { tool: 'phpcs', configFiles: ['phpcs.xml', '.phpcs.xml'] },
    { tool: 'rubocop', configFiles: ['.rubocop.yml'] },
    { tool: 'swiftlint', configFiles: ['.swiftlint.yml', '.swiftlint.yaml'] },
    { tool: 'swiftformat', configFiles: ['.swiftformat'] },
    { tool: 'periphery', configFiles: ['.periphery.yml'] },
    { tool: 'android-lint', configFiles: ['lint.xml'] },
    {
        tool: 'commitlint',
        configFiles: [
            'commitlint.config.js',
            '.commitlintrc',
            '.commitlintrc.js',
            '.commitlintrc.json',
            'commitlint.config.cjs',
            'commitlint.config.mjs',
        ],
        npmPkg: '@commitlint/cli',
    },
    {
        tool: 'markdownlint',
        configFiles: [
            '.markdownlint.json',
            '.markdownlint.yml',
            '.markdownlintrc',
            '.markdownlint.yaml',
        ],
        npmPkg: 'markdownlint-cli2',
    },
    { tool: 'hadolint', configFiles: ['.hadolint.yaml', '.hadolint.yml'] },
    { tool: 'actionlint', configFiles: [] },
    { tool: 'shellcheck', configFiles: [] },
    { tool: 'sqlfluff', configFiles: ['.sqlfluff', 'pyproject.toml'] },
];
export async function analyzeLintingEnhanced(projectPath) {
    const registry = await loadLinterRegistry();
    const deps = await collectDependencies(projectPath);
    const detectedLinters = [];
    for (const check of LINTER_CHECKS) {
        const foundConfig = await findActualConfigFile(projectPath, check.configFiles);
        const hasDep = check.npmPkg ? deps.has(check.npmPkg) : false;
        const hasGlobal = check.tool === 'golangci-lint'
            ? await hasAnyFile(projectPath, ['.golangci.yml', '.golangci.yaml'])
            : check.tool === 'clippy'
                ? await fileExists(projectPath, 'Cargo.toml')
                : false;
        if (foundConfig ?? hasGlobal) {
            const rulesCount = foundConfig ? await countRulesInConfig(projectPath, foundConfig) : 0;
            detectedLinters.push({
                tool: check.tool,
                status: 'configured',
                isDefault: rulesCount === 0,
                configFile: foundConfig ?? undefined,
                rulesCount,
            });
        }
        else if (hasDep) {
            detectedLinters.push({
                tool: check.tool,
                status: 'installed-not-configured',
                isDefault: false,
            });
        }
    }
    const maturityScore = Math.min(100, detectedLinters.filter((l) => l.status === 'configured').length * 20);
    return {
        projectId: '',
        language: 'unknown',
        detectedLinters,
        missingRecommended: [],
        rulesConflicts: detectLinterConflictsFromRegistry(detectedLinters, registry),
        customRulesFromProject: [],
        maturityScore,
    };
}
//# sourceMappingURL=linter-checks.js.map