"""Watch non-Python files and trigger Hypercorn reload.

Hypercorn --reload only watches .py files.  This script watches .sx,
.sx, .js, and .css files and touches a sentinel .py file when they
change, causing Hypercorn to restart.

Usage (from entrypoint.sh, before exec hypercorn):
    python3 -m shared.dev_watcher &
"""

import os
import time
import sys

WATCH_EXTENSIONS = {".sx", ".sx", ".js", ".css"}
SENTINEL = "/app/_reload_sentinel.py"
POLL_INTERVAL = 1.5  # seconds


def _collect_mtimes(roots):
    mtimes = {}
    for root in roots:
        for dirpath, _dirs, files in os.walk(root):
            for fn in files:
                ext = os.path.splitext(fn)[1]
                if ext in WATCH_EXTENSIONS:
                    path = os.path.join(dirpath, fn)
                    try:
                        mtimes[path] = os.path.getmtime(path)
                    except OSError:
                        pass
    return mtimes


def main():
    # Watch /app/shared and /app/<service>/sx plus static dirs
    roots = []
    for entry in os.listdir("/app"):
        full = os.path.join("/app", entry)
        if os.path.isdir(full):
            roots.append(full)
    if not roots:
        roots = ["/app"]

    # Ensure sentinel exists
    if not os.path.exists(SENTINEL):
        with open(SENTINEL, "w") as f:
            f.write("# reload sentinel\n")

    prev = _collect_mtimes(roots)
    while True:
        time.sleep(POLL_INTERVAL)
        curr = _collect_mtimes(roots)
        changed = []
        for path, mtime in curr.items():
            if path not in prev or prev[path] != mtime:
                changed.append(path)
        if changed:
            names = ", ".join(os.path.basename(p) for p in changed[:3])
            if len(changed) > 3:
                names += f" (+{len(changed) - 3} more)"
            print(f"[dev_watcher] Changed: {names} — triggering reload",
                  flush=True)
            os.utime(SENTINEL, None)
        prev = curr


if __name__ == "__main__":
    main()
