import threading, gi
from typing import Callable
from os import path

gi.require_version('Gtk', '3.0')

from gi.repository import Gtk, GLib

OnSuccessFunction = Callable[[], None]
OnErrorFunction = Callable[[str], None]

GET_TEXT_DOMAIN="domainjoin"

def get_locale_dir():
    if path.exists(path.join('po', 'locale')):
        return path.join('po', 'locale')
    elif path.exists('/usr/local/share/locale'):
        return '/usr/local/share/locale'
    return '/usr/share/locale'

def get_ui_file_path(f):
    if path.exists(path.join('data', f)):
        return path.join('data', f)
    elif path.exists(path.join('/usr/local/share/domain-join', f)):
        return path.join('/usr/local/share/domain-join', f)
    elif path.exists(path.join('/usr/share/domain-join', f)):
        return path.join('/usr/share/domain-join', f)


def create_builder(ui_file):
    if path.exists(ui_file):
        builder = Gtk.Builder()
        builder.set_translation_domain(GET_TEXT_DOMAIN)
        builder.add_from_file(ui_file)

        return builder
    raise Exception('File %s not found' % ui_file)


def show_error_dialog(error):
    error_dialog = Gtk.MessageDialog(self, Gtk.DialogFlags.DESTROY_WITH_PARENT, Gtk.MessageType.ERROR, Gtk.ButtonsType.OK, error)
    error_dialog.run()
    error_dialog.destroy()


def call_async(sync_function):
    def _real_decorator(async_func):
        def _inner_func(*args, **kwargs):
            on_success_func = kwargs['on_success']
            on_error_func = kwargs['on_error']
            def _internal_thread(*args, **kwargs):
                result = sync_function(*args, **kwargs)
                if result['exit_code'] == 0:
                    GLib.idle_add(lambda: on_success_func())
                else:
                    GLib.idle_add(lambda: on_error_func(result['error']))
            thread = threading.Thread(target=_internal_thread, args=args)
            thread.daemon = True
            thread.start()
            async_func(*args, **kwargs)
        return _inner_func
    return _real_decorator
