# -*- coding: utf-8 -*-
# Moovida - Home multimedia server
# Copyright (C) 2007-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: Philippe Normand <philippe@fluendo.com>

"""
Functional tests for thetvdb.com resource provider.
"""

from twisted.trial.unittest import TestCase
from elisa.core.utils.misc import run_functional_tests_check
from twisted.internet import defer

from elisa.core.components.resource_provider import ResourceNotFound

from elisa.plugins.thetvdb.resource_provider import TheTvDBResourceProvider
from elisa.plugins.thetvdb.constants import *
from elisa.plugins.thetvdb.utils import get_series_lookup_url
from elisa.plugins.thetvdb import models
from elisa.plugins.base.models.media import RawDataModel

from elisa.core.media_uri import MediaUri

class TestTheTvDBResourceProvider(TestCase):

    """
    This test case tests the TheTvDBResourceProvider class.
    """

    def setUp(self):
        run_functional_tests_check()
        def created(provider):
            self.provider = provider
            return provider.initialize()

        create_dfr = TheTvDBResourceProvider.create({}).addCallback(created)
        return create_dfr

    def tearDown(self):
        return self.provider.clean()

    def test_get_wrong_uri(self):
        """
        Test trying to get a unexisting URI.
        """
        uri = 'http://%s/idontexist' % API_SERVER
        result_model, request_defer = self.provider.get(MediaUri(uri))
        self.failUnlessFailure(request_defer, ResourceNotFound)
        return request_defer

    def test_get_wrong_api_method(self):
        """
        Test trying to get an unknown method of the API
        """
        uri = 'http://%s/api/idontexist' % API_SERVER
        result_model, request_defer = self.provider.get(MediaUri(uri))
        self.failUnlessFailure(request_defer, ResourceNotFound)
        return request_defer

    def _search_lost(self):
        # I love that tv show. so much.
        uri = get_series_lookup_url('lost')
        result_model, request_defer = self.provider.get(uri)
        return request_defer

    def test_search(self):
        """
        Test a simple API call.
        """
        def request_done(result_model):
            self.failUnless(isinstance(result_model, models.TvSeriesListModel))
            self.failUnless(reduce(lambda x, y: x and \
                                   isinstance(y, models.TvSeriesModel),
                                   result_model.series))
            return result_model

        dfr = self._search_lost()
        dfr.addCallback(request_done)
        return dfr

    def test_get_info(self):
        """
        Test a getInfo API call.
        """
        def got_info(info):
            self.failUnless(info.runtime is not None)

        def request_done(result_model):
            first_match = result_model.series[0]
            self.failIf(first_match.runtime is not None)
            model, dfr = self.provider.get(first_match.extended_infos_url('en'),
                                           first_match)
            dfr.addCallback(got_info)
            return dfr

        dfr = self._search_lost()
        dfr.addCallback(request_done)
        return dfr

    def test_seasons_retrieval(self):
        """
        Test the retrieval of a tv show seasons list
        """

        def got_seasons(seasons_model):
            self.failUnless(isinstance(seasons_model,
                                       models.TvSeasonsListModel))

            first_season = seasons_model.seasons[1]
            self.failUnless(isinstance(first_season,
                                       models.TvSeasonModel))
            self.assertEquals(first_season.tvshow_name, u'Lost')

            first_episode = first_season.episodes[0]
            self.failUnless(isinstance(first_episode,
                                       models.TvEpisodeModel))
            self.assertEquals(first_episode.season_number, 1)
            self.assertEquals(first_episode.episode_number, 1)

        def request_done(result_model):
            first = result_model.series[0]
            result_model = models.TvSeasonsListModel()
            model, dfr = self.provider.get(first.all_episodes_url('en'),
                                           result_model)
            dfr.addCallback(got_seasons)
            return dfr

        dfr = self._search_lost()
        dfr.addCallback(request_done)
        return dfr

    def test_episode_retrieval(self):
        """
        Test the retrieval of a tv show episode
        """

        def got_episode(model):
            self.failUnless(isinstance(model, models.TvEpisodeModel))
            self.failUnless(model.name)

        def got_show(show_model):
            model, dfr = self.provider.get(show_model.episode_url(2, 3, 'en'),
                                           models.TvEpisodeModel())
            dfr.addCallback(got_episode)
            return dfr

        def request_done(result_model):
            first = result_model.series[0]
            model, dfr = self.provider.get(first.extended_infos_url('en'),
                                           first)
            dfr.addCallback(got_show)
            return dfr

        dfr = self._search_lost()
        dfr.addCallback(request_done)
        return dfr


    def test_picture_retrieval(self):
        """
        Test the retrieval of a tv show poster
        """
        def got_poster(poster):
            self.failUnless(isinstance(poster, RawDataModel))
            self.failUnless(poster.size > 0)

        def got_show(show_model):
            model, dfr = self.provider.get(show_model.poster_url)
            dfr.addCallback(got_poster)
            return dfr

        def request_done(result_model):
            first = result_model.series[0]
            model, dfr = self.provider.get(first.extended_infos_url('en'),
                                           first)
            dfr.addCallback(got_show)
            return dfr

        dfr = self._search_lost()
        dfr.addCallback(request_done)
        return dfr


    def test_seasons_banners_retrieval(self):
        """
        Test the retrieval of a tv show season banners
        """

        def got_banners(model):
            self.failUnless(model.season_banners)

        def request_done(result_model):
            first = result_model.series[0]
            model, dfr = self.provider.get(first.season_banners_url,
                                           first)
            dfr.addCallback(got_banners)
            return dfr

        dfr = self._search_lost()
        dfr.addCallback(request_done)
        return dfr
