# encoding=utf-8
import sys
import time
import logging
from qtpy.QtWidgets import QApplication, QMainWindow
from qtpy.QtCore import QObject, Signal, QThread
from pmgwidgets import PMQThreadObject

logger = logging.getLogger(__name__)


def jedi_init():
    """
    初始化jedi，预加载相关模块
    :return:
    """
    t0 = time.time()
    import jedi
    code = """
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from numpy import *
a
    """
    script = jedi.Script(code)
    script.complete(6, 1)
    t1 = time.time()
    logger.info('time elapsed for preload autocompletion modules/s:' + str(t1 - t0))


class PMAutoCompWorker(QObject):
    signal_autocomp_parsed = Signal(list, int, int)

    def __init__(self):
        super(PMAutoCompWorker, self).__init__()
        self.quit = False
        self.code: str = ''
        self.line: int = 0
        self.col: int = 0
        self.last_code = ''
        self.last_line = ''
        self.last_col = ''
        self.path: str = ''

    def set_scan_task(self, code: str, line: int, col: int, path: str = ''):
        self.code = code
        self.line = line
        self.col = col
        self.path = path

    def is_changed(self) -> bool:
        return not (self.code == self.last_code and self.line == self.last_line and self.col == self.last_col)

    def work(self):
        """
        工作函数.

        :return:
        """
        import jedi
        try:
            jedi_init()
        except:
            pass
        while 1:
            if self.quit:
                break
            if not self.is_changed():
                QThread.msleep(50)
                continue
            else:
                script = jedi.Script(code=self.code, path=self.path)

                try:
                    line, col = self.line, self.col
                    completions = script.complete(line + 1, col + 1, fuzzy=True)
                    names = [c.name for c in completions]
                    self.signal_autocomp_parsed.emit(names, line, col)

                except ValueError as e:
                    pass
                except Exception:
                    pass
                self.last_col = self.col
                self.last_line = self.line
                self.last_code = self.code

    def on_exit(self):
        self.quit = True


class PMPythonAutocompleter(PMQThreadObject):
    def __init__(self):
        autocomp_worker = PMAutoCompWorker()
        super(PMPythonAutocompleter, self).__init__(parent=None, worker=autocomp_worker)
        self.signal_autocomp_parsed = self.worker.signal_autocomp_parsed

    def terminate(self):
        logger.warning('client quit')
        self.worker.on_exit()

        if self.thread.isRunning():
            self.thread.quit()
        self.thread.wait(500)
        logger.warning('Autocompleter quit!!')


if __name__ == '__main__':
    logger.setLevel(logging.INFO)


    class W(QMainWindow):

        def closeEvent(self, a0) -> None:
            super().closeEvent(a0)
            m.terminate()


    app = QApplication(sys.argv)
    # w = W()
    # w.show()
    logger.warning("Start print log")
    m = PMPythonAutocompleter()
    m.worker.set_scan_task('i', 0, 0, '')
    m.signal_autocomp_parsed.connect(lambda x: print(x))
    sys.exit(app.exec_())
