"""Adom Bridge — Fusion 360 Add-In.

Starts a localhost HTTP server on a background thread (port 8774).
Incoming commands are marshaled to the main Fusion thread via a CustomEvent,
so all Fusion API calls execute safely on the main thread.
"""

import adsk.core
import adsk.fusion
import traceback

# Module-level references kept alive for the add-in lifetime
_app = None
_ui = None
_custom_event = None
_event_handler = None
_http_thread = None

CUSTOM_EVENT_ID = "AdomBridgeCommandEvent"


class CommandEventHandler(adsk.core.CustomEventHandler):
    """Handles custom events fired from the HTTP background thread.

    Each event's additionalInfo is a JSON string with {request_id, command, args}.
    The handler dispatches to the appropriate command function, then stores
    the result so the HTTP thread can return it.
    """

    def __init__(self):
        super().__init__()

    def notify(self, args: adsk.core.CustomEventArgs):
        try:
            import json
            from . import http_server
            from .commands import dispatch_command

            info = json.loads(args.additionalInfo)
            request_id = info["request_id"]
            command = info["command"]
            cmd_args = info.get("args", {})

            # Staleness check: if the HTTP waiter already timed out and
            # bailed, skip the work entirely. Saves main-thread time on
            # heavy exports whose caller already gave up.
            if not http_server.is_request_alive(request_id):
                adsk.core.Application.log(
                    f"AdomBridge: skipping stale request {request_id[:8]} ({command}) — HTTP waiter gone"
                )
                return

            try:
                result = dispatch_command(_app, command, cmd_args)
            except Exception as e:
                result = {"success": False, "error": f"Command error: {e}\n{traceback.format_exc()}"}

            http_server.set_result(request_id, result)

        except Exception:
            traceback.print_exc()


def run(context):
    """Called by Fusion 360 when the add-in starts."""
    global _app, _ui, _custom_event, _event_handler, _http_thread

    try:
        _app = adsk.core.Application.get()
        _ui = _app.userInterface

        # Register the custom event for thread marshaling
        _custom_event = _app.registerCustomEvent(CUSTOM_EVENT_ID)
        _event_handler = CommandEventHandler()
        _custom_event.add(_event_handler)

        # Start the HTTP server on a background daemon thread
        from . import http_server
        _http_thread = http_server.start(CUSTOM_EVENT_ID, _app)

        # Log to the Text Commands palette (non-blocking)
        adsk.core.Application.log(f"Adom Bridge add-in started (port 8774)")

    except Exception:
        # Only use messageBox for errors — worth blocking to show the user
        if _ui:
            _ui.messageBox(f"Adom Bridge failed to start:\n{traceback.format_exc()}")


def stop(context):
    """Called by Fusion 360 when the add-in stops."""
    global _app, _ui, _custom_event, _event_handler, _http_thread

    try:
        # Stop HTTP server
        from . import http_server
        http_server.stop()

        # Unregister custom event
        if _app and _custom_event:
            _app.unregisterCustomEvent(CUSTOM_EVENT_ID)

        _custom_event = None
        _event_handler = None
        _http_thread = None

    except Exception:
        if _ui:
            _ui.messageBox(f"Adom Bridge stop error:\n{traceback.format_exc()}")