"""Evidence-based auth-method selection for legacy generated projects."""

from __future__ import annotations

import re
from dataclasses import dataclass
from pathlib import Path


PASSWORD_FIELD = re.compile(
    r"(?:type\s*=\s*['\"]password|password(?:Input|Field|Form)|\bpassword\b)", re.I
)
PASSWORD_SIGNIN = re.compile(
    r"(?:signIn|signin|login|logIn|authenticate|/api/auth/signin|auth/signin)", re.I
)
USERNAME = re.compile(r"\buser(?:name|_name)\b", re.I)
PASSWORD_ARGUMENT = re.compile(
    r"(?:password\s*[,}:)]|[,({:]\s*password\b|password\s*[:=])", re.I
)
SOURCE_SUFFIXES = {".html", ".js", ".mjs", ".cjs", ".ts", ".tsx", ".jsx", ".vue"}
SKIP_DIRS = {".git", "node_modules", "dist", "build", ".nuxt", ".output", ".p2hs"}


@dataclass(frozen=True)
class LegacyAuthIntent:
    method: str
    confidence: str
    evidence: tuple[str, ...]
    repair_class: str


def classify_legacy_auth_intent(
    repo_path: str | Path,
    *,
    cloud_password_credential_count: int = 0,
    managed_paths: set[str] | None = None,
) -> LegacyAuthIntent:
    """Select legacy auth intent without treating dormant adapters as proof."""
    root = Path(repo_path)
    managed = managed_paths or set()
    password_files: list[str] = []
    username_files: list[str] = []
    for directory, dirs, files in __import__("os").walk(root):
        dirs[:] = [name for name in dirs if name not in SKIP_DIRS]
        for name in files:
            path = Path(directory) / name
            if path.suffix.lower() not in SOURCE_SUFFIXES:
                continue
            relative = path.relative_to(root).as_posix()
            if relative in managed or any(relative.startswith(prefix.rstrip("/") + "/") for prefix in managed if prefix.endswith("/")):
                continue
            try:
                source = path.read_text(encoding="utf-8-sig")
            except (OSError, UnicodeDecodeError):
                continue
            if not PASSWORD_FIELD.search(source) or not PASSWORD_SIGNIN.search(source):
                continue
            if USERNAME.search(source) and PASSWORD_ARGUMENT.search(source):
                username_files.append(relative)
            elif PASSWORD_ARGUMENT.search(source):
                password_files.append(relative)

    if username_files:
        return LegacyAuthIntent(
            method="USERNAME_PASSWORD_UNSUPPORTED",
            confidence="strong",
            evidence=tuple(f"username_password_surface:{path}" for path in username_files),
            repair_class="BLOCK_PROJECT_AUTH_INTENT",
        )
    if password_files and cloud_password_credential_count > 0:
        evidence = tuple(
            [f"password_login_surface:{path}" for path in password_files]
            + [f"cloud_password_credentials:{cloud_password_credential_count}"]
        )
        return LegacyAuthIntent(
            method="PASSWORD",
            confidence="strong",
            evidence=evidence,
            repair_class="PRESERVE_PASSWORD_AUTH",
        )
    if password_files:
        return LegacyAuthIntent(
            method="PASSWORD",
            confidence="strong",
            evidence=tuple(f"password_login_surface:{path}" for path in password_files),
            repair_class="PRESERVE_PASSWORD_AUTH",
        )
    return LegacyAuthIntent(
        method="PASSWORDLESS",
        confidence="deterministic_absence_of_strong_password_surface",
        evidence=("no_proven_password_login_surface",),
        repair_class="ADOPT_PASSWORDLESS_MAGIC_LINK",
    )
