"""TS-SSRF-001: Server-Side Request Forgery for TypeScript/JavaScript.

Detects fetch/axios/http calls with user-controlled URLs.
"""

from __future__ import annotations

import re

from . import TSRule
from ..models import Finding, Severity

# HTTP request functions with potential SSRF
FETCH_PATTERN = re.compile(
    r'\b(?:fetch|axios\.(?:get|post|put|delete|patch|head|request)|'
    r'axios\s*\(|'
    r'got\s*\(|got\.(?:get|post|put|delete)|'
    r'superagent\.(?:get|post|put|delete)|'
    r'node-fetch|'
    r'http\.(?:get|request)|https\.(?:get|request)|'
    r'urllib\.request)\s*\('
)

# Dynamic URL indicators
DYNAMIC_URL_TEMPLATE = re.compile(
    r'(?:fetch|axios|got|http|https)\s*[\.(]\s*`[^`]*\$\{'
)
DYNAMIC_URL_CONCAT = re.compile(
    r'(?:fetch|axios|got|http|https)\s*[\.(]\s*\w+\s*\+'
    r'|(?:fetch|axios|got|http|https)\s*[\.(]\s*[^\'"][a-zA-Z]'
)
DYNAMIC_URL_VAR = re.compile(
    r'(?:fetch|axios|got|http|https)\s*[\.(]\s*'
    r'(?:url|endpoint|href|uri|target|dest|link|addr|host|'
    r'req\.|args\.|params\.|input\.|body\.|config\.)'
)


class TSSSRFRule(TSRule):
    """Detects SSRF patterns in TypeScript/JavaScript."""

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

    @property
    def name(self) -> str:
        return "Server-Side Request Forgery"

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

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

    @property
    def description(self) -> str:
        return (
            "HTTP request with user-controlled URL may allow "
            "SSRF attacks."
        )

    @property
    def detailed_description(self) -> str:
        return (
            "HTTP request with user-controlled URL may allow SSRF.\n\n"
            "Examples of vulnerable code:\n"
            "  const resp = await fetch(userUrl);\n"
            "  await axios.get(`http://${host}/api`);\n\n"
            "How to fix:\n"
            "  - Validate URLs against an allowlist\n"
            "  - Block private/internal IP ranges\n"
            "  - Use a URL validation library"
        )

    def check(self, source: str) -> list[Finding]:
        """Check for SSRF patterns."""
        findings: list[Finding] = []
        lines = self._get_lines(source)

        for i, line in enumerate(lines, 1):
            if self._is_comment_line(line):
                continue

            if not FETCH_PATTERN.search(line):
                continue

            # Template literal URL
            if DYNAMIC_URL_TEMPLATE.search(line):
                findings.append(self._make_finding(
                    i, line, "HTTP request with template literal URL."
                ))
                continue

            # Variable URL
            if DYNAMIC_URL_VAR.search(line):
                findings.append(self._make_finding(
                    i, line, "HTTP request with dynamic URL variable."
                ))
                continue

            # Concatenated URL
            if DYNAMIC_URL_CONCAT.search(line):
                findings.append(self._make_finding(
                    i, line, "HTTP request with concatenated URL."
                ))

        return findings

    def _make_finding(
        self, lineno: int, line: str, desc: str
    ) -> Finding:
        """Create an SSRF finding."""
        return Finding(
            rule_id=self.rule_id,
            severity=self.severity,
            title="Potential SSRF",
            description=desc,
            file="",
            line=lineno,
            code_snippet=line.strip()[:80],
            recommendation=(
                "Validate URLs against an allowlist of "
                "permitted hosts/schemes."
            ),
            cwe=self.cwe,
        )
