import os
import platform
import sys

import typer


def main():
    """Launches aiexec with appropriate environment setup.

    On macOS, sets required environment variables and replaces current process.
    On other platforms, calls main function directly.
    """
    if platform.system() == "Darwin":  # macOS
        _launch_with_exec()
    else:
        # On non-macOS systems, call the main function directly
        from aiexec.__main__ import main as aiexec_main

        aiexec_main()


def _launch_with_exec():
    """Launch aiexec by replacing current process with properly configured environment.

    This approach is necessary because Objective-C libraries are preloaded by the Python
    runtime before any Python code executes. Setting OBJC_DISABLE_INITIALIZE_FORK_SAFETY
    within Python code is too late - it must be set in the parent process environment
    before spawning Python.

    Testing with OBJC_PRINT_INITIALIZE=YES confirms that NSCheapMutableString and
    other Objective-C classes are initialized during Python startup, before any
    user code runs. This causes fork safety issues when gunicorn or multiprocessing
    attempts to fork the process.

    The exec approach sets the environment variables and then replaces the current
    process with a new Python process. This is more efficient than subprocess since
    we don't need the launcher process to remain running, and signals are handled
    directly by the target process.
    """
    # Set environment variables before exec
    os.environ["OBJC_DISABLE_INITIALIZE_FORK_SAFETY"] = "YES"
    # Additional fix for gunicorn compatibility
    os.environ["no_proxy"] = "*"

    try:
        os.execv(sys.executable, [sys.executable, "-m", "aiexec.__main__", *sys.argv[1:]])  # noqa: S606
    except OSError as e:
        # If exec fails, we need to exit since the process replacement failed
        typer.echo(f"Failed to exec aiexec: {e}", file=sys.stderr)
        sys.exit(1)
