import logging
import logging.handlers
import threading
import time
import sys

from kprobe import load_bpf_program, probe
from exporter import record_retransmissions
from kubeinfo import update_pod_info

logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s - %(levelname)s - %(filename)s - %(message)s',
    datefmt='%Y-%m-%d %H:%M:%S',
    handlers=[
        logging.FileHandler('manager.log'),
        # Send logs to Syslog
        logging.handlers.SysLogHandler(address='/dev/log')
    ]
)
logger = logging.getLogger(__name__)

bpf_program = None


def pod_info_thread():
    logger.info("Starting pod_info_thread... ")
    while True:
        update_pod_info()
        time.sleep(60)


def probe_thread():
    global bpf_program
    logger.info("Starting probe_thread... ")    
    while True:
        probe(bpf_program, record_retransmissions)
        time.sleep(1)


def monitor_threads(threads):
    """Monitors the threads tocheck they are running."""
    print("Manager started: counting TCP retransmissions per flow..."
          "Press Ctrl+C to exit.")
    try:
        while True:
            time.sleep(2)
            for thread in threads:
                if not thread.is_alive():
                    print(f"Thread {thread.name} failed or not running.")
                    sys.exit(1) 
    except KeyboardInterrupt:
        print("Stopping threads...")
        for thread in threads:
            print(f"Stopping thread: {thread.name}")
        sys.exit(0)


def main():
    global bpf_program
    
    logger.info("Starting manager... ")

    try:
        # Load BPF inside the try block so we can log the failure
        bpf_program = load_bpf_program()
    except Exception as e:
        logger.error(f"Failed to load BPF program: {e}")
        sys.exit(1)

    threads = []
    for i, name in [(pod_info_thread, "pod_info"), (probe_thread, "probe")]:
        thread = threading.Thread(target=i, name=name, daemon=True)
        threads.append(thread)
        thread.start()

    monitor_threads(threads)


if __name__ == "__main__":
    main()
