# Python imports
import traceback, threading, time

# Lib imports
import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk, GLib

# Application imports


def threaded(fn):
    def wrapper(*args, **kwargs):
        threading.Thread(target=fn, args=args, kwargs=kwargs, daemon=True).start()
    return wrapper


class ExceptionHookMixin:
    """ ExceptionHookMixin custom exception hook to reroute to a Gtk text area. """

    def custom_except_hook(self, exec_type, value, _traceback):
        trace     = ''.join(traceback.format_tb(_traceback))
        data      = f"Exec Type:  {exec_type}  <-->  Value:  {value}\n\n{trace}\n\n\n\n"
        start_itr = self.message_buffer.get_start_iter()
        self.message_buffer.place_cursor(start_itr)
        self.display_message(self.error, data)

    def display_message(self, type, text, seconds=None):
        self.message_buffer.insert_at_cursor(text)
        self.message_popup_widget.popup()
        if seconds:
            self.hide_message_timeout(seconds)

    @threaded
    def hide_message_timeout(self, seconds=3):
        time.sleep(seconds)
        GLib.idle_add(self.message_popup_widget.popdown)

    def save_debug_alerts(self, widget=None, eve=None):
        start_itr, end_itr   = self.message_buffer.get_bounds()
        save_location_prompt = Gtk.FileChooserDialog("Choose Save Folder", self.window, \
                                                        action  = Gtk.FileChooserAction.SAVE, \
                                                        buttons = (Gtk.STOCK_CANCEL, \
                                                                    Gtk.ResponseType.CANCEL, \
                                                                    Gtk.STOCK_SAVE, \
                                                                    Gtk.ResponseType.OK))

        text = self.message_buffer.get_text(start_itr, end_itr, False)
        resp = save_location_prompt.run()
        if (resp == Gtk.ResponseType.CANCEL) or (resp == Gtk.ResponseType.DELETE_EVENT):
            pass
        elif resp == Gtk.ResponseType.OK:
            target = save_location_prompt.get_filename();
            with open(target, "w") as f:
                f.write(text)

        save_location_prompt.destroy()


    def set_arc_buffer_text(self, widget=None, eve=None):
        sid = widget.get_active_id()
        self.arc_command_buffer.set_text(self.arc_commands[int(sid)])
