# -*- 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>
#

from elisa.core.components.resource_provider import ResourceProvider
from elisa.plugins.filtered_shares.models import FilteredSharesModel
from elisa.core.resource_manager import NoMatchingResourceProvider

from elisa.core import common
from elisa.core.media_uri import MediaUri

from twisted.internet import defer, task


class FilteredSharesResource(ResourceProvider):

    supported_uri = '^network-services:///'

    filter_to_types = {'file' : ['smb', 'sftp', 'ftp', 'nfs'],
                       'audio' : ['daap',],
                       'upnp' : [# the standard urn
                                 'urn:schemas-upnp-org:serviceId:ContentDirectory',
                                 # the urn as advertised by windows media center
                                 'urn:upnp-org:serviceId:ContentDirectory',
                                 ] }

    def get(self, uri, model):
        """
        Returns a filtered list of all the known resource providers for network
        shares: C{lan://} and C{coherence://media_servers} and merges them
        corresponding to your selected filter. You will always get a
        FilteredSharesModel containing the list of services that fit your
        request.

        The filter is given as a parameter in the C{URI}. Known filters are:
        'file', 'audio' and 'upnp'. You can even request multiple ones at a time
        by comma seperate them: C{network-services:///?filter=file,audio}.
        """
        filters = uri.get_param('filter', None)
        if not filters:
            # default is everything
            filters = 'file,audio,upnp'

        filter_types = []

        for filter in filters.split(','):
            if not filter in self.filter_to_types:
                msg = "Unknown Filter '%s'" % filter
                return None, defer.fail(TypeError(msg))

            filter_types += self.filter_to_types[filter]

        model = FilteredSharesModel()
        model.filter = set(filter_types)

        dfrs =  []
        for u_uri, name in ( ('coherence://media_servers', 'media_servers'),
                             ('smb://', 'servers'),
                             ('lan://', 'services')):
            uri = MediaUri(u_uri)
            try:
                this_model, dfr = common.application.resource_manager.get(uri)
            except NoMatchingResourceProvider:
                self.warning("%s not found." % uri)
                continue

            if not this_model:
                self.warning("%s not found." % uri)
                continue
            dfr.addCallback(self._filter_list, name, model)
            dfrs.append(dfr)
        dfr = defer.DeferredList(dfrs, consumeErrors=False)
        dfr.addCallback(lambda x: model)

        return model, dfr

    def _filter_list(self, input_model, list_name, model):
        def filterer(list, model):
            for item in list:
                if item.type in model.filter:
                    model.services.append(item)
                yield item

        dfr = task.coiterate(filterer(getattr(input_model, list_name), model))
        return dfr
