# -*- 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 twisted.trial.unittest import SkipTest
from twisted.internet import task

from elisa.core.media_uri import MediaUri

import re, platform

from elisa.plugins.base.models.media import PlayableModel

class GenericSetup(object):
    
    # set a configuration for testing
    config = {}

    # set the class you want to set up
    resource_class = None

    def setUp(self):
        klass = self.resource_class
        if klass is None:
            raise SkipTest("Not supported on %s platform" % platform.system()) 

        def setup_done(resource):
            self.resource = resource

        return klass.create(self.config).addCallback(setup_done)

    def tearDown(self):
        if self.resource:
            return self.resource.clean()


class UriRegExpTester(object):

    # set a list of uris that have to work
    working_uris = [] # of unicode

    # set a list of uris that have to 
    failing_uris = [] # of unicode

    def test_working_uris(self):
        """
        test that the uri expression matches the given working uris
        """
        if not len(self.working_uris):
            raise SkipTest("No working uris specified.")

        for uri in self.working_uris:
            msg = "Failed to match '%s'" % uri
            self.failUnless(re.match(self.resource_class.supported_uri, uri), msg)

    def test_compile_regexp(self):
        """
        test that the uri expression can be compiled
        """
        compiled = re.compile(self.resource_class.supported_uri)

    def test_failing_uris(self):
        """
        test that the uri expression does not match the given failing uris
        """
        if not self.failing_uris:
            raise SkipTest("No working uris specified.")

        for uri in self.failing_uris:
            msg = "'%s' matched" % uri
            self.failUnless(re.match(self.resource_class.supported_uri, uri) \
                    is None, msg)


class PlayableUriTester(object):
    
    # list of tuple: (ContextModel, expected_playable_uri_as_unicode), filled
    # for example in setUpClass
    playable_uris = []

    def test_playable_uris(self):
        """
        test that we receive playable models and that they contain the expected
        playable uri
        """

        def got_model(model, expected_uri):
            self.failUnless(isinstance(model, PlayableModel),
                    "%r is not a PlayableModel" % model)
            self.assertEquals(unicode(model.uri), expected_uri)
            self.failUnless(isinstance(model.uri, MediaUri), "Uri is no MediaUri")

        if not self.playable_uris:
            raise SkipTest('No playable uris defined')
        
        def run_test():
            for model, expected_uri in self.playable_uris:

                model, dfr = self.resource.get(model.playable_uri, model)

                self.failUnless(isinstance(model, PlayableModel),
                    "%r is not a PlayableModel" % model)

                dfr.addCallback(got_model, unicode(expected_uri))
                yield dfr

        return task.coiterate(run_test())


class CommonResourceTester(GenericSetup, UriRegExpTester, PlayableUriTester):
    pass
