"""
Exploitability validator — confirm findings are actually exploitable.
"""

from __future__ import annotations

from typing import Any

from senshi.ai.brain import Brain
from senshi.reporters.models import Confidence, Finding
from senshi.utils.logger import get_logger

logger = get_logger("senshi.dast.validators.exploitability")


EXPLOITABILITY_PROMPT = """You are assessing the EXPLOITABILITY of a security finding.

A finding may be real (the vulnerability exists) but not exploitable
(there are mitigating factors that prevent actual exploitation).

FINDING:
{finding_json}

Assess:
1. Can this be exploited in a real-world scenario?
2. What prerequisites does an attacker need?
3. Are there mitigating controls (CSP, SameSite cookies, etc.)?
4. What is the realistic impact if exploited?
5. How complex is the exploitation?

OUTPUT FORMAT (strict JSON):
{{
  "is_exploitable": true,
  "exploitation_complexity": "low|medium|high",
  "prerequisites": "what the attacker needs",
  "mitigating_factors": "what reduces the impact",
  "realistic_impact": "what actually happens if exploited",
  "revised_cvss": 0.0,
  "reasoning": "detailed explanation"
}}"""


class ExploitabilityValidator:
    """Validate if findings are actually exploitable."""

    def __init__(self, brain: Brain) -> None:
        self.brain = brain

    def validate(self, finding: Finding) -> Finding | None:
        """
        Validate exploitability of a finding.

        Returns the finding with updated CVSS if exploitable, None if not.
        """
        import json

        finding_json = json.dumps(finding.to_dict(), indent=2)

        system_prompt = EXPLOITABILITY_PROMPT.format(finding_json=finding_json)

        try:
            result = self.brain.think(
                system_prompt=system_prompt,
                user_prompt="Assess the exploitability of this finding.",
                json_schema={"type": "object"},
            )

            if isinstance(result, dict):
                if not result.get("is_exploitable", True):
                    logger.debug(f"Not exploitable: {finding.title}")
                    return None

                # Update CVSS with revised estimate
                revised_cvss = result.get("revised_cvss", finding.cvss_estimate)
                if revised_cvss:
                    finding.cvss_estimate = revised_cvss

                # Add exploitation context
                finding.evidence += (
                    f"\nExploitation complexity: {result.get('exploitation_complexity', 'unknown')}"
                    f"\nPrerequisites: {result.get('prerequisites', 'none')}"
                )

                return finding

            return finding

        except Exception as e:
            logger.warning(f"Exploitability validation failed: {e}")
            return finding

    def validate_batch(self, findings: list[Finding]) -> list[Finding]:
        """Validate a batch of findings."""
        validated = []
        for finding in findings:
            result = self.validate(finding)
            if result is not None:
                validated.append(result)
        return validated
