// engine/detectors/library-detector-langs2.ts — Elixir, Scala, Dart library detection
// SPEC-004 tech-debt: Additional backend language library detection
import { readFile } from 'node:fs/promises';
import { join } from 'node:path';
// === Elixir library catalog ===
const ELIXIR_WEB_LIBS = ['phoenix', 'plug', 'bandit'];
const ELIXIR_DB_LIBS = ['ecto', 'ecto_sql', 'postgrex', 'redix'];
const ELIXIR_TESTING_LIBS = ['ex_unit', 'mox', 'bypass'];
const ELIXIR_BACKGROUND_LIBS = ['oban', 'exq'];
// === Scala library catalog ===
const SCALA_HTTP_LIBS = ['akka-http', 'http4s-core', 'tapir-core', 'zio-http'];
const SCALA_FP_LIBS = ['cats-core', 'cats-effect', 'zio', 'monix'];
const SCALA_DB_LIBS = ['slick', 'doobie-core', 'quill-jdbc'];
const SCALA_TESTING_LIBS = ['scalatest', 'specs2-core', 'munit'];
// === Dart library catalog ===
const DART_HTTP_LIBS = ['shelf', 'shelf_router', 'conduit', 'dart_frog'];
const DART_DB_LIBS = ['postgres', 'drift', 'isar'];
const DART_TESTING_LIBS = ['test', 'mockito', 'mocktail'];
// === Detection helpers ===
function filterPresent(catalog, deps) {
    return catalog.filter((lib) => deps.has(lib));
}
// === Elixir dependency collection ===
/**
 * Parse mix.exs deps block.
 * Matches lines like: {:phoenix, "~> 1.7"},
 * Extracts the atom name (first part after `{:`).
 */
export function parseMixExs(content) {
    const deps = new Set();
    const matches = content.matchAll(/\{:([a-z0-9_]+),/g);
    for (const match of matches) {
        /* v8 ignore start */
        if (match[1]) {
            /* v8 ignore stop */
            deps.add(match[1]);
        }
    }
    return deps;
}
async function collectMixExs(projectPath) {
    try {
        const content = await readFile(join(projectPath, 'mix.exs'), 'utf-8');
        return parseMixExs(content);
    }
    catch {
        return new Set();
    }
}
// === Scala dependency collection ===
/**
 * Parse build.sbt for artifact IDs.
 * Matches patterns like:
 *   "com.typesafe.akka" %% "akka-http" % "10.5.0"
 *   "org.typelevel" %% "cats-core" % "2.10.0"
 * Extracts the artifact ID (second string in the % chain).
 */
export function parseBuildSbt(content) {
    const deps = new Set();
    // Match both %% (cross-version) and % (exact version) separators
    const matches = content.matchAll(/"[^"]+"\s*%%?\s*"([^"]+)"\s*%/g);
    for (const match of matches) {
        /* v8 ignore start */
        if (match[1]) {
            /* v8 ignore stop */
            deps.add(match[1]);
        }
    }
    return deps;
}
async function collectBuildSbt(projectPath) {
    try {
        const content = await readFile(join(projectPath, 'build.sbt'), 'utf-8');
        return parseBuildSbt(content);
    }
    catch {
        return new Set();
    }
}
// === Dart dependency collection ===
/**
 * Parse pubspec.yaml dependencies section.
 * Matches lines indented under `dependencies:` like:
 *   shelf: ^1.4.0
 *   conduit: ^4.2.0
 * Stops at the next top-level section (dev_dependencies, flutter, etc.)
 */
export function parsePubspecYaml(content) {
    const deps = new Set();
    // Find the dependencies section and extract package names
    const depsMatch = /^dependencies:\s*\n((?:[ \t]+[^\n]+\n?)*)/m.exec(content);
    if (depsMatch?.[1]) {
        const lines = depsMatch[1].split('\n');
        for (const line of lines) {
            const trimmed = line.trim();
            if (!trimmed || trimmed.startsWith('#')) {
                continue;
            }
            // Match "package_name:" or "package_name: version"
            const pkgMatch = /^([a-z0-9_]+)\s*:/.exec(trimmed);
            if (pkgMatch === null) {
                continue;
            }
            /* v8 ignore start */
            if (pkgMatch[1]) {
                /* v8 ignore stop */
                deps.add(pkgMatch[1]);
            }
        }
    }
    return deps;
}
async function collectPubspecYaml(projectPath) {
    try {
        const content = await readFile(join(projectPath, 'pubspec.yaml'), 'utf-8');
        return parsePubspecYaml(content);
    }
    catch {
        return new Set();
    }
}
// === Public API ===
/**
 * Detect popular Elixir Mix dependencies in a project.
 * Reads mix.exs for {:package_name, ...} patterns.
 */
export async function detectElixirLibraries(projectPath) {
    const deps = await collectMixExs(projectPath);
    return {
        web: filterPresent(ELIXIR_WEB_LIBS, deps),
        db: filterPresent(ELIXIR_DB_LIBS, deps),
        testing: filterPresent(ELIXIR_TESTING_LIBS, deps),
        background: filterPresent(ELIXIR_BACKGROUND_LIBS, deps),
    };
}
/**
 * Detect popular Scala libraries in a project.
 * Reads build.sbt for artifact ID patterns in % chains.
 */
export async function detectScalaLibraries(projectPath) {
    const deps = await collectBuildSbt(projectPath);
    return {
        http: filterPresent(SCALA_HTTP_LIBS, deps),
        fp: filterPresent(SCALA_FP_LIBS, deps),
        db: filterPresent(SCALA_DB_LIBS, deps),
        testing: filterPresent(SCALA_TESTING_LIBS, deps),
    };
}
/**
 * Detect popular Dart backend packages in a project.
 * Reads pubspec.yaml dependencies section.
 */
export async function detectDartLibraries(projectPath) {
    const deps = await collectPubspecYaml(projectPath);
    return {
        http: filterPresent(DART_HTTP_LIBS, deps),
        db: filterPresent(DART_DB_LIBS, deps),
        testing: filterPresent(DART_TESTING_LIBS, deps),
    };
}
//# sourceMappingURL=library-detector-langs2.js.map