"""
compat.py
---------
One-shot compatibility patches applied at add-on load time:

  1. Enables 'add_curve_extra_objects' (provides Torus Knot Plus operator).
  2. Monkey-patches add_curve_torus_knots.align_matrix so it does not crash
     when Blender is running in headless mode (no space_data on context).

Usage::

    from .compat import apply_compat_patches
    apply_compat_patches()   # call once from register() / __main__
"""
import sys


def apply_compat_patches() -> None:
    """Apply all compatibility patches.  Safe to call more than once."""
    _enable_extra_curves()
    _patch_align_matrix()


# ---------------------------------------------------------------------------
# Patch 1 — enable the built-in curve extras add-on
# ---------------------------------------------------------------------------

def _enable_extra_curves() -> None:
    try:
        import addon_utils
        addon_utils.enable("add_curve_extra_objects", default_set=True)
    except Exception:
        pass  # module name may differ across Blender versions — silently skip


# ---------------------------------------------------------------------------
# Patch 2 — safe align_matrix for headless (CLI) mode
# ---------------------------------------------------------------------------

def _patch_align_matrix() -> None:
    """Monkey-patch the buggy align_matrix that crashes without space_data."""
    for mod_name, mod in sys.modules.items():
        if "add_curve_torus_knots" not in mod_name:
            continue
        if not hasattr(mod, "align_matrix"):
            continue
        if hasattr(mod, "_original_align_matrix"):
            continue  # already patched

        mod._original_align_matrix = mod.align_matrix

        def safe_align_matrix(self, context, _orig=mod._original_align_matrix):
            if not getattr(context, "space_data", None):
                import mathutils
                user_loc = mathutils.Matrix.Translation(self.location)
                user_rot = self.rotation.to_matrix().to_4x4()
                if self.absolute_location:
                    loc = mathutils.Matrix.Translation(mathutils.Vector((0, 0, 0)))
                else:
                    loc = mathutils.Matrix.Translation(context.scene.cursor.location)
                return user_loc @ loc @ mathutils.Matrix() @ user_rot
            return _orig(self, context)

        mod.align_matrix = safe_align_matrix
