# -*- 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.extern.storm_wrapper import store

from twisted.trial.unittest import TestCase
from twisted.internet import task, defer

from storm.locals import create_database

from elisa.plugins.database.models import MusicAlbum, MusicTrack, Artist

class TestAudioDatabase(TestCase):
    """
    test whether the audio database storage concept works
    """

    def setUp(self):
        self.db = create_database('sqlite:')
        self.store = store.DeferredStore(self.db)

        def create_test_data():

            yield self.store.execute("CREATE TABLE music_albums" \
                           "(name VARCHAR, artist_name VARCHAR," \
                           "cover_uri VARCHAR, release_date VARCHAR)")

            yield self.store.execute("CREATE TABLE artists" \
                           "(id INTEGER PRIMARY KEY, name VARCHAR," \
                           "image_uri VARCHAR)")

            yield self.store.execute("CREATE TABLE track_artists" \
                           "(artist_id INTEGER, track_id INTEGER," \
                           " PRIMARY KEY (artist_id, track_id))")

            yield self.store.execute("CREATE TABLE music_tracks" \
                           "(title VARCHAR," \
                           "track_number INTEGER, album_id INTEGER," \
                           "file_path VARCHAR)")

            for name in ('Kill Bill', 'Gorillaz',
                        'the good, the bad and the queen',
                        'moby - best of'):
                album = MusicAlbum()
                album.name = unicode(name)
                yield self.store.add(album)


        dfr = self.store.start()
        dfr.addCallback(lambda x: task.coiterate(create_test_data()))
        return dfr

    def test_albums(self):
        x_and_y = MusicAlbum()
        x_and_y.name = u"X and Y"
        dfr = self.store.add(x_and_y)
        yield defer.waitForDeferred(dfr)

        tr1 = MusicTrack()
        tr1.title = u"Square One"
        dfr = x_and_y.tracks.add(tr1)
        yield defer.waitForDeferred(dfr)

        tr2 = MusicTrack()
        tr2.title = u"What if?"
        dfr = x_and_y.tracks.add(tr2)
        yield defer.waitForDeferred(dfr)

        del x_and_y
        del tr1
        del tr2

        def test_result(album):
            self.assertEquals(album.name, 'X and Y')

            self.assertEquals([track.title for track in album.tracks],
                [u'Square One', u'What if?'])

        dfr = self.store.find(MusicAlbum,
                MusicAlbum.name == u"X an Y").addCallback(lambda x: x.one()
                ).addCallback(test_result)

        yield defer.waitForDeferred(dfr)
    
    test_albums = defer.deferredGenerator(test_albums)

       
    def test_artist_albums(self):
        killbill = MusicAlbum()
        killbill.name = u"Kill Bill"
        dfr = self.store.add(killbill)
        yield defer.waitForDeferred(dfr)

        # set up the artists
        nancy = Artist()
        nancy.name = u"Nancy Sinatra"
        dfr = self.store.add(nancy)
        yield defer.waitForDeferred(dfr)

        bernard = Artist()
        bernard.name = u"Bernard Herrmann"
        dfr = self.store.add(bernard)
        yield defer.waitForDeferred(dfr)

        # add some tracks
        tr1 = MusicTrack()
        tr1.title = u"Bang Bang"
        tr1.track = 1
        dfr = killbill.tracks.add(tr1)
        yield defer.waitForDeferred(dfr)

        dfr = tr1.artists.add(nancy)
        yield defer.waitForDeferred(dfr)

        tr2 = MusicTrack()
        tr2.title = u"Twisted Nerve"
        tr2.track = 4
        dfr = killbill.tracks.add(tr2)
        yield defer.waitForDeferred(dfr)

        dfr = tr2.artists.add(bernard)
        yield defer.waitForDeferred(dfr)

        del nancy, bernard, tr1, tr2, killbill

        # try to get all artists for an album

        dfr = self.store.find(MusicAlbum, MusicAlbum.name == u"Kill Bill"
                ).addCallback(lambda x: x.one()).addCallback(lambda x:
                self.failUnless(x))
        yield defer.waitForDeferred(dfr)

    test_artists_albums = defer.deferredGenerator(test_artist_albums)

    def test_all_albums(self):
        return self.store.find(MusicAlbum).addCallback(lambda album: album.count()
                ).addCallback(lambda counted: self.assertEquals(counted, 4))
