# retoor <retoor@molodetz.nl>
from __future__ import annotations

import re

from devplacepy.services.jobs.isslop.analysis.signals import (
    AXIS_ORIGIN,
    SEVERITY_MEDIUM,
    SEVERITY_STRONG,
    SEVERITY_WEAK,
    FileContext,
    Signal,
)

PATH_FRAMEWORK_PATTERNS: tuple[tuple[re.Pattern[str], str, str], ...] = (
    (re.compile(r"(^|/)_next/", re.IGNORECASE), "Next.js build output (_next/)", SEVERITY_WEAK),
    (re.compile(r"(^|/)_nuxt/", re.IGNORECASE), "Nuxt build output (_nuxt/)", SEVERITY_WEAK),
    (re.compile(r"(^|/)_astro/", re.IGNORECASE), "Astro build output (_astro/)", SEVERITY_WEAK),
    (re.compile(r"(^|/)\.svelte-kit/", re.IGNORECASE), "SvelteKit build output", SEVERITY_WEAK),
    (re.compile(r"(^|/)webpack-[0-9a-f]{8,}\.js$", re.IGNORECASE), "Webpack runtime chunk", SEVERITY_WEAK),
    (re.compile(r"(^|/)polyfills-[0-9a-f]{6,}\.js$", re.IGNORECASE), "Bundler polyfills chunk", SEVERITY_WEAK),
    (re.compile(r"(^|/)main-app-[0-9a-f]{6,}\.js$", re.IGNORECASE), "Next.js app-router bundle", SEVERITY_MEDIUM),
    (re.compile(r"(^|/)chunks/app/(page|layout|loading|error|not-found)-[0-9a-f]{6,}\.js$", re.IGNORECASE), "Next.js app-router page bundle", SEVERITY_MEDIUM),
    (re.compile(r"(^|/)framework-[0-9a-f]{8,}\.js$", re.IGNORECASE), "Next.js framework chunk", SEVERITY_WEAK),
    (re.compile(r"(^|/)assets/index-[0-9A-Za-z_-]{8,}\.(js|css)$"), "Vite hashed asset bundle", SEVERITY_WEAK),
    (re.compile(r"(^|/)gptengineer\.js$|(^|/)cdn\.gpteng\.co", re.IGNORECASE), "GPT Engineer / Lovable runtime", SEVERITY_STRONG),
    (re.compile(r"(^|/)lovable-uploads/", re.IGNORECASE), "Lovable uploads directory", SEVERITY_STRONG),
    (re.compile(r"(^|/)gatsby-", re.IGNORECASE), "Gatsby build artifact", SEVERITY_WEAK),
)

VITE_HASH_ASSET = re.compile(r"index-[0-9A-Za-z_-]{8,}\.(js|css)$")

CONTENT_FRAMEWORK_PATTERNS: tuple[tuple[re.Pattern[str], str], ...] = (
    (re.compile(r"self\.__next_f|__NEXT_DATA__|next/dist/", re.IGNORECASE), "next.js runtime"),
    (re.compile(r"__nuxt|nuxt\.config", re.IGNORECASE), "nuxt runtime"),
    (re.compile(r"astro-island|astro:", re.IGNORECASE), "astro runtime"),
    (re.compile(r"data-radix|@radix-ui|radix-ui", re.IGNORECASE), "radix primitives"),
    (re.compile(r"lucide", re.IGNORECASE), "lucide icons"),
    (re.compile(r"shadcn|class-variance-authority|\bcn\(", re.IGNORECASE), "shadcn/ui"),
    (re.compile(r"tailwind|--tw-", re.IGNORECASE), "tailwind"),
    (re.compile(r"framer-motion", re.IGNORECASE), "framer motion"),
    (re.compile(r"createClient\([^)]*supabase|supabase\.co", re.IGNORECASE), "supabase backend"),
    (re.compile(r"clerk\.|@clerk/", re.IGNORECASE), "clerk auth"),
)

CONTENT_STRONG_MARKERS: tuple[tuple[re.Pattern[str], str], ...] = (
    (re.compile(r"gpteng|lovable|data-lov-id", re.IGNORECASE), "Lovable/GPT-Engineer marker"),
    (re.compile(r"generated by (v0|bolt|base44|lovable)", re.IGNORECASE), "AI builder attribution"),
)

VIBE_COMBO_THRESHOLD: int = 3


def detect_infrastructure(context: FileContext) -> list[Signal]:
    findings: list[Signal] = []
    relative = context.relative

    for pattern, title, severity in PATH_FRAMEWORK_PATTERNS:
        if pattern.search(relative):
            weight = 3.0 if severity == SEVERITY_STRONG else (1.0 if severity == SEVERITY_MEDIUM else 0.5)
            findings.append(
                Signal("BUILD_ARTIFACT_PATH", f"Framework build artifact path: {title}", severity, AXIS_ORIGIN, weight, 1, relative)
            )
            break

    text = context.text
    for pattern, marker in CONTENT_STRONG_MARKERS:
        match = pattern.search(text)
        if match:
            findings.append(
                Signal(
                    "AI_BUILDER_FINGERPRINT",
                    f"AI builder marker in bundle: {marker}",
                    SEVERITY_STRONG,
                    AXIS_ORIGIN,
                    4.0,
                    text.count("\n", 0, match.start()) + 1,
                    match.group(0)[:100],
                )
            )
            break

    stack_hits = [label for pattern, label in CONTENT_FRAMEWORK_PATTERNS if pattern.search(text)]
    if len(stack_hits) >= VIBE_COMBO_THRESHOLD:
        findings.append(
            Signal(
                "VIBE_STACK",
                f"Default AI frontend stack in bundle ({len(stack_hits)} libraries)",
                SEVERITY_STRONG if len(stack_hits) >= 5 else SEVERITY_MEDIUM,
                AXIS_ORIGIN,
                3.0,
                1,
                ", ".join(stack_hits[:8]),
            )
        )
    return findings
