from __future__ import annotations

import os
import shutil
from typing import Iterable, List

import requests

from ..localization.helpers import create_translated_finding
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(
            create_translated_finding(
                check="third-party",
                i18n_key="thirdparty.ready",
                severity="info",
            )
        )

    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 [
            create_translated_finding(
                check="third-party",
                i18n_key="thirdparty.zap_not_configured",
                severity="low",
            )
        ]

    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 [
            create_translated_finding(
                check="third-party",
                i18n_key="thirdparty.zap_unreachable",
                severity="medium",
                i18n_params={
                    "url": base_url,
                    "error": str(exc),
                },
            )
        ]

    if response.ok:
        version = response.json().get("version", "unknown")
        return [
            create_translated_finding(
                check="third-party",
                i18n_key="thirdparty.zap_detected",
                severity="info",
                i18n_params={
                    "url": base_url,
                    "version": version,
                },
            )
        ]

    return [
        create_translated_finding(
            check="third-party",
            i18n_key="thirdparty.zap_error",
            severity="medium",
            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 [
            create_translated_finding(
                check="third-party",
                i18n_key="thirdparty.burp_not_configured",
                severity="low",
            )
        ]

    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 [
            create_translated_finding(
                check="third-party",
                i18n_key="thirdparty.burp_unreachable",
                severity="medium",
                i18n_params={
                    "url": base_url,
                    "error": str(exc),
                },
            )
        ]

    if response.ok:
        return [
            create_translated_finding(
                check="third-party",
                i18n_key="thirdparty.burp_detected",
                severity="info",
                i18n_params={"url": base_url},
            )
        ]

    return [
        create_translated_finding(
            check="third-party",
            i18n_key="thirdparty.burp_error",
            severity="medium",
            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 [
            create_translated_finding(
                check="third-party",
                i18n_key="thirdparty.nikto_not_found",
                severity="low",
            )
        ]

    return [
        create_translated_finding(
            check="third-party",
            i18n_key="thirdparty.nikto_detected",
            severity="info",
            i18n_params={"path": binary},
        )
    ]
