#!/usr/bin/env python3
"""Agent for implementing EPSS (Exploit Prediction Scoring System) for vulnerability prioritization."""

import json
import argparse
import csv

try:
    import requests
except ImportError:
    requests = None

EPSS_API_URL = "https://api.first.org/data/v1/epss"


def get_epss_scores(cve_list):
    """Fetch EPSS scores for a list of CVE IDs from the FIRST.org API."""
    if not requests:
        return {"error": "requests library not installed"}
    results = []
    # API supports up to 100 CVEs per request
    for i in range(0, len(cve_list), 100):
        batch = cve_list[i:i + 100]
        params = {"cve": ",".join(batch)}
        resp = requests.get(EPSS_API_URL, params=params, timeout=30)
        resp.raise_for_status()
        data = resp.json()
        for item in data.get("data", []):
            results.append({
                "cve": item["cve"],
                "epss": float(item["epss"]),
                "percentile": float(item["percentile"]),
            })
    return {"total": len(results), "scores": results}


def get_epss_csv():
    """Download the full EPSS score CSV from FIRST.org."""
    if not requests:
        return {"error": "requests library not installed"}
    resp = requests.get(f"{EPSS_API_URL}?envelope=true&pretty=true", timeout=60)
    resp.raise_for_status()
    return resp.json()


def prioritize_vulnerabilities(cve_scores, epss_threshold=0.1, percentile_threshold=0.9):
    """Prioritize vulnerabilities based on EPSS score and percentile."""
    critical = []
    high = []
    medium = []
    low = []
    for item in cve_scores:
        epss = item["epss"]
        pct = item["percentile"]
        if epss >= epss_threshold or pct >= percentile_threshold:
            item["priority"] = "CRITICAL"
            critical.append(item)
        elif epss >= 0.05:
            item["priority"] = "HIGH"
            high.append(item)
        elif epss >= 0.01:
            item["priority"] = "MEDIUM"
            medium.append(item)
        else:
            item["priority"] = "LOW"
            low.append(item)
    return {
        "thresholds": {"epss": epss_threshold, "percentile": percentile_threshold},
        "summary": {
            "critical": len(critical),
            "high": len(high),
            "medium": len(medium),
            "low": len(low),
        },
        "critical": sorted(critical, key=lambda x: x["epss"], reverse=True),
        "high": sorted(high, key=lambda x: x["epss"], reverse=True),
    }


def enrich_from_scan(scan_file, output_file=None):
    """Enrich a vulnerability scan CSV with EPSS scores."""
    with open(scan_file, "r") as f:
        reader = csv.DictReader(f)
        rows = list(reader)
    cve_col = None
    for col in ["CVE", "cve", "CVE-ID", "cve_id", "vulnerability_id"]:
        if col in (rows[0] if rows else {}):
            cve_col = col
            break
    if not cve_col:
        return {"error": "No CVE column found in scan file"}
    cves = [row[cve_col] for row in rows if row.get(cve_col, "").startswith("CVE-")]
    if not cves:
        return {"error": "No CVE IDs found in scan file"}
    epss_data = get_epss_scores(cves)
    epss_map = {s["cve"]: s for s in epss_data.get("scores", [])}

    enriched = []
    for row in rows:
        cve = row.get(cve_col, "")
        epss_info = epss_map.get(cve, {})
        row["epss_score"] = epss_info.get("epss", "N/A")
        row["epss_percentile"] = epss_info.get("percentile", "N/A")
        enriched.append(row)

    if output_file:
        fieldnames = list(enriched[0].keys())
        with open(output_file, "w", newline="") as f:
            writer = csv.DictWriter(f, fieldnames=fieldnames)
            writer.writeheader()
            writer.writerows(enriched)

    prioritized = prioritize_vulnerabilities(
        [s for s in epss_data.get("scores", [])]
    )
    return {
        "scan_file": scan_file,
        "total_cves": len(cves),
        "enriched_count": sum(1 for r in enriched if r["epss_score"] != "N/A"),
        "prioritization": prioritized["summary"],
        "top_10_exploitable": prioritized.get("critical", [])[:10],
    }


def main():
    parser = argparse.ArgumentParser(description="EPSS Vulnerability Prioritization Agent")
    sub = parser.add_subparsers(dest="command")
    s = sub.add_parser("score", help="Get EPSS scores for CVE IDs")
    s.add_argument("--cves", nargs="+", required=True, help="CVE IDs (e.g., CVE-2024-1234)")
    e = sub.add_parser("enrich", help="Enrich vulnerability scan with EPSS scores")
    e.add_argument("--scan-file", required=True, help="CSV vulnerability scan report")
    e.add_argument("--output", help="Output enriched CSV file")
    args = parser.parse_args()
    if args.command == "score":
        epss = get_epss_scores(args.cves)
        result = prioritize_vulnerabilities(epss.get("scores", []))
        result["raw_scores"] = epss["scores"]
    elif args.command == "enrich":
        result = enrich_from_scan(args.scan_file, args.output)
    else:
        parser.print_help()
        return
    print(json.dumps(result, indent=2, default=str))


if __name__ == "__main__":
    main()
