"""GO-AUTH-001: Missing Auth Middleware detection for Go.

Detects HTTP handlers registered without authentication middleware,
which is a common vulnerability in Go MCP servers.
"""

from __future__ import annotations

import re

from . import GoRule
from ..models import Finding, Severity

# HTTP handler registration patterns
HTTP_HANDLE_PATTERN = re.compile(
    r'(?:http\.HandleFunc|mux\.HandleFunc|router\.HandleFunc|'
    r'http\.Handle|mux\.Handle|router\.Handle|'
    r'r\.(?:Get|Post|Put|Delete|Patch|HandleFunc)|'
    r'e\.(?:GET|POST|PUT|DELETE|PATCH)|'
    r'app\.(?:Get|Post|Put|Delete|Patch))\s*\('
)

# Auth middleware patterns (presence = good)
AUTH_MIDDLEWARE_PATTERNS = [
    re.compile(r'\bauth\w*[Mm]iddleware', re.IGNORECASE),
    re.compile(r'\b(?:Auth|JWT|Token|Session|Bearer)(?:Handler|Check|Verify|Validate|Guard)\b'),
    re.compile(r'\.Use\s*\(\s*(?:auth|jwt|token|session)', re.IGNORECASE),
    re.compile(r'r\.With\s*\(\s*(?:auth|jwt)', re.IGNORECASE),
    re.compile(r'middleware\.(?:Auth|JWT|Bearer|Token)', re.IGNORECASE),
]

# Public endpoint patterns (OK without auth)
PUBLIC_PATH_PATTERN = re.compile(
    r'["`]/(?:health|ping|ready|readyz|livez|healthz|metrics|favicon\.ico|public|static|version)["`]'
)


class GoMissingAuthRule(GoRule):
    """Detects HTTP handlers without authentication middleware."""

    @property
    def rule_id(self) -> str:
        return "GO-AUTH-001"

    @property
    def name(self) -> str:
        return "Missing Auth Middleware"

    @property
    def severity(self) -> Severity:
        return Severity.HIGH

    @property
    def cwe(self) -> str:
        return "CWE-306"

    @property
    def description(self) -> str:
        return (
            "HTTP handler registered without authentication middleware. "
            "Endpoints may be accessible without authorization."
        )

    @property
    def detailed_description(self) -> str:
        return (
            "HTTP handler registered without authentication middleware.\n\n"
            "Go HTTP servers often register handlers directly without\n"
            "wrapping them in auth middleware. This means any client can\n"
            "access the endpoint without authentication.\n\n"
            "Examples of vulnerable code:\n"
            '  http.HandleFunc("/api/delete-user", deleteUserHandler)\n'
            '  router.Get("/admin/config", configHandler)\n\n'
            "How to fix:\n"
            "  - Wrap handlers with auth middleware\n"
            "  - Use router groups with middleware (chi, gin, echo)\n"
            "  - Implement JWT/session validation middleware"
        )

    def check(self, source: str, filename: str = "") -> list[Finding]:
        """Check for handlers without auth middleware."""
        findings: list[Finding] = []

        # Check if the file has any auth middleware setup
        has_auth_middleware = any(
            p.search(source) for p in AUTH_MIDDLEWARE_PATTERNS
        )

        # If auth middleware is present globally, don't flag
        if has_auth_middleware:
            return findings

        # Find handler registrations
        for lineno, line, _match in self._search_lines(source, HTTP_HANDLE_PATTERN):
            # Skip health/public endpoints
            if PUBLIC_PATH_PATTERN.search(line):
                continue
            findings.append(Finding(
                rule_id=self.rule_id,
                severity=self.severity,
                title="Missing Auth Middleware",
                description=(
                    "HTTP handler registered without authentication "
                    "middleware."
                ),
                file="",
                line=lineno,
                code_snippet=line.strip()[:80],
                recommendation=(
                    "Add authentication middleware to protect this endpoint. "
                    "Use router.Use(authMiddleware) or wrap the handler."
                ),
                cwe=self.cwe,
            ))

        return findings
