#!/usr/bin/env python3
# @CODE:HOOKS-REFACTOR-001 | SPEC: SPEC-HOOKS-REFACTOR-001.md
"""Alfred Hooks - Main entry point for MoAI-ADK Claude Code Hooks

A main entry point that routes Claude Code events to the appropriate handlers.

🏗️ Architecture:
┌─────────────────────────────────────────────────────────────┐
│ alfred_hooks.py (Router)                                    │
├─────────────────────────────────────────────────────────────┤
│ - CLI argument parsing                                      │
│ - JSON I/O (stdin/stdout)                                   │
│ - Event routing to handlers                                 │
└─────────────────────────────────────────────────────────────┘
                         ▼
┌─────────────────────────────────────────────────────────────┐
│ handlers/ (Event Handlers)                                  │
├─────────────────────────────────────────────────────────────┤
│ - session.py: SessionStart, SessionEnd                      │
│ - user.py: UserPromptSubmit                                 │
│ - tool.py: PreToolUse, PostToolUse                          │
│ - notification.py: Notification, Stop, SubagentStop         │
└─────────────────────────────────────────────────────────────┘
                         ▼
┌─────────────────────────────────────────────────────────────┐
│ core/ (Business Logic)                                      │
├─────────────────────────────────────────────────────────────┤
│ - project.py: Language detection, Git info, SPEC progress   │
│ - context.py: JIT Retrieval, workflow context               │
│ - checkpoint.py: Event-Driven Checkpoint system             │
│ - tags.py: TAG search/verification, library version cache   │
└─────────────────────────────────────────────────────────────┘

🛠️ Usage:
    python alfred_hooks.py <event_name> < payload.json

📣 Supported Events:
    - SessionStart: Start Session (display project status)
    - UserPromptSubmit: Prompt submission (JIT document loading)
    - PreToolUse: Before using the tool (automatically creates checkpoint)
    - SessionEnd, PostToolUse, Notification, Stop, SubagentStop

🚦 Exit Codes:
    - 0: Success
    - 1: Error (no arguments, JSON parsing failure, exception thrown)

🧪 TDD History:
    - RED: Module separation design, event routing test
    - GREEN: 1233 LOC → 9 items Module separation implementation (SRP compliance)
    - REFACTOR: Import optimization, enhanced error handling

Setup sys.path for package imports
"""

import json
import sys
from pathlib import Path
from typing import Any

from utils.timeout import CrossPlatformTimeout, TimeoutError as PlatformTimeoutError

from core import HookResult
from handlers import (
    handle_notification,
    handle_post_tool_use,
    handle_pre_tool_use,
    handle_session_end,
    handle_session_start,
    handle_stop,
    handle_subagent_stop,
    handle_user_prompt_submit,
)

# Add the hooks directory to sys.path to enable package imports
HOOKS_DIR = Path(__file__).parent
if str(HOOKS_DIR) not in sys.path:
    sys.path.insert(0, str(HOOKS_DIR))


    pass


def _hook_timeout_handler(signum, frame):
    """Signal handler for global hook timeout"""
    raise HookTimeoutError("Hook execution exceeded 5-second timeout")


def main() -> None:
    """Main entry point - Claude Code Hook script with GLOBAL TIMEOUT PROTECTION

    Receives the event name as a CLI argument and reads the JSON payload through stdin.
    Calls the handler appropriate for the event and outputs the results to stdout as JSON.
    Enforces a 5-second global timeout to prevent subprocess hangs from freezing Claude Code.

    🛠️ Usage:
        python alfred_hooks.py <event_name> < payload.json

    📣 Supported Events:
        - SessionStart: Start Session (display project status)
        - UserPromptSubmit: Prompt submission (JIT document loading)
        - SessionEnd, PreToolUse, PostToolUse, Notification, Stop, SubagentStop

    🚦 Exit Codes:
        - 0: Success
        - 1: Error (timeout, no arguments, JSON parsing failure, exception thrown)

    📝 Examples:
        $ echo '{"cwd": "."}' | python alfred_hooks.py SessionStart
        {"message": "🚀 MoAI-ADK Session Started\\n...", ...}

    🗒️ Notes:
        - Claude Code is automatically called (no need for direct user execution)
        - JSON I/O processing through stdin/stdout
        - Print error message to stderr
        - UserPromptSubmit uses a special output schema (hookEventName + additionalContext)
        - CRITICAL: 5-second global timeout prevents Claude Code freeze on subprocess hang

    🧪 TDD History:
        - RED: Event routing, JSON I/O, error handling testing
        - GREEN: Handler map-based routing implementation
        - REFACTOR: Error message clarification, exit code standardization, UserPromptSubmit schema separation
        - HOTFIX: Added global SIGALRM timeout to prevent subprocess hang (Issue #66)

    @TAG:HOOKS-TIMEOUT-001
    """
    # Set global 5-second timeout for entire hook execution
    signal.signal(signal.SIGALRM, _hook_timeout_handler)
    signal.alarm(5)

    try:
        # Check for event argument
        if len(sys.argv) < 2:
            print("Usage: alfred_hooks.py <event>", file=sys.stderr)
            sys.exit(1)

        event_name = sys.argv[1]

        try:
            # Read JSON from stdin
            input_data = sys.stdin.read()
            # Handle empty stdin gracefully (return empty dict)
            if not input_data or not input_data.strip():
                data = {}
            else:
                data = json.loads(input_data)

            cwd = data.get("cwd", ".")

            # Route to appropriate handler
            handlers = {
                "SessionStart": handle_session_start,
                "UserPromptSubmit": handle_user_prompt_submit,
                "SessionEnd": handle_session_end,
                "PreToolUse": handle_pre_tool_use,
                "PostToolUse": handle_post_tool_use,
                "Notification": handle_notification,
                "Stop": handle_stop,
                "SubagentStop": handle_subagent_stop,
            }

            handler = handlers.get(event_name)
            result = handler({"cwd": cwd, **data}) if handler else HookResult()

            # Output Hook result as JSON
            # Note: UserPromptSubmit uses to_user_prompt_submit_dict() for special schema
            if event_name == "UserPromptSubmit":
                print(json.dumps(result.to_user_prompt_submit_dict()))
            else:
                print(json.dumps(result.to_dict()))

            sys.exit(0)

        except json.JSONDecodeError as e:
            # Return valid Hook response even on JSON parse error
            error_response: dict[str, Any] = {
                "continue": True,
                "hookSpecificOutput": {"error": f"JSON parse error: {e}"},
            }
            print(json.dumps(error_response))
            print(f"JSON parse error: {e}", file=sys.stderr)
            sys.exit(1)
        except Exception as e:
            # Return valid Hook response even on unexpected error
            error_response: dict[str, Any] = {
                "continue": True,
                "hookSpecificOutput": {"error": f"Hook error: {e}"},
            }
            print(json.dumps(error_response))
            print(f"Unexpected error: {e}", file=sys.stderr)
            sys.exit(1)

    except PlatformTimeoutError:
        # CRITICAL: Hook took too long - return minimal valid response to prevent Claude Code freeze
        timeout_response: dict[str, Any] = {
            "continue": True,
            "systemMessage": "⚠️ Hook execution timeout - continuing without session info",
        }
        print(json.dumps(timeout_response))
        print("Hook timeout after 5 seconds", file=sys.stderr)
        sys.exit(1)

    finally:
        # Always cancel the alarm to prevent signal leakage
        timeout.cancel()


if __name__ == "__main__":
    main()
