import pytest

from pytestqt.exceptions import (
    _is_exception_capture_enabled,
    _QtExceptionCaptureManager,
)
from pytestqt.logging import QtLoggingPlugin, _QtMessageCapture
from pytestqt.qt_compat import qt_api
from pytestqt.qtbot import QtBot, _close_widgets


@pytest.fixture(scope="session")
def qapp_args():
    """
    Fixture that provides QApplication arguments to use.

    You can override this fixture to pass different arguments to
    ``QApplication``:

    .. code-block:: python

       @pytest.fixture(scope="session")
       def qapp_args():
           return ["--arg"]
    """
    return []


@pytest.fixture(scope="session")
def qapp(qapp_args, pytestconfig):
    """
    Fixture that instantiates the QApplication instance that will be used by
    the tests.

    You can use the ``qapp`` fixture in tests which require a ``QApplication``
    to run, but where you don't need full ``qtbot`` functionality.
    """
    app = qt_api.QtWidgets.QApplication.instance()
    if app is None:
        global _qapp_instance
        _qapp_instance = qt_api.QtWidgets.QApplication(qapp_args)
        name = pytestconfig.getini("qt_qapp_name")
        _qapp_instance.setApplicationName(name)
        return _qapp_instance
    else:
        return app  # pragma: no cover


# holds a global QApplication instance created in the qapp fixture; keeping
# this reference alive avoids it being garbage collected too early
_qapp_instance = None


@pytest.fixture
def qtbot(qapp, request):
    """
    Fixture used to create a QtBot instance for using during testing.

    Make sure to call addWidget for each top-level widget you create to ensure
    that they are properly closed after the test ends.
    """
    result = QtBot(request)
    return result


@pytest.fixture
def qtlog(request):
    """Fixture that can access messages captured during testing"""
    if hasattr(request._pyfuncitem, "qt_log_capture"):
        return request._pyfuncitem.qt_log_capture
    else:
        return _QtMessageCapture([])  # pragma: no cover