import * as fs from "fs";
import * as path from "path";
export function detectProjectMetadata(repositoryPath) {
    const langSet = new Set();
    const fwSet = new Set();
    const meta = {
        projectType: "other", primaryLanguage: "unknown", primaryFramework: "unknown",
        deploymentPattern: "unknown", languages: [], frameworks: [], runtime: "unknown",
        isContainerized: false, hasDockerCompose: false, hasCiCd: false,
    };
    const exists = (rel) => fs.existsSync(path.join(repositoryPath, rel));
    const readJson = (rel) => {
        try {
            return JSON.parse(fs.readFileSync(path.join(repositoryPath, rel), "utf-8"));
        }
        catch {
            return null;
        }
    };
    const readText = (rel) => {
        try {
            return fs.readFileSync(path.join(repositoryPath, rel), "utf-8");
        }
        catch {
            return "";
        }
    };
    meta.isContainerized = exists("Dockerfile") || exists("backend/Dockerfile") || exists("frontend/Dockerfile");
    meta.hasDockerCompose = exists("docker-compose.yml") || exists("docker-compose.yaml");
    meta.hasCiCd = exists(".github/workflows") || exists(".gitlab-ci.yml") || exists("Jenkinsfile");
    if (meta.isContainerized)
        meta.deploymentPattern = "containerized-monolith";
    const pkg = readJson("package.json");
    if (pkg) {
        langSet.add("TypeScript/JavaScript");
        meta.runtime = "Node.js";
        const allDeps = { ...(pkg.dependencies || {}), ...(pkg.devDependencies || {}) };
        if (allDeps["next"]) {
            fwSet.add("Next.js");
            meta.primaryFramework = "Next.js";
        }
        if (allDeps["express"]) {
            fwSet.add("Express");
            if (meta.primaryFramework === "unknown")
                meta.primaryFramework = "Express";
        }
        if (allDeps["react"])
            fwSet.add("React");
        if (allDeps["vue"])
            fwSet.add("Vue");
        if (allDeps["@nestjs/core"]) {
            fwSet.add("NestJS");
            meta.primaryFramework = "NestJS";
        }
        meta.primaryLanguage = allDeps["typescript"] ? "TypeScript" : "JavaScript";
    }
    const reqs = readText("requirements.txt") + readText("backend/requirements.txt");
    const pyproject = readText("pyproject.toml");
    if (reqs || exists("setup.py") || pyproject) {
        langSet.add("Python");
        if (!meta.runtime || meta.runtime === "unknown")
            meta.runtime = "Python";
        if (/fastapi/i.test(reqs + pyproject)) {
            fwSet.add("FastAPI");
            meta.primaryFramework = "FastAPI";
            meta.primaryLanguage = "Python";
        }
        if (/django/i.test(reqs + pyproject)) {
            fwSet.add("Django");
            if (meta.primaryFramework === "unknown") {
                meta.primaryFramework = "Django";
                meta.primaryLanguage = "Python";
            }
        }
        if (/flask/i.test(reqs + pyproject)) {
            fwSet.add("Flask");
            if (meta.primaryFramework === "unknown") {
                meta.primaryFramework = "Flask";
                meta.primaryLanguage = "Python";
            }
        }
    }
    // Java: check repo root and one directory level deep for Maven/Gradle build files.
    const JAVA_BUILD_FILES = ["pom.xml", "build.gradle", "build.gradle.kts"];
    const javaFound = JAVA_BUILD_FILES.some(f => exists(f)) || (() => {
        try {
            return fs.readdirSync(repositoryPath, { withFileTypes: true })
                .filter(e => e.isDirectory() && !e.name.startsWith(".") && e.name !== "node_modules" && e.name !== "target")
                .some(dir => JAVA_BUILD_FILES.some(f => fs.existsSync(path.join(repositoryPath, dir.name, f))));
        }
        catch {
            return false;
        }
    })();
    if (javaFound) {
        langSet.add("Java");
        if (meta.primaryLanguage === "unknown")
            meta.primaryLanguage = "Java";
        fwSet.add("Spring");
        if (meta.primaryFramework === "unknown")
            meta.primaryFramework = "Spring";
        meta.runtime = "JVM";
    }
    // Go
    if (exists("go.mod")) {
        langSet.add("Go");
        if (meta.primaryLanguage === "unknown")
            meta.primaryLanguage = "Go";
        meta.runtime = "Go";
        const gomod = readText("go.mod");
        if (/gin-gonic/i.test(gomod)) {
            fwSet.add("Gin");
            if (meta.primaryFramework === "unknown")
                meta.primaryFramework = "Gin";
        }
        else if (/labstack\/echo/i.test(gomod)) {
            fwSet.add("Echo");
            if (meta.primaryFramework === "unknown")
                meta.primaryFramework = "Echo";
        }
        else if (/go-chi/i.test(gomod)) {
            fwSet.add("Chi");
            if (meta.primaryFramework === "unknown")
                meta.primaryFramework = "Chi";
        }
    }
    // Ruby
    if (exists("Gemfile")) {
        langSet.add("Ruby");
        if (meta.primaryLanguage === "unknown")
            meta.primaryLanguage = "Ruby";
        meta.runtime = "Ruby";
        const gemfile = readText("Gemfile");
        if (/rails/i.test(gemfile)) {
            fwSet.add("Rails");
            meta.primaryFramework = "Rails";
        }
        else if (/sinatra/i.test(gemfile)) {
            fwSet.add("Sinatra");
            if (meta.primaryFramework === "unknown")
                meta.primaryFramework = "Sinatra";
        }
    }
    // PHP
    const composerJson = readJson("composer.json");
    if (composerJson) {
        langSet.add("PHP");
        if (meta.primaryLanguage === "unknown")
            meta.primaryLanguage = "PHP";
        meta.runtime = "PHP";
        const allPhpDeps = { ...(composerJson.require || {}), ...(composerJson["require-dev"] || {}) };
        if (allPhpDeps["laravel/framework"]) {
            fwSet.add("Laravel");
            meta.primaryFramework = "Laravel";
        }
        else if (allPhpDeps["symfony/framework-bundle"]) {
            fwSet.add("Symfony");
            if (meta.primaryFramework === "unknown")
                meta.primaryFramework = "Symfony";
        }
    }
    // Rust
    if (exists("Cargo.toml")) {
        langSet.add("Rust");
        if (meta.primaryLanguage === "unknown")
            meta.primaryLanguage = "Rust";
        meta.runtime = "Rust";
        const cargo = readText("Cargo.toml");
        if (/actix-web/i.test(cargo)) {
            fwSet.add("Actix");
            if (meta.primaryFramework === "unknown")
                meta.primaryFramework = "Actix";
        }
        else if (/axum/i.test(cargo)) {
            fwSet.add("Axum");
            if (meta.primaryFramework === "unknown")
                meta.primaryFramework = "Axum";
        }
        else if (/rocket/i.test(cargo)) {
            fwSet.add("Rocket");
            if (meta.primaryFramework === "unknown")
                meta.primaryFramework = "Rocket";
        }
    }
    meta.languages = Array.from(langSet);
    meta.frameworks = Array.from(fwSet);
    const hasBackend = meta.frameworks.some(f => /express|fastapi|django|flask|nestjs|spring|gin|echo|chi|rails|sinatra|laravel|symfony|actix|axum|rocket/i.test(f));
    const hasFrontend = meta.frameworks.some(f => /react|vue|next/i.test(f));
    if (hasBackend && hasFrontend)
        meta.projectType = "full-stack";
    else if (hasBackend)
        meta.projectType = "rest-api";
    else if (hasFrontend)
        meta.projectType = "frontend";
    if (exists("backend") && exists("frontend") && meta.projectType !== "full-stack") {
        meta.projectType = "full-stack";
        meta.deploymentPattern = "full-stack";
    }
    return meta;
}
