#!/usr/bin/python3

import os
import sys
import time
import signal
import asyncio
import threading
from pathlib import Path
from PySide6.QtWidgets import QApplication
from PySide6.QtCore import QTimer
from PySide6.QtGui import (QPalette, QColor)

SCRIPT_PATH = Path(os.path.dirname(os.path.realpath(__file__)))
sys.path.append(str(SCRIPT_PATH.absolute()))

from MessageBus import MessageBus
from PelinkWorker import PelinkWorker
from PelinkWindow import PelinkWindow
from pelink.PelinkClient import PelinkClient


_last_cwd = []
_kill = False
app = None
worker = None
pelink_window = None

def quit_application(*args, **kwargs):
    print("KILL SIGNAL RECIEVED")
    global _kill
    _kill = True
    if pelink_window:
        pelink_window.close()

def check_kill():
    global _kill
    if _kill:
        if pelink_window:
            pelink_window.close()

def push_cwd(path):
    """
    cd path
    Can be undone by pop_cwd()
    """
    global _last_cwd
    _last_cwd.append(os.getcwd())
    os.chdir(path)

def pop_cwd():
    """
    Return to the previous cwd (before calling push_cwd)
    """
    global _last_cwd
    if _last_cwd:
        path = _last_cwd.pop()
        os.chdir(path)
        return path
    return None

def install_quit_event():
    """
    Install the handlers for nicely killing main.py with:
    - CTRL+C
    - SIGINT
    - SIGTERM

    We need to set a QTimer to let the python interpreter run otherwise QT will
    just run without letting any asyncronous python code run in the main thread.

    Reference: https://stackoverflow.com/questions/4938723/what-is-the-correct-way-to-make-my-pyqt-application-quit-when-killed-from-the-co
    """
    signal.signal(signal.SIGINT, quit_application)
    signal.signal(signal.SIGTERM, quit_application)

    timer = QTimer(app)
    timer.timeout.connect(check_kill)
    timer.start(500) # Miliseconds

def run_gui(bus:MessageBus=None, on_launch=None):
    global pelink_window
    global app

    app = QApplication(sys.argv)

    install_quit_event()

    palette = app.palette()
    palette.setColor(QPalette.Highlight, QColor("#ff9800"))
    palette.setColor(QPalette.HighlightedText, QColor("#000000"))
    app.setPalette(palette)

    pelink_window = PelinkWindow(bus=bus, on_launch=on_launch)
    pelink_window.show()

    ret = app.exec()
    return ret

def main():
    global worker
    push_cwd(SCRIPT_PATH)

    bus = MessageBus()

    worker = PelinkWorker(bus)
    wthread = threading.Thread(target=worker.run, daemon=True).start()

    ret = run_gui(bus=bus, on_launch=worker.launch)
    if worker:
        worker.kill()

    pop_cwd()
    return ret

if __name__ == "__main__":
    sys.exit(main())
