# coding=utf-8
import os
import sys
import logging

from qgis.PyQt.QtWidgets import QWidget
from qgis.analysis import QgsNativeAlgorithms
from qgis.utils import iface
import atexit

LOGGER = logging.getLogger('QGIS')
QGIS_APP = None  # Static variable used to hold hand to running QGIS app
CANVAS = None
PARENT = None
IFACE = None


def get_qgis_app(cleanup=True):
    """ Start one QGIS application to test against.

    :returns: Handle to QGIS app, canvas, iface and parent. If there are any
        errors the tuple members will be returned as None.
    :rtype: (QgsApplication, CANVAS, IFACE, PARENT)

    If QGIS is already running the handle to that app will be returned.
    """

    try:
        from qgis.PyQt import QtGui, QtCore
        from qgis.core import QgsApplication
        from qgis.gui import QgsMapCanvas
        from .qgis_interface import QgisInterface
    except ImportError:
        return None, None, None, None

    global QGIS_APP, PARENT, IFACE, CANVAS  # pylint: disable=W0603

    if iface:
        QGIS_APP = QgsApplication
        CANVAS = iface.mapCanvas()
        PARENT = iface.mainWindow()
        IFACE = iface
        return QGIS_APP, CANVAS, IFACE, PARENT

    global QGISAPP

    try:
        QGISAPP
    except NameError:
        print("Name error")
        myGuiFlag = True  # All test will run qgis in gui mode

        # In python3 we need to convert to a bytes object (or should
        # QgsApplication accept a QString instead of const char* ?)
        try:
            argvb = list(map(os.fsencode, sys.argv))
        except AttributeError:
            argvb = sys.argv

        # Note: QGIS_PREFIX_PATH is evaluated in QgsApplication -
        # no need to mess with it here.
        QGISAPP = QgsApplication(argvb, myGuiFlag)

        QGISAPP.initQgis()

        # Import and initialize processing
        processing_path = os.path.join(QGISAPP.prefixPath(), 'python', 'plugins')
        sys.path.append(processing_path)
        from processing.core.Processing import Processing  # Processing plugin located inside processing_path
        QGISAPP.processingRegistry().addProvider(QgsNativeAlgorithms())

        s = QGISAPP.showSettings()
        LOGGER.debug(s)

        def debug_log_message(message, tag, level):
            """
            Prints a debug message to a log
            :param message: message to print
            :param tag: log tag
            :param level: log message level (severity)
            :return:
            """
            print(f'{tag}({level}): {message}')

        QgsApplication.instance().messageLog().messageReceived.connect(
            debug_log_message)

        if cleanup:
            @atexit.register
            def exitQgis():  # pylint: disable=unused-variable
                """
                Gracefully closes the QgsApplication instance
                """
                try:
                    QGISAPP.exitQgis()  # pylint: disable=used-before-assignment
                    QGISAPP = None  # pylint: disable=redefined-outer-name
                except NameError:
                    pass


    """if QGIS_APP is None:
        gui_flag = False  # All test will run qgis in gui mode
        #noinspection PyPep8Naming
        argv_bytes = list(map(lambda x: bytes(x, 'utf-8'), sys.argv))
        QGIS_APP = QgsApplication(argv_bytes, gui_flag)
        # Make sure QGIS_PREFIX_PATH is set in your env if needed!
        QGIS_APP.initQgis()
        s = QGIS_APP.showSettings()

        LOGGER.debug(s)"""

    if PARENT is None:
        #noinspection PyPep8Naming
        PARENT = QWidget()

    if CANVAS is None:
        #noinspection PyPep8Naming
        CANVAS = QgsMapCanvas(PARENT)
        CANVAS.resize(QtCore.QSize(400, 400))

    if IFACE is None:
        # QgisInterface is a stub implementation of the QGIS plugin interface
        #noinspection PyPep8Naming
        IFACE = QgisInterface(CANVAS)

    return QGISAPP, CANVAS, IFACE, PARENT
    # return QGIS_APP, CANVAS, IFACE, PARENT
