"""TS-PERM-001: Excessive Permissions for TypeScript/JavaScript.

Detects wildcard permissions, overly broad access patterns,
and dangerous file permissions in MCP servers.
"""

from __future__ import annotations

import re

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

# Wildcard permission patterns
WILDCARD_PERMS = re.compile(
    r'''['"](?:\*:\*|\*\.\*|admin:\*|\*:admin|'''
    r'''[\w-]+:\*|scope:\s*\*|'''
    r'''permissions?\s*:\s*\[?\s*['"]?\*['"]?\]?)['"]'''
)

# Dangerous file permissions (777, 666)
CHMOD_DANGEROUS = re.compile(
    r'(?:chmod|chmodSync|fs\.chmod)\s*\([^)]*'
    r'(?:0o?777|0o?666|0x1ff|511)'
)

# Overly broad CORS — matches both header assignment and object key styles
CORS_WILDCARD = re.compile(
    r'''Access-Control-Allow-Origin['"]?\s*[:=]\s*['"]?\*['"]?'''
)

# Run as root / privileged patterns
PRIVILEGED_PATTERN = re.compile(
    r'(?:process\.setuid\s*\(\s*0|'
    r'--privileged|'
    r'allowAllHosts|'
    r'dangerouslyAllowBrowser\s*:\s*true)',
    re.IGNORECASE
)

# Broad env access
ENV_SPREAD = re.compile(
    r'(?:\.\.\.process\.env|Object\.keys\s*\(\s*process\.env\)|'
    r'JSON\.stringify\s*\(\s*process\.env\s*\))'
)


class TSExcessivePermissionsRule(TSRule):
    """Detects excessive permissions in TypeScript/JavaScript."""

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

    @property
    def name(self) -> str:
        return "Excessive Permissions"

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

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

    @property
    def description(self) -> str:
        return (
            "Wildcard permissions, overly broad access, or dangerous "
            "file permissions."
        )

    @property
    def detailed_description(self) -> str:
        return (
            "Wildcard permissions, overly broad access, or dangerous "
            "file permissions.\n\n"
            "Examples of vulnerable code:\n"
            "  permissions: ['*:*']\n"
            "  fs.chmodSync(file, 0o777)\n"
            "  Access-Control-Allow-Origin: *\n\n"
            "How to fix:\n"
            "  - Use least-privilege permissions\n"
            "  - Specify exact permission scopes\n"
            "  - Use restrictive file permissions (0o644, 0o755)\n"
            "  - Restrict CORS to specific origins"
        )

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

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

            # Wildcard permissions
            if WILDCARD_PERMS.search(line):
                findings.append(Finding(
                    rule_id=self.rule_id,
                    severity=self.severity,
                    title="Wildcard Permissions",
                    description="Wildcard permission grants overly broad access.",
                    file="",
                    line=i,
                    code_snippet=line.strip()[:80],
                    recommendation="Specify exact permission scopes.",
                    cwe=self.cwe,
                ))
                continue

            # Dangerous chmod
            if CHMOD_DANGEROUS.search(line):
                findings.append(Finding(
                    rule_id=self.rule_id,
                    severity=self.severity,
                    title="Dangerous File Permissions",
                    description=(
                        "chmod 777/666 grants excessive file permissions."
                    ),
                    file="",
                    line=i,
                    code_snippet=line.strip()[:80],
                    recommendation=(
                        "Use restrictive permissions (0o644 for files, "
                        "0o755 for directories)."
                    ),
                    cwe="CWE-732",
                ))
                continue

            # Wildcard CORS
            if CORS_WILDCARD.search(line):
                findings.append(Finding(
                    rule_id=self.rule_id,
                    severity=Severity.MEDIUM,
                    title="Wildcard CORS Origin",
                    description=(
                        "CORS allows all origins (*). Should restrict "
                        "to specific domains."
                    ),
                    file="",
                    line=i,
                    code_snippet=line.strip()[:80],
                    recommendation="Restrict CORS to specific origins.",
                    cwe="CWE-942",
                ))
                continue

            # Environment spread
            if ENV_SPREAD.search(line):
                findings.append(Finding(
                    rule_id=self.rule_id,
                    severity=Severity.MEDIUM,
                    title="Full Environment Exposure",
                    description=(
                        "Entire process.env exposed, may leak secrets."
                    ),
                    file="",
                    line=i,
                    code_snippet=line.strip()[:80],
                    recommendation=(
                        "Access specific env vars instead of "
                        "spreading the entire environment."
                    ),
                    cwe="CWE-200",
                ))

        return findings
