#!/usr/bin/python3 -u
# -*- coding: utf-8 -*-

## Copyright (C) 2014 troubadour <trobador@riseup.net>
## Copyright (C) 2014 - 2023 ENCRYPTED SUPPORT LP <adrelanos@whonix.org>

"""
This script creates a GUI message dialog using PyQt5. It allows the user to specify
the type of message, title, and content, as well as customize the icon and position of the dialog.

Usage:
/usr/libexec/msgcollector/msgdispatcher_dispatch_x <message_type> <title> <message> <position> [icon]

Arguments:
1. message_type: 'info', 'warning', or 'error'
2. title: The window title
3. message: The main message text
4. position: The position of the dialog (e.g., "1" for top-left corner)
5. icon (optional): Path to a custom icon (defaults to a specific icon if not provided)

Example:
/usr/libexec/msgcollector/msgdispatcher_dispatch_x warning "Warning Title" "This is a warning message." "1" "/path/to/custom/icon.svg"
"""

import os
import sys
import signal
import argparse
from PyQt5.QtGui import QIcon, QPixmap
from PyQt5 import QtCore, QtGui, QtWidgets

def signal_handler(sig, frame):
    sys.exit(128 + sig)

class Ui_Dialog(object):
    def setupUi(self, Dialog, args):
        self.Dialog = Dialog
        self.title = args.title
        self.msg = args.message
        self.icon = args.icon
        self.pos = args.position

        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
        sizePolicy.setHeightForWidth(Dialog.sizePolicy().hasHeightForWidth())
        Dialog.setSizePolicy(sizePolicy)
        Dialog.setWindowIcon(QIcon(self.icon))
        if self.pos == "1":
            Dialog.move(0, 0)

        self.gridLayout = QtWidgets.QGridLayout(Dialog)

        self.Info_Icon = QtWidgets.QLabel(Dialog)
        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Preferred)
        sizePolicy.setHeightForWidth(self.Info_Icon.sizePolicy().hasHeightForWidth())
        self.Info_Icon.setSizePolicy(sizePolicy)

        image = QtGui.QImage(args.itype)
        self.Info_Icon.setPixmap(QPixmap.fromImage(image))
        self.Info_Icon.setAlignment(QtCore.Qt.AlignLeading | QtCore.Qt.AlignLeft | QtCore.Qt.AlignTop)
        self.gridLayout.addWidget(self.Info_Icon, 0, 0, 1, 1)

        self.Message = QtWidgets.QTextBrowser(Dialog)
        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
        sizePolicy.setHeightForWidth(self.Message.sizePolicy().hasHeightForWidth())
        self.Message.setSizePolicy(sizePolicy)
        self.Message.setMinimumSize(QtCore.QSize(715, 0))
        self.Message.setFrameShape(QtWidgets.QFrame.StyledPanel)
        palette = QtGui.QPalette()
        brush = QtGui.QBrush(QtGui.QColor(255, 255, 255, 0))
        brush.setStyle(QtCore.Qt.SolidPattern)
        palette.setBrush(QtGui.QPalette.Active, QtGui.QPalette.Base, brush)
        brush = QtGui.QBrush(QtGui.QColor(255, 255, 255, 0))
        brush.setStyle(QtCore.Qt.SolidPattern)
        palette.setBrush(QtGui.QPalette.Inactive, QtGui.QPalette.Base, brush)
        brush = QtGui.QBrush(QtGui.QColor(244, 244, 244))
        brush.setStyle(QtCore.Qt.SolidPattern)
        palette.setBrush(QtGui.QPalette.Disabled, QtGui.QPalette.Base, brush)
        self.Message.setPalette(palette)
        self.Message.setTextInteractionFlags(QtCore.Qt.LinksAccessibleByMouse | QtCore.Qt.TextSelectableByMouse)
        self.Message.setOpenExternalLinks(True)
        self.Message.setFrameShape(QtWidgets.QFrame.NoFrame)
        self.gridLayout.addWidget(self.Message, 0, 1, 1, 2)

        self.buttonBox = QtWidgets.QDialogButtonBox(Dialog)
        self.buttonBox.setOrientation(QtCore.Qt.Horizontal)
        self.buttonBox.setStandardButtons(QtWidgets.QDialogButtonBox.Ok)
        self.gridLayout.addWidget(self.buttonBox, 1, 1, 1, 1)

        self.retranslateUi(Dialog)
        self.buttonBox.accepted.connect(Dialog.accept)
        self.buttonBox.rejected.connect(Dialog.reject)
        QtCore.QMetaObject.connectSlotsByName(Dialog)

    def retranslateUi(self, Dialog):
        Dialog.setWindowTitle(self.title)
        self.Message.setHtml(self.msg)
        QtCore.QTimer.singleShot(0, self.setSize)

    def setSize(self):
        messageHeight = int(self.Message.document().size().height())
        maximumHeight = int(QtWidgets.QDesktopWidget().availableGeometry().height() - 25)
        if messageHeight <= maximumHeight:
            self.Dialog.resize(830, messageHeight + 55)
            self.center()
        else:
            self.Dialog.resize(830, maximumHeight)
            self.center()

    def center(self):
        frameGm = self.Dialog.frameGeometry()
        centerPoint = QtWidgets.QDesktopWidget().availableGeometry().center()
        frameGm.moveCenter(centerPoint)
        self.Dialog.move(frameGm.topLeft())

def main():
    parser = argparse.ArgumentParser(description="Create a GUI message dialog using PyQt5.")
    parser.add_argument('message_type', choices=['info', 'warning', 'error'], help="Type of the message ('info', 'warning', or 'error')")
    parser.add_argument('title', help="The window title")
    parser.add_argument('message', help="The main message text")
    parser.add_argument('position', help="The position of the dialog (e.g., '1' for top-left corner)")
    parser.add_argument('icon', nargs='?', default="/usr/share/icons/gnome/24x24/status/info.png", help="Path to a custom icon (optional)")

    args = parser.parse_args()

    idir = "/usr/share/icons/gnome-colors-common/scalable/status/"
    if args.message_type == "info":
        args.itype = os.path.join(idir, "dialog-information.svg")
    elif args.message_type == "warning":
        args.itype = os.path.join(idir, "dialog-warning.svg")
    elif args.message_type == "error":
        args.itype = os.path.join(idir, "dialog-error.svg")
    else:
        sys.exit("Information type not recognized: {}".format(args.message_type))

    if not os.path.exists(args.itype):
        print(f"INFO: The icon path '{args.itype}' does not exist.", file=sys.stderr)

    app = QtWidgets.QApplication(sys.argv)
    Dialog = QtWidgets.QDialog()

    ui = Ui_Dialog()
    ui.setupUi(Dialog, args)
    Dialog.show()

    signal.signal(signal.SIGINT, signal_handler)
    signal.signal(signal.SIGTERM, signal_handler)

    timer = QtCore.QTimer()
    timer.start(500)
    timer.timeout.connect(lambda: None)

    app.exec_()

if __name__ == '__main__':
    main()
