#!/usr/bin/env python3

from pathlib import Path
from sys import argv, exit
from signal import SIGINT
from struct import unpack
import common

import gi
gi.require_versions({'GLib': '2.0', 'Hinawa': '3.0'})
from gi.repository import GLib, Hinawa

# Qt5 python binding
from PyQt5.QtWidgets import QApplication, QWidget, QHBoxLayout, QVBoxLayout
from PyQt5.QtWidgets import QToolButton, QGroupBox, QLineEdit, QLabel


def main() -> int:
    if len(argv) < 2:
        msg = ('One argument is required for path to special file of Linux FireWire character '
               'device')
        common.print_help_with_msg(Path(__file__).name, msg)
        return 1
    cmd, literal = argv[:2]

    try:
        path = common.detect_fw_cdev(literal)
    except Exception as e:
        common.print_help_with_msg(cmd, str(e))
        return 1

    try:
        node = Hinawa.FwNode.new()
        node.open(str(path))
        common.print_fw_node_information(node)
    except Exception as e:
        msg = str(e)
        common.print_help_with_msg(cmd, msg)
        return 1

    with common.listen_node_event(node):
        app = QApplication(argv)
        sample = Sample(app, node)
        node.connect('disconnected', lambda n, a: a.quit(), app)

        sample.show()
        app.exec()

    return 0


class Sample(QWidget):
    def __init__(self, app, node):
        super(Sample, self).__init__()

        self.node = node
        self.req = Hinawa.FwReq.new()

        self.setWindowTitle("Hinawa-3.0 gir sample")

        layout = QVBoxLayout()
        self.setLayout(layout)

        top_grp = QGroupBox(self)
        top_layout = QHBoxLayout()
        top_grp.setLayout(top_layout)
        layout.addWidget(top_grp)

        buttom_grp = QGroupBox(self)
        buttom_layout = QHBoxLayout()
        buttom_grp.setLayout(buttom_layout)
        layout.addWidget(buttom_grp)

        button = QToolButton(top_grp)
        button.setText('Read')
        top_layout.addWidget(button)
        button.clicked.connect(self.run_transaction)

        close = QToolButton(top_grp)
        close.setText('Close')
        top_layout.addWidget(close)
        close.clicked.connect(app.quit)

        self.addr = QLineEdit(buttom_grp)
        self.addr.setText('0xfffff0000980')
        buttom_layout.addWidget(self.addr)

        self.value = QLabel(buttom_grp)
        self.value.setText('00000000')
        buttom_layout.addWidget(self.value)

        # handle unix signal
        GLib.unix_signal_add(GLib.PRIORITY_HIGH, SIGINT, lambda a: a.quit(), app)

    def run_transaction(self, val):
        try:
            addr = int(self.addr.text(), 16)
            frames = [0] * 4
            frames = self.req.transaction_sync(self.node, Hinawa.FwTcode.READ_QUADLET_REQUEST,
                                               addr, 4, frames, 100)
            label = '0x{:08x}'.format(unpack('>I', frames)[0])
            self.value.setText(label)
            print(self.value.text())
        except Exception as e:
            print(e)


if __name__ == '__main__':
    exit(main())
