# -*- coding: utf-8 -*-
# Moovida - Home multimedia server
# Copyright (C) 2006-2009 Fluendo Embedded S.L. (www.fluendo.com).
# All rights reserved.
#
# This file is available under one of two license agreements.
#
# This file is licensed under the GPL version 3.
# See "LICENSE.GPL" in the root of this distribution including a special
# exception to use Moovida with Fluendo's plugins.
#
# The GPL part of Moovida is also available under a commercial licensing
# agreement from Fluendo.
# See "LICENSE.Moovida" in the root directory of this distribution package
# for details on that license.
#
# Author: Benjamin Kampmann <benjamin@fluendo.com>

"""
D-Bus interface for media scanner control.
"""
import dbus
import dbus.service
import dbus.glib

from elisa.core.utils import defer

class ScannerIsScanningError(Exception):
    pass


def no_data_dbus_callback(result, callback):
    callback()
    return result


class DBusInterface(dbus.service.Object):
    interface = 'com.fluendo.Elisa.Plugins.Database.MediaScanner'

    def __init__(self, scanner, *args, **kw):
        dbus.service.Object.__init__(self, *args, **kw)
        self.scanner = scanner

    @dbus.service.method(dbus_interface=interface,
            async_callbacks=('callback', 'errback'))
    def stop(self, callback, errback):
        if not self.scanner.running:
            callback()
            return

        scan_stat = self.scanner.scan_stat
        queue = scan_stat.queue

        # remove the currently scanning
        currently = scan_stat.currently_scanning
        if currently is not None:
            scan_stat.scanned.append(currently)
            scan_stat.currently_scanning = None

        # clear the queue
        while not queue.empty():
            scan_stat.scanned.append(queue.get())

        # this is not nice: using an internal variable
        deferred = self.scanner._current_scan_deferred

        # stop processing
        self.scanner.running = False

        deferred.cancel()
        deferred.addBoth(no_data_dbus_callback, callback)

    @dbus.service.method(dbus_interface=interface,
            async_callbacks=('callback', 'errback'))
    def start(self, callback, errback):

        if self.scanner.running:
            return errback(ScannerIsScanningError())

        def trigger_callback(result, callback):
            callback()

        self.scanner._reset_auto_rescan(False)
        dfr = self.scanner._reschedule_scanned()
        dfr.addCallback(self.scanner._scan)
        dfr.addCallback(trigger_callback, callback)
