from __future__ import annotations

import os
import shutil
from typing import Iterable, List

import requests

from ..model import Finding, ScanRequest


def evaluate_third_party_integrations(request: ScanRequest) -> Iterable[Finding]:
    del request  # third-party status is environment-driven

    findings: List[Finding] = []
    findings.extend(_check_zap())
    findings.extend(_check_burp())
    findings.extend(_check_nikto())

    if not findings:
        findings.append(
            Finding(
                check="third-party",
                title="Third-party integrations ready",
                severity="info",
                description="OWASP ZAP, Burp Suite Enterprise, or Nikto integrations detected.",
                remediation="Trigger orchestrated scans using the integration CLI or API profiles.",
                impact="Coordinated execution expands passive coverage with specialized tooling.",
                i18n_key="thirdparty.ready",
            )
        )

    return findings


def _check_zap() -> List[Finding]:
    base_url = os.getenv("ZAP_API_URL")
    api_key = os.getenv("ZAP_API_KEY")
    if not base_url:
        return [
            Finding(
                check="third-party",
                title="OWASP ZAP API not configured",
                severity="low",
                description="Set ZAP_API_URL and optionally ZAP_API_KEY to enable passive scan integration.",
                remediation="Provision OWASP ZAP in daemon mode and expose the API over localhost with API key restrictions.",
                impact="Without the API endpoint the orchestrator cannot trigger baseline scans.",
                i18n_key="thirdparty.zap_not_configured",
            )
        ]

    try:
        params = {}
        if api_key:
            params["apikey"] = api_key
        response = requests.get(
            f"{base_url.rstrip('/')}/JSON/core/view/version/",
            params=params,
            timeout=5,
        )
    except requests.RequestException as exc:
        return [
            Finding(
                check="third-party",
                title="OWASP ZAP API unreachable",
                severity="medium",
                description=f"Failed to query ZAP API at {base_url}: {exc}",
                remediation="Ensure the daemon is running, network ACLs allow loopback connections, and the API key is valid.",
                impact="Passive spidering and alerts export are disabled.",
                i18n_key="thirdparty.zap_unreachable",
                i18n_params={
                    "url": base_url,
                    "error": str(exc),
                },
            )
        ]

    if response.ok:
        version = response.json().get("version", "unknown")
        return [
            Finding(
                check="third-party",
                title="OWASP ZAP API detected",
                severity="info",
                description=f"ZAP API reachable at {base_url} (version {version}).",
                remediation="Configure ZAP context to restrict scope and share session storage with the orchestrator.",
                impact="ZAP passive scanning can be scheduled alongside internal checks.",
                i18n_key="thirdparty.zap_detected",
                i18n_params={
                    "url": base_url,
                    "version": version,
                },
            )
        ]

    return [
        Finding(
            check="third-party",
            title="OWASP ZAP API returned error",
            severity="medium",
            description=f"ZAP API responded with HTTP {response.status_code}.",
            remediation="Review ZAP logs and confirm the API endpoint is accessible with the configured key.",
            impact="Passive findings cannot be harvested from ZAP.",
            i18n_key="thirdparty.zap_error",
            i18n_params={
                "url": base_url,
                "status": response.status_code,
            },
        )
    ]


def _check_burp() -> List[Finding]:
    base_url = os.getenv("BURP_API_URL")
    api_key = os.getenv("BURP_API_KEY")
    if not base_url:
        return [
            Finding(
                check="third-party",
                title="Burp Suite Enterprise API not configured",
                severity="low",
                description="Set BURP_API_URL/BURP_API_KEY to pull passive issues into the report.",
                remediation="Expose the Burp Enterprise REST API and generate an API key with read-only scope.",
                impact="Burp scan baselines will not be correlated in sentinel reports.",
                i18n_key="thirdparty.burp_not_configured",
            )
        ]

    headers = {}
    if api_key:
        headers["Authorization"] = f"Bearer {api_key}"

    try:
        response = requests.get(
            f"{base_url.rstrip('/')}/v1/status",
            headers=headers,
            timeout=5,
        )
    except requests.RequestException as exc:
        return [
            Finding(
                check="third-party",
                title="Burp Enterprise API unreachable",
                severity="medium",
                description=f"Failed to connect to Burp Enterprise at {base_url}: {exc}",
                remediation="Check VPN access, TLS certificates, and API key validity.",
                impact="No delta analysis between Burp and internal diagnostics.",
                i18n_key="thirdparty.burp_unreachable",
                i18n_params={
                    "url": base_url,
                    "error": str(exc),
                },
            )
        ]

    if response.ok:
        return [
            Finding(
                check="third-party",
                title="Burp Suite Enterprise API detected",
                severity="info",
                description=f"Burp Enterprise API reachable at {base_url}.",
                remediation="Automate scan scheduling and import issues via the orchestrator pipeline.",
                impact="Correlating Burp findings enhances triage accuracy.",
                i18n_key="thirdparty.burp_detected",
                i18n_params={"url": base_url},
            )
        ]

    return [
        Finding(
            check="third-party",
            title="Burp Suite Enterprise API returned error",
            severity="medium",
            description=f"Burp API responded with HTTP {response.status_code}.",
            remediation="Inspect Burp Enterprise logs and validate account permissions.",
            impact="Remote vulnerability data cannot be synchronized.",
            i18n_key="thirdparty.burp_error",
            i18n_params={
                "url": base_url,
                "status": response.status_code,
            },
        )
    ]


def _check_nikto() -> List[Finding]:
    binary = os.getenv("NIKTO_PATH") or shutil.which("nikto")
    if not binary:
        return [
            Finding(
                check="third-party",
                title="Nikto binary not found",
                severity="low",
                description="Nikto executable missing from PATH; passive profile cannot be launched.",
                remediation="Install Nikto and expose the path via NIKTO_PATH or system PATH.",
                impact="Legacy HTTP misconfiguration coverage from Nikto will be absent.",
                i18n_key="thirdparty.nikto_not_found",
            )
        ]

    return [
        Finding(
            check="third-party",
            title="Nikto binary detected",
            severity="info",
            description=f"Nikto available at {binary}.",
            remediation="Invoke Nikto with `-Plugins passive -Format json` and import results via the report engine.",
            impact="Nikto baselines can run as part of scheduled orchestrations.",
            i18n_key="thirdparty.nikto_detected",
            i18n_params={"path": binary},
        )
    ]
