// engine/detectors/library-detector-multilang-c.ts — Ruby + .NET library detection
// SPEC-004 tech-debt: Ruby and .NET library detection
import { readFile } from 'node:fs/promises';
import { join } from 'node:path';
import { glob } from 'glob';
// === Ruby gem catalog ===
const RUBY_BACKGROUND_GEMS = ['sidekiq', 'resque', 'delayed_job'];
const RUBY_AUTH_GEMS = ['devise', 'pundit', 'cancancan'];
const RUBY_TYPES_GEMS = ['sorbet', 'tapioca'];
const RUBY_QA_GEMS = ['rubocop', 'rubocop-rails'];
// === .NET package catalog ===
const DOTNET_CQRS_PKGS = ['MediatR', 'Wolverine'];
const DOTNET_MAPPING_PKGS = ['AutoMapper', 'Mapster'];
const DOTNET_VALIDATION_PKGS = ['FluentValidation'];
const DOTNET_DB_PKGS = ['Dapper', 'Microsoft.EntityFrameworkCore', 'Npgsql'];
const DOTNET_RESILIENCE_PKGS = ['Polly', 'Refit'];
// === Detection helpers ===
function filterPresent(catalog, deps) {
    return catalog.filter((lib) => deps.has(lib));
}
// === Ruby dependency collection ===
function parseGemfile(content) {
    const deps = new Set();
    const matches = content.matchAll(/^\s*gem\s+['"]([a-zA-Z0-9_-]+)['"]/gm);
    for (const match of matches) {
        /* v8 ignore start */
        if (match[1]) {
            /* v8 ignore stop */
            deps.add(match[1]);
        }
    }
    return deps;
}
async function collectGemfile(projectPath) {
    try {
        const content = await readFile(join(projectPath, 'Gemfile'), 'utf-8');
        return parseGemfile(content);
    }
    catch {
        return new Set();
    }
}
// === .NET dependency collection ===
function parseCsprojOrPackagesConfig(content, isCsproj) {
    const deps = new Set();
    if (isCsproj) {
        // <PackageReference Include="SomePkg" Version="..." />
        const matches = content.matchAll(/<PackageReference[^>]+Include="([^"]+)"/g);
        for (const match of matches) {
            /* v8 ignore start */
            if (match[1]) {
                /* v8 ignore stop */
                deps.add(match[1].trim());
            }
        }
    }
    else {
        // packages.config: <package id="SomePkg" version="..." />
        const matches = content.matchAll(/<package[^>]+id="([^"]+)"/g);
        for (const match of matches) {
            /* v8 ignore start */
            if (match[1]) {
                /* v8 ignore stop */
                deps.add(match[1].trim());
            }
        }
    }
    return deps;
}
async function collectDotNetDeps(projectPath) {
    try {
        const csprojFiles = await glob('**/*.csproj', { cwd: projectPath, absolute: true });
        const allDeps = new Set();
        await Promise.all(csprojFiles.map(async (filePath) => {
            try {
                const content = await readFile(filePath, 'utf-8');
                for (const dep of parseCsprojOrPackagesConfig(content, true)) {
                    allDeps.add(dep);
                }
            }
            catch {
                /* v8 ignore next -- unreachable: glob only returns readable files */
            }
        }));
        if (allDeps.size === 0) {
            try {
                const pkgConfig = await readFile(join(projectPath, 'packages.config'), 'utf-8');
                for (const dep of parseCsprojOrPackagesConfig(pkgConfig, false)) {
                    allDeps.add(dep);
                }
            }
            catch {
                // No packages.config either — empty result
            }
        }
        return allDeps;
        /* v8 ignore start */
    }
    catch {
        return new Set();
    }
    /* v8 ignore stop */
}
// === Public API ===
/**
 * Detect popular Ruby gems in a project.
 * Reads Gemfile for gem declarations.
 */
export async function detectRubyGems(projectPath) {
    const deps = await collectGemfile(projectPath);
    return {
        background: filterPresent(RUBY_BACKGROUND_GEMS, deps),
        auth: filterPresent(RUBY_AUTH_GEMS, deps),
        types: filterPresent(RUBY_TYPES_GEMS, deps),
        qa: filterPresent(RUBY_QA_GEMS, deps),
    };
}
/**
 * Detect popular .NET NuGet packages in a project.
 * Reads *.csproj files or packages.config.
 */
export async function detectDotNetPackages(projectPath) {
    const deps = await collectDotNetDeps(projectPath);
    return {
        cqrs: filterPresent(DOTNET_CQRS_PKGS, deps),
        mapping: filterPresent(DOTNET_MAPPING_PKGS, deps),
        validation: filterPresent(DOTNET_VALIDATION_PKGS, deps),
        db: filterPresent(DOTNET_DB_PKGS, deps),
        resilience: filterPresent(DOTNET_RESILIENCE_PKGS, deps),
    };
}
//# sourceMappingURL=library-detector-multilang-c.js.map