import requests
import time
import json

FASTAPI_URL = "http://localhost:8000/api/alerts"  # عدّليها لـ 10.0.0.124:8000 لو بتشغليها من مكان تاني غير k2

def simulate_spark_alert_burst(n_unique_ips, base_ip_prefix="203.0.113"):
    results = {"success": 0, "timeout": 0, "other_error": 0, "latencies": []}

    print(f"\n{'='*60}")
    print(f"Simulating Spark sending {n_unique_ips} sequential alerts (timeout=3s each)...")
    print(f"{'='*60}")

    batch_start = time.time()

    for i in range(n_unique_ips):
        alert = {
            "attack_type": "DDoS",
            "src_ip": f"{base_ip_prefix}.{i % 254 + 1}",
            "severity": "HIGH",
            "occurrence_count": 1,
            "sample_features": {}
        }

        start = time.time()
        try:
            resp = requests.post(FASTAPI_URL, json=alert, timeout=3)
            elapsed = time.time() - start
            results["latencies"].append(elapsed)
            if resp.status_code == 200:
                results["success"] += 1
            else:
                print(f"  [UNEXPECTED STATUS] Alert #{i+1}: {resp.status_code}")
        except requests.exceptions.Timeout:
            results["timeout"] += 1
            print(f"  [LOST] Alert #{i+1} DROPPED (timeout > 3s)")
        except Exception as ex:
            results["other_error"] += 1
            print(f"  [ERROR] Alert #{i+1}: {ex}")

    total_batch_time = time.time() - batch_start

    print(f"\n--- Results for {n_unique_ips} sequential alerts ---")
    print(f"Successful:      {results['success']}/{n_unique_ips}")
    print(f"LOST (timeout):  {results['timeout']}/{n_unique_ips}  <-- critical metric")
    print(f"Other errors:    {results['other_error']}/{n_unique_ips}")
    if results["latencies"]:
        avg_lat = sum(results["latencies"]) / len(results["latencies"])
        print(f"Avg latency (successful only): {avg_lat:.3f}s")
        print(f"Max latency (successful only): {max(results['latencies']):.3f}s")
    print(f"Total time for Spark to send this batch: {total_batch_time:.2f}s")
    print(f"(Spark's next trigger fires every 15s — if this exceeds ~15s, batches back up)")

    return {
        "n": n_unique_ips,
        "success": results["success"],
        "lost": results["timeout"],
        "errors": results["other_error"],
        "total_time": total_batch_time
    }


if __name__ == "__main__":
    summary = []
    for n in [100, 300, 600, 1000]:
        r = simulate_spark_alert_burst(n)
        summary.append(r)
        time.sleep(3)  # فترة راحة بين كل حجم دفعة

    print(f"\n{'='*60}")
    print("FINAL SUMMARY")
    print(f"{'='*60}")
    print(f"{'Batch Size':<12}{'Success':<10}{'Lost':<10}{'Errors':<10}{'Total Time (s)':<15}")
    for r in summary:
        print(f"{r['n']:<12}{r['success']:<10}{r['lost']:<10}{r['errors']:<10}{r['total_time']:<15.2f}")
