#!/usr/bin/python3.11

import socket
from socket import socket, AF_INET, SOCK_DGRAM, inet_aton
import ipaddress

try:
    from zeroconf import ServiceBrowser, ServiceListener, Zeroconf
    GOT_ZEROCONF = True
except ImportError:
    GOT_ZEROCONF = False
    print("Error importing zeroconf module.")
    print("Perhaps it isn't installed?.")
    print("pip install zeroconf")

def getMyIPaddress():
    sx = socket(AF_INET, SOCK_DGRAM)
    sx.connect(("8.8.8.8", 80))
    return sx.getsockname()[0]

class myListener(ServiceListener):

    def __init__(self, my_ip_address, notify_add_service):
        self.my_ip_address = inet_aton(my_ip_address)
        self.notify_add_service = notify_add_service

    def update_service(self, zc: Zeroconf, type_: str, name: str) -> None:
        print(f"Service {name} updated")

    def remove_service(self, zc: Zeroconf, type_: str, name: str) -> None:
        print(f"Service {name} removed")

    def add_service(self, zc: Zeroconf, type_: str, name: str) -> None:
        info = zc.get_service_info(type_, name)
        print(f"Service {name} added, service info: {info}")
        for address in info.addresses:
            if self.my_ip_address != address:
                their_ip_address = str(ipaddress.IPv4Address(address))
                self.notify_add_service(True, their_ip_address)

class FindController:
    def __init__(self, notify_add_service):
        self.notify_add_service = notify_add_service
        self.zeroconf = None

    def Run(self):
        if GOT_ZEROCONF:
            self.zeroconf = Zeroconf()
            self.listener = myListener(getMyIPaddress(), self.notify_add_service)
            self.browser = ServiceBrowser(self.zeroconf,"_controller._udp.local.", self.listener)
        else:
            print("zeroconf module not installed.")

    def Stop(self):
        if self.zeroconf:
            self.zeroconf.close()
            self.zeroconf = None

def main():
    """ simple test
    """
    import time
    
    def notify_add_service(available, ip_address):
        print(ip_address)

    myFindController = FindController(notify_add_service)
    myFindController.Run()
    time.sleep(10)
    myFindController.Stop()

if __name__ == "__main__":
    main()
            
        
