from flask import Flask
from flask_cors import CORS
from time import sleep
from typing import cast
from zeroconf import IPVersion, ServiceBrowser, ServiceStateChange, Zeroconf, ZeroconfServiceTypes
import json
import threading

#init the app
app = Flask(__name__)
CORS(app)
app.cache={}
app.srv_out={}

def identify_service(addr: str):
    if "smb" in app.cache[addr]["service_type"]:
        app.cache[addr]["type"]="SMB"
        #TODO: detect shares from IP/Port
    elif "nfs" in app.cache[addr]["service_type"]:
        app.cache[addr]["type"]="NFS"
        #TODO: detect shares from IP/Port
    elif "afp" in app.cache[addr]["service_type"]:
        app.cache[addr]["type"]="AFP"

def on_service_state_change(
    zeroconf: Zeroconf, service_type: str, name: str, state_change: ServiceStateChange
) -> None:
    if state_change is ServiceStateChange.Added:
        info = zeroconf.get_service_info(service_type, name)
        for addr in info.parsed_addresses(IPVersion.V4Only):
            if addr is not None and addr+":"+str(info.port) not in app.cache:
                app.cache[addr+":"+str(info.port)]={"address": addr, "port": int(info.port), "name": name, "service_type": service_type, "shares": [], "type":"" }
                identify_service(addr+":"+str(info.port))
    for k in app.cache:
        if app.cache[k]["type"]!="":
            app.srv_out[k]=app.cache[k]

def do_browse():
    ip_version = IPVersion.V4Only
    zeroconf = Zeroconf(ip_version=ip_version)
    services = list(ZeroconfServiceTypes.find(zc=zeroconf))
    services_search=[]
    for s in services:
        if "smb" in s or "afp" in s or "nfs" in s:
            services_search.append(s)
    browser = ServiceBrowser(zeroconf, services_search, handlers=[on_service_state_change])

#start browsing for devices
th = threading.Thread(target=do_browse)
th.start()

@app.route("/get_services")
def discover_services():
    return json.dumps(app.srv_out)

if __name__ == "__main__":
    app.run()

