# -*- coding: utf-8 -*-
import multiprocessing
import threading

from pybind11_tests import gil_scoped as m


def _run_in_process(target, *args, **kwargs):
    """Runs target in process and returns its exitcode after 10s (None if still alive)."""
    process = multiprocessing.Process(target=target, args=args, kwargs=kwargs)
    process.daemon = True
    try:
        process.start()
        # Do not need to wait much, 10s should be more than enough.
        process.join(timeout=10)
        return process.exitcode
    finally:
        if process.is_alive():
            process.terminate()


def _python_to_cpp_to_python():
    """Calls different C++ functions that come back to Python."""

    class ExtendedVirtClass(m.VirtClass):
        def virtual_func(self):
            pass

        def pure_virtual_func(self):
            pass

    extended = ExtendedVirtClass()
    m.test_callback_py_obj(lambda: None)
    m.test_callback_std_func(lambda: None)
    m.test_callback_virtual_func(extended)
    m.test_callback_pure_virtual_func(extended)


def _python_to_cpp_to_python_from_threads(num_threads, parallel=False):
    """Calls different C++ functions that come back to Python, from Python threads."""
    threads = []
    for _ in range(num_threads):
        thread = threading.Thread(target=_python_to_cpp_to_python)
        thread.daemon = True
        thread.start()
        if parallel:
            threads.append(thread)
        else:
            thread.join()
    for thread in threads:
        thread.join()


# TODO: FIXME, sometimes returns -11 (segfault) instead of 0 on macOS Python 3.9
def test_python_to_cpp_to_python_from_thread():
    """Makes sure there is no GIL deadlock when running in a thread.

    It runs in a separate process to be able to stop and assert if it deadlocks.
    """
    assert _run_in_process(_python_to_cpp_to_python_from_threads, 1) == 0


# TODO: FIXME on macOS Python 3.9
def test_python_to_cpp_to_python_from_thread_multiple_parallel():
    """Makes sure there is no GIL deadlock when running in a thread multiple times in parallel.

    It runs in a separate process to be able to stop and assert if it deadlocks.
    """
    assert _run_in_process(_python_to_cpp_to_python_from_threads, 8, parallel=True) == 0


# TODO: FIXME on macOS Python 3.9
def test_python_to_cpp_to_python_from_thread_multiple_sequential():
    """Makes sure there is no GIL deadlock when running in a thread multiple times sequentially.

    It runs in a separate process to be able to stop and assert if it deadlocks.
    """
    assert (
        _run_in_process(_python_to_cpp_to_python_from_threads, 8, parallel=False) == 0
    )


# TODO: FIXME on macOS Python 3.9
def test_python_to_cpp_to_python_from_process():
    """Makes sure there is no GIL deadlock when using processes.

    This test is for completion, but it was never an issue.
    """
    assert _run_in_process(_python_to_cpp_to_python) == 0


def test_cross_module_gil():
    """Makes sure that the GIL can be acquired by another module from a GIL-released state."""
    m.test_cross_module_gil()  # Should not raise a SIGSEGV
