"""
BREACH.AI - CORS Misconfiguration Exploiter
============================================
Detects and exploits Cross-Origin Resource Sharing misconfigurations.
"""

import asyncio
from typing import List, Optional
from dataclasses import dataclass
from .base import BaseAttack, Finding, Severity


@dataclass
class CORSFinding:
    """CORS vulnerability finding."""
    endpoint: str
    origin_tested: str
    acao_header: str
    acac_header: Optional[str]
    vulnerability_type: str
    severity: Severity


class CORSExploiter(BaseAttack):
    """
    CORS Misconfiguration Exploiter

    Tests for:
    - Wildcard origins (*)
    - Null origin acceptance
    - Arbitrary origin reflection
    - Subdomain wildcard matching
    - Credentials with wildcard
    - Pre-flight bypass
    """

    name = "CORS Exploiter"

    MALICIOUS_ORIGINS = [
        "https://evil.com",
        "https://attacker.com",
        "null",
        "https://localhost",
        "https://127.0.0.1",
    ]

    async def run(self) -> List[Finding]:
        findings = []

        # Test main target
        cors_findings = await self._test_cors(self.target)
        findings.extend(cors_findings)

        # Test discovered API endpoints
        for endpoint in self.state.discovered_endpoints[:20]:
            endpoint_findings = await self._test_cors(endpoint)
            findings.extend(endpoint_findings)

        return findings

    async def _test_cors(self, url: str) -> List[Finding]:
        """Test CORS configuration for a URL."""
        findings = []

        for origin in self.MALICIOUS_ORIGINS:
            try:
                headers = {"Origin": origin}
                response = await self.client.get(url, headers=headers)

                acao = response.headers.get("Access-Control-Allow-Origin", "")
                acac = response.headers.get("Access-Control-Allow-Credentials", "")

                # Check for vulnerabilities
                if acao == "*":
                    findings.append(self._create_finding(
                        url, origin, acao, acac,
                        "Wildcard Origin (*)",
                        Severity.HIGH if acac.lower() == "true" else Severity.MEDIUM
                    ))
                elif acao == origin:
                    if origin == "null":
                        findings.append(self._create_finding(
                            url, origin, acao, acac,
                            "Null Origin Accepted",
                            Severity.HIGH
                        ))
                    elif "evil" in origin or "attacker" in origin:
                        findings.append(self._create_finding(
                            url, origin, acao, acac,
                            "Arbitrary Origin Reflection",
                            Severity.CRITICAL if acac.lower() == "true" else Severity.HIGH
                        ))

            except Exception:
                continue

        # Test subdomain matching
        await self._test_subdomain_cors(url, findings)

        return findings

    async def _test_subdomain_cors(self, url: str, findings: List[Finding]) -> None:
        """Test for subdomain-based CORS bypass."""
        from urllib.parse import urlparse
        parsed = urlparse(self.target)
        domain = parsed.netloc

        subdomain_origins = [
            f"https://evil.{domain}",
            f"https://{domain}.evil.com",
            f"https://sub.{domain}",
        ]

        for origin in subdomain_origins:
            try:
                response = await self.client.get(url, headers={"Origin": origin})
                acao = response.headers.get("Access-Control-Allow-Origin", "")
                acac = response.headers.get("Access-Control-Allow-Credentials", "")

                if acao == origin:
                    findings.append(self._create_finding(
                        url, origin, acao, acac,
                        "Subdomain Origin Bypass",
                        Severity.HIGH
                    ))
            except Exception:
                continue

    def _create_finding(
        self,
        endpoint: str,
        origin: str,
        acao: str,
        acac: str,
        vuln_type: str,
        severity: Severity
    ) -> Finding:
        """Create a CORS finding."""
        return Finding(
            title=f"CORS Misconfiguration: {vuln_type}",
            severity=severity,
            category="CORS",
            endpoint=endpoint,
            method="GET",
            description=f"The endpoint accepts requests from untrusted origin '{origin}'. "
                       f"Access-Control-Allow-Origin: {acao}, "
                       f"Access-Control-Allow-Credentials: {acac or 'not set'}",
            evidence=f"Origin: {origin}\nACAO: {acao}\nACAC: {acac}",
            business_impact=75000 if severity == Severity.CRITICAL else 25000,
            impact_explanation="CORS misconfiguration can allow attackers to steal sensitive data "
                             "from authenticated users via malicious websites.",
            fix_suggestion="Configure CORS to only allow trusted origins. Never use wildcard (*) "
                         "with credentials. Validate the Origin header against a whitelist.",
            curl_command=f"curl -H 'Origin: {origin}' -I '{endpoint}'"
        )
