import os
import socket
import threading
import time
import gevent  # Add this import
from django.conf import settings

# SSDP Multicast Address and Port
SSDP_MULTICAST = "239.255.255.250"
SSDP_PORT = 1900

DEVICE_TYPE = "urn:schemas-upnp-org:device:MediaServer:1"
SERVER_PORT = 8000

def get_host_ip():
    try:
        # This relies on "host.docker.internal" being mapped to the host’s gateway IP.
        return socket.gethostbyname("host.docker.internal")
    except Exception:
        return "127.0.0.1"

def ssdp_response(addr, host_ip):
    response = (
        f"HTTP/1.1 200 OK\r\n"
        f"CACHE-CONTROL: max-age=1800\r\n"
        f"EXT:\r\n"
        f"LOCATION: http://{host_ip}:{SERVER_PORT}/hdhr/device.xml\r\n"
        f"SERVER: Dispatcharr/1.0 UPnP/1.0 HDHomeRun/1.0\r\n"
        f"ST: {DEVICE_TYPE}\r\n"
        f"USN: uuid:device1-1::{DEVICE_TYPE}\r\n"
        f"\r\n"
    )
    sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
    sock.sendto(response.encode("utf-8"), addr)
    sock.close()

def ssdp_listener(host_ip):
    sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
    sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    sock.bind((SSDP_MULTICAST, SSDP_PORT))
    while True:
        data, addr = sock.recvfrom(1024)
        if b"M-SEARCH" in data and DEVICE_TYPE.encode("utf-8") in data:
            print(f"Received M-SEARCH from {addr}")
            ssdp_response(addr, host_ip)

def ssdp_broadcaster(host_ip):
    notify = (
        f"NOTIFY * HTTP/1.1\r\n"
        f"HOST: {SSDP_MULTICAST}:{SSDP_PORT}\r\n"
        f"CACHE-CONTROL: max-age=1800\r\n"
        f"LOCATION: http://{host_ip}:{SERVER_PORT}/hdhr/device.xml\r\n"
        f"SERVER: Dispatcharr/1.0 UPnP/1.0 HDHomeRun/1.0\r\n"
        f"NT: {DEVICE_TYPE}\r\n"
        f"NTS: ssdp:alive\r\n"
        f"USN: uuid:device1-1::{DEVICE_TYPE}\r\n"
        f"\r\n"
    )
    sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
    sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, 2)
    while True:
        sock.sendto(notify.encode("utf-8"), (SSDP_MULTICAST, SSDP_PORT))
        gevent.sleep(30)  # Replace time.sleep with gevent.sleep

def start_ssdp():
    host_ip = get_host_ip()
    threading.Thread(target=ssdp_listener, args=(host_ip,), daemon=True).start()
    threading.Thread(target=ssdp_broadcaster, args=(host_ip,), daemon=True).start()
    print(f"SSDP services started on {host_ip}.")
