import psutil
import requests
import json
import time
import socket
from datetime import datetime
from collections import deque
from dotenv import load_dotenv
import os

# Load environment variables
load_dotenv()

BACKEND_URL = os.getenv("BACKEND_URL", "http://localhost:5000/api/metrics")
AUTH_TOKEN = os.getenv("AUTH_TOKEN", "test")
INTERVAL = int(os.getenv("INTERVAL", 10))
QUEUE_LIMIT = int(os.getenv("QUEUE_LIMIT", 50))

unsent_data = deque(maxlen=QUEUE_LIMIT)

def collect_metrics():
    metrics = {
        "hostname": socket.gethostname(),
        "timestamp": datetime.utcnow().isoformat(),
        "cpu": psutil.cpu_percent(interval=1),
        "memory": psutil.virtual_memory().percent,
        "disk_read": psutil.disk_io_counters().read_bytes,
        "disk_write": psutil.disk_io_counters().write_bytes,
        "net_in": psutil.net_io_counters().bytes_recv,
        "net_out": psutil.net_io_counters().bytes_sent
    }
    return metrics

def send_metrics(data):
    headers = {
        "Authorization": f"Bearer {AUTH_TOKEN}",
        "Content-Type": "application/json"
    }
    try:
        response = requests.post(BACKEND_URL, json=data, headers=headers, timeout=5)
        if response.status_code == 200:
            print(f"[{datetime.now()}] Metrics sent successfully.")
            return True
        else:
            print(f"[{datetime.now()}] Server responded with {response.status_code}")
            return False
    except requests.exceptions.RequestException:
        print(f"[{datetime.now()}] Connection failed. Queuing data...", data)
        return False

def flush_queue():
    global unsent_data
    while unsent_data:
        if send_metrics(unsent_data[0]):
            unsent_data.popleft()
        else:
            break

def main():
    print(f"Agent started. Sending metrics to {BACKEND_URL} every {INTERVAL}s.")
    while True:
        metrics = collect_metrics()
        if not send_metrics(metrics):
            unsent_data.append(metrics)
        flush_queue()
        time.sleep(INTERVAL)

if __name__ == "__main__":
    main()
