#!/usr/bin/python3

from gi.repository import GLib
from pydbus import SystemBus
import isodumper.raw_write as raw_write
import threading
import gettext
import logging

DEAMON_ORG = 'org.mageia.Magiback'
DEAMON_INTERFACE = DEAMON_ORG
ISODUMPER_INTERFACE = DEAMON_ORG + ".Isodumper"
logging.basicConfig(filename="/var/log/magiback.log",
                    format='%(asctime)s %(levelname)-8s %(message)s',
                    level=logging.DEBUG)

class Isodumper(raw_write.Dumper):
    """
		<node>
			<interface name='org.mageia.Magiback.Isodumper'>
				<method name='do_write'>
					<arg type='s' name='source' direction='in'/>
					<arg type='s' name='target' direction='in'/>
					<arg type='x' name='size' direction='in'/>
				</method>
				<method name='do_format'>
					<arg type='s' name='device' direction='in'/>
					<arg type='s' name='format' direction='in'/>
					<arg type='b' name='success' direction='out'/>
					<arg type='s' name='message' direction='out'/>
				</method>
				<method name='check_write'>
					<arg type='s' name='target' direction='in'/>
					<arg type='s' name='source' direction='in'/>
				</method>
				<method name='do_persistence'>
					<arg type='s' name='target' direction='in'/>
					<arg type='s' name='label' direction='in'/>
					<arg type='s' name='key' direction='in'/>
				</method>
				<method name='get_sum'>
					<arg type='s' name='source' direction='in'/>
				</method>
				<method name='end'>
					<arg type='b' name='success' direction='out'/>
					<arg type='s' name='message' direction='out'/>
				</method>
                <property name="done" type="b" access="read"/>
                <property name="progress" type="i" access="read"/>
                <property name="message" type="s" access="read"/>
                <property name="state" type="b" access="read"/>
			</interface>
		</node>
    """
    def __init__(self):
        super().__init__()
        APP = "isodumper"
        DIR = "/usr/share/locale"
        # Call translation catalog
        gettext.install(APP, localedir=DIR,)
        self.finished = threading.Event()
        # finished is cleared at start of operation, and set at the end
        self.finished.clear()
        self._progress = 0
        self.loop = GLib.MainLoop()
        self.return_state = False
        self.return_message = ""
        self.authorized_sender_read = set()
        self.authorized_sender_write = set()
        self.sum_check = ""
        self.sum_check_searched = False
        self.signature_checked = False
        self.writing_perm = False
        self.writing_target = ""

    def do_write(self, source, target, size, dbus_context):
        self.finished.clear()
        if check_permission('org.mageia.Magiback.Isodumper.write', dbus_context):
            self.thread = threading.Thread(target=self._do_write, args=(source, target, size, ))
            self.thread.start()
            logging.debug("Writing thread started")
            self.writing_perm = True
            self.writing_target = target
        else:
            self.return_message = "Writing: Access denied"
            logging.debug(self.return_message)
            self.finished.set()

    def do_persistence(self, target, label, key):
        self.finished.clear()
        if self.writing_perm and self.writing_target == target:
            self.thread = threading.Thread(target=self._do_persistence, args=(target, label, key))
            self.thread.start()
            logging.debug("Persistence thread started")
        else:
            self.return_message = "Persistence: Access denied"
            self.finished.set()
        self.writing_perm = False
        self.writing_target = ""

    @property
    def done(self):
        return self.finished.wait(1)

    @property
    def message(self):
        return self.return_message

    @property
    def state(self):
        return self.return_state

    def end(self):
        if hasattr(self, 'thread'):
            self.thread.join()
        self._progress = 0
        self.finished.clear()
        return self.return_state, self.return_message

    @property
    def progress(self):
        return self._progress

    def get_sum(self, source):
        self.key_thread = threading.Thread(target=self._get_sum, args=(source,))
        self.key_thread.start()

    def check_write(self, target, source):
        if hasattr(self, 'key_thread'):
            self.key_thread.join()
        self.thread = threading.Thread(target=self._check_write, args=(target, source,))
        self.thread.start()

    def run(self):
        self.loop.run()


def check_permission(action, dbus_context):
    """ Check permission
    """
    return dbus_context.is_authorized(action, {'polkit.icon_name': 'isodumper.png', }, interactive=True)


class ConfFile(object):
    """
		<node>
			<interface name='org.mageia.Magiback'>
				<method name='setName'>
					<arg type='s' name='a' direction='in'/>
				</method>
				<method name='getFile'>
					<arg type='s' name='content' direction='out'/>
				</method>
				<method name='saveFile'>
					<arg type='s' name='content' direction='in'/>
				</method>
			</interface>
		</node>
    """
    def __init__(self):
        super().__init__()

    def setName(self, file_name):
        self.file_name = file_name

    def getFile(self):
        with open(self.file_name, 'r') as tcf:
            # read the file
            content=""
            while 1:
                line = tcf.readline()
                if not line:
                    break
                content += line
        return content

    def saveFile(self, tc, dbus_context):
        if check_permission('org.mageia.Magiback.write', dbus_context):
            try:
                with open(self.file_name, 'w') as tcf:
                    tcf.write(tc)
            except:
                return False
            return True


if __name__ == '__main__':
    print("Running Magiback service.")
    bus = SystemBus()
    conf_file = ConfFile()
    bus.publish(DEAMON_ORG, conf_file, ("Isodumper", Isodumper()))
    loop = GLib.MainLoop()
    loop.run()
    logging.shutdown()