#!/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', 'Gtk': '4.0'})
from gi.repository import GLib, Hinawa, Gtk


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):
        main_dispatcher = GLib.MainLoop.new(None, False)
        node.connect('disconnected', lambda n, d: d.quit(), main_dispatcher)

        win = Sample(main_dispatcher, node)
        win.present()

        main_dispatcher.run()

    return 0


class Sample(Gtk.Window):
    def __init__(self, dispatcher, node):
        Gtk.Window.__init__(self, title="Hinawa-3.0 gir sample")

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

        grid = Gtk.Grid(row_spacing=10, row_homogeneous=True,
                        column_spacing=10, column_homogeneous=True,
                        margin_start=20, margin_end=20, margin_top=20,
                        margin_bottom=20)
        self.set_child(grid)

        button = Gtk.Button(label="Read")
        button.connect("clicked", self.run_transaction)
        grid.attach(button, 0, 0, 1, 1)

        button = Gtk.Button(label="_Close", use_underline=True)
        button.connect("clicked", lambda s, d: d.quit(), dispatcher)
        grid.attach(button, 1, 0, 1, 1)

        self.entry = Gtk.Entry()
        self.entry.set_text("0xfffff0000980")
        grid.attach(self.entry, 0, 1, 1, 1)

        self.label = Gtk.Label(label="result")
        self.label.set_text("0x00000000")
        grid.attach(self.label, 1, 1, 1, 1)

        # handle unix signal
        GLib.unix_signal_add(GLib.PRIORITY_HIGH, SIGINT, lambda d: d.quit(), dispatcher)

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


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