# -*- coding: utf-8 -*-
# Elisa - Home multimedia server
# Copyright (C) 2007-2008 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 Elisa with Fluendo's plugins.
#
# The GPL part of Elisa is also available under a commercial licensing
# agreement from Fluendo.
# See "LICENSE.Elisa" in the root directory of this distribution package
# for details on that license.

from elisa.core.tests.test_media_provider import TestMediaProvider
from elisa.core.media_uri import MediaUri
from elisa.core.component import Component, InitializeFailure
from elisa.extern.natural_sort import natcasecmp
import gst
from twisted.internet import defer

from elisa.core.tests.elisa_test_case import BoilerPlateApp, DEFAULT_CONFIG, MAPPINGS
from elisa.core import common

try:
    common.set_application(BoilerPlateApp(DEFAULT_CONFIG,
                                        load_all_plugins=True))
    from elisa.plugins.daap_plugin.daap_media import DaapSource, DaapMedia
    skip_test = False
except ImportError, x:
    # we don't have the dependencies to test this
    skip_test = str(x)
    class DaapMedia(Component):
        def _get_library(*args, **kw):
            pass

        def _build_library(*args, **kw):
            pass

class TestDaapTrack(object):
    def __init__(self, artist, album, track_id, track_name):
        self.artist = artist
        self.album = album
        self.id = track_id
        self.name = track_name

class TestDaapMediaProvider(DaapMedia):
    def __init__(self, *args, **kw):
        super(TestDaapMediaProvider, self).__init__(*args, **kw)

        self.n_artists = 10
        self.n_albums_per_artist = 2
        self.n_tracks_per_album = 10

        # create the tracks, put artists and tracks in reverse to check that
        # natural sorting works in the provider
        self._tracks = []
        for x in range(self.n_artists, 0, -1):
            for y in range(self.n_albums_per_artist):
                for z in range(self.n_tracks_per_album, 0, -1):
                    artist = unicode('artist-%d' % x, 'utf-8')
                    album = 'album-%d' % y
                    track_name = 'artist-%d-album-%d-track-name-%d' % (x, y, z)
                    self._tracks.append(TestDaapTrack(artist, album, z, track_name))

    def _initialize_avahi(self):
        # override this so we don't need a daap server to test the media
        # provider
        pass

    def _retrieve_library(self, uri):
        # get our test library
        return self._tracks

class TestDaapMedia(TestMediaProvider):
    component_class = TestDaapMediaProvider

    if skip_test:
        skip = skip_test

    def get_valid_uris(self):
        return [MediaUri("daap:///")]

    def test_uri(self):
        uri = 'daap://ciao'
        src = gst.element_make_from_uri(gst.URI_SRC, uri)
        self.failUnless(type(src) == DaapSource)
        self.failUnlessEquals(src.get_uri(), uri)

        uri = 'daap://miao'
        self.failUnless(src.set_uri(uri))
        self.failUnlessEquals(src.get_uri(), uri)

        uri = 'ciao://bao'
        self.failUnlessFalse(src.set_uri(uri))

    def test_is_directory(self):
        uri = MediaUri('daap://ciao')
        track = MediaUri('daap://ciao?artist=asd&album=asd&id=1')

        def expected(result, expected_result):
            self.failIf(result != expected_result)
        
        d1 = self.component.is_directory(uri)
        d1.addCallback(expected, True)
        
        d2 = self.component.is_directory(track)
        d2.addCallback(expected, False)

        return defer.DeferredList([d1, d2])

    def test_get_direct_children(self):
        # get the artists
        d1 = self.component.get_direct_children(MediaUri('daap://host:1234'),
                                                [])
        d1.addCallback(lambda c: self.failIf(len(c)!= self.component.n_artists))

        # get the albums of the first artist
        artist_uri = MediaUri("daap://host:1234/?artist=artist-1")
        albums = []
        d2 = self.component.get_direct_children(artist_uri, albums)
        d2.addCallback(lambda a: self.failIf(len(a) != self.component.n_albums_per_artist))

        # get the tracks in the first album of the first artist
        album_uri = MediaUri("daap://host:1234/?album=album-0&artist=artist-1")
        tracks = []
        d3 = self.component.get_direct_children(album_uri, tracks)
        d3.addCallback(lambda t: self.failIf(len(t) != self.component.n_tracks_per_album))
        
        # tracks have no children
        track_uri = MediaUri("daap://host:1234/?album=album-0&track=artist-1-album-0-track-name-1&id=1&artist=artist-1")
        empty = []
        d4 = self.component.get_direct_children(track_uri, empty)
        d4.addCallback(lambda e: self.failIf(len(e) != 0))

        return defer.DeferredList([d1, d2, d3, d4])
    
    def test_has_children_with_types(self):

        def expect(result, expected_result):
            self.failIf(result != expected_result)
        
        types = ['audio', 'video']
        uri = MediaUri('daap://host:1234')
        d1 = self.component.has_children_with_types(uri, types)
        d1.addCallback(expect, True)
    
        types = ['directory', 'video']
        d2 = self.component.has_children_with_types(uri, types)
        d2.addCallback(expect, True)

        types = ['video']
        d3 = self.component.has_children_with_types(uri, types)
        d3.addCallback(expect, False)
        
        uri = MediaUri('daap://host:1234?id=something')
        types = ['audio']
        d4 = self.component.has_children_with_types(uri, types)
        d4.addCallback(expect, False)
        
        return defer.DeferredList([d1, d2, d3, d4])
    
