"""REDOS-001: ReDoS detection rule."""

from __future__ import annotations

import ast
import re

from . import Rule
from ..models import Finding, Severity

REDOS_PATTERNS = [r'\(.*\+\)\+', r'\(.*\*\)\*', r'\(.*\+\)\*']


class ReDosRule(Rule):
    """Detects regex patterns vulnerable to ReDoS attacks."""

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

    @property
    def name(self) -> str:
        return "ReDoS Vulnerability"

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

    @property
    def description(self) -> str:
        return "Regex with nested quantifiers may be vulnerable to ReDoS."

    def check(self, tree: ast.Module, source: str) -> list[Finding]:
        """Check for regex patterns with nested quantifiers."""
        findings: list[Finding] = []
        re_funcs = ("re.compile", "re.match", "re.search", "re.findall")

        for node in ast.walk(tree):
            if not isinstance(node, ast.Call):
                continue
            func_name = self._get_func_name(node)
            if func_name not in re_funcs:
                continue
            if not node.args or not isinstance(node.args[0], ast.Constant):
                continue

            pattern = str(node.args[0].value)
            for redos in REDOS_PATTERNS:
                if re.search(redos, pattern):
                    findings.append(Finding(
                        rule_id=self.rule_id,
                        severity=self.severity,
                        title="Regex vulnerable a ReDoS",
                        description=f"Cuantificadores anidados: {pattern[:60]}",
                        file="",
                        line=node.lineno,
                        recommendation="Simplificar regex o usar timeout.",
                        cwe="CWE-1333",
                    ))
                    break  # One finding per regex
        return findings
