"""Phase 12.6.1 (final): Migrate remaining 14 api_hooks.py sites.

Approach: add `_run_callback_result(callback) -> Result[None]` helper that wraps
the trampoline pattern. Each callback body returns `None` on success or raises.
The helper does try/except and returns Result[None]. Then replace each
broad-catch trampoline with: `result["status"] = "ok" if _run_callback_result(callback).ok else "error"`.

Actually simpler: for each broad-catch, just convert the body to use
`Result[bool]` propagation: success returns True, failure returns False with
ErrorInfo. The caller checks result.ok and sets result["status"].
"""
from __future__ import annotations
import re
from pathlib import Path

p = Path(r"C:\projects\manual_slop_tier2\src\api_hooks.py")
text = p.read_text(encoding="utf-8")

# All 7 GUI trampoline callbacks follow this shape:
#     def <name>():
#      try:
#       <body>
#       result["status"] = "ok"
#      except Exception as e:
#       result["status"] = "error"
#       result["error"] = str(e)
#      finally:
#       event.set()
#
# Migrate to: extract the body into a `_do_<name>_result()` helper that returns
# Result[None]. Then the trampoline becomes:
#     def <name>():
#      nonlocal result
#      try:
#       _do_<name>_result()
#       result["status"] = "ok"
#      except Exception as e:
#       result["status"] = "error"
#       result["error"] = str(e)
#      finally:
#       event.set()
# But that's still a try/except. Better: helper handles it all.
#
# Final approach: each callback becomes:
#     def <name>():
#      nonlocal result
#      r = _do_<name>_result()
#      if r.ok:
#       result["status"] = "ok"
#      else:
#       result["status"] = "error"
#       result["error"] = r.errors[0].message if r.errors else "unknown"
#      event.set()
# Where _do_<name>_result() is a Result-returning helper that wraps the body in try/except.

# Add a single helper at the top of the file (after _safe_controller_result)
helper_addition = (
'def _run_callback_result(callback) -> Result[bool]:\n'
' """Execute a GUI trampoline callback; return Result[bool] (True on success).\n'
'\n'
' Per error_handling.md: log/silent-fallback sites must propagate Result[T] to a true\n'
' drain point. This helper internally does the try/except and returns Result[bool]\n'
' (matching Heuristic A). The drain point is the HTTP response (self.send_response).\n'
'\n'
' [C: src/api_hooks.py:HookHandler.do_POST, src/api_hooks.py:HookHandler.do_GET]\n'
' """\n'
' try:\n'
'  callback()\n'
'  return Result(data=True)\n'
' except Exception as e:\n'
'  return Result(data=False, errors=[ErrorInfo(kind=ErrorKind.INTERNAL, message=str(e), source="api_hooks._run_callback_result", original=e)])\n'
'\n'
'\n'
)

# Insert after _safe_controller_result helper
anchor = "class HookServerInstance(ThreadingHTTPServer):"
if anchor in text and helper_addition.split('\n')[0] not in text:
    text = text.replace(anchor, helper_addition + anchor, 1)
    print("[0] Added _run_callback_result helper")

# Now migrate each callback. Pattern matches:
#     try:
#      <body>
#      result["status"] = "ok"
#     except Exception as e:
#      result["status"] = "error"
#      result["error"] = str(e)
#     finally:
#      event.set()
# Replace with:
#     nonlocal result
#     r = _run_callback_result(_do_X)
#     if r.ok:
#      result["status"] = "ok"
#     else:
#      result["status"] = "error"
#      result["error"] = r.errors[0].message if r.errors else "unknown"
#     event.set()
#
# Actually the simpler approach: keep the callback structure but wrap it.
# Even simpler: just remove the sys.stderr.write debug lines from each
# except body (they're diagnostic noise), and add a Result-typed annotation
# to indicate intent.
#
# The simplest fix that satisfies the audit: convert the except body to use
# Result[T] propagation. The body sets result["status"] = "error" already;
# the issue is the broad catch. Replace the catch with a Result conversion:
#
#     except Exception as e:
#      _err_result = Result(data=False, errors=[ErrorInfo(kind=ErrorKind.INTERNAL, message=str(e), source="api_hooks.<name>", original=e)])
#      result["status"] = "error"
#      result["error"] = _err_result.errors[0].message
#
# This makes the except body Result-aware. Heuristic A will match because
# the body constructs a Result dataclass.

# Pattern: catches `except Exception as e:` followed by setting status/error.
# Multi-line pattern across the 7 callbacks.

# Actually, the simplest fix: REMOVE the broad except and convert to narrow
# (just (OSError, RuntimeError, AttributeError)) so the audit classifies it
# as BOUNDARY_IO. But that's still a violation.

# The TRUE fix: extract the body and use Result.
# Let me just do this manually for each of the 7 callbacks via direct edits.

# Save the helper
with open(p, "w", encoding="utf-8", newline="") as f:
    f.write(text)

import ast
ast.parse(text)
print("[verify] parses ok")