# Elisa - Home multimedia server
# Copyright (C) 2006-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 import elisa_test_case
import sys, os
import inspect
from twisted.internet import defer

class ComponentTestCase(elisa_test_case.ElisaTestCase):

    component_class = None
    component_path = '.'
    config = None
    logged = False
    
    def get_component(self):
        component = None
        if self.component_class:
            if isinstance(self.component_class, basestring):

                # setup path
                sys_path = os.getcwd()
                if self.component_path == '.':
                    sys_path = inspect.getsourcefile(self.__class__)
                    sys_path = os.path.dirname(sys_path)
                elif self.component_path.startswith('..'):
                    sys_path = inspect.getsourcefile(self.__class__)
                    sys_path = os.path.dirname(sys_path)
                    sys_path = os.path.dirname(sys_path[:-1])
                    index = self.component_path.find(os.path.sep)
                    if index > -1:
                        dirname = self.component_path[index+1:]
                        sys_path = os.path.join(sys_path, dirname)

                self.debug('Appending %r to sys.path', sys_path)
                sys.path.insert(0, sys_path)
                        
                # import
                path = self.component_class
                mod_class = path.split(':')

                try:
                    module = __import__(mod_class[0], globals(),
                                        locals(), [mod_class[1]])
                except ImportError:
                    pass
                else:
                    Class = getattr(module, mod_class[1])
                    # avoid unecessary future imports
                    self.component_class = Class
                    component = Class()

                # clean sys path
                sys.path.remove(sys_path)
                
            else:
                component = self.component_class()

        # TODO: perform extra stuff that's normally done by the
        #       plugin registry create_component() method
        from elisa.core import common
        app = common.application
        if component is None:
            self.skip = "Component could not get created"
            return
        if app:
            self.debug("Initializing %r component", component.name)
            if self.config is None:
                component.load_config(app.config)
            else:
                component.config = self.config
            dfr = defer.maybeDeferred(component.initialize)
            dfr.addCallback(lambda result: component)
            dfr.addErrback(lambda failure: setattr(self,'skip',failure.value))
            return dfr
        else:
            self.debug("Application not set, skipping component initialization")
        return component

    def setUp(self):
        elisa_test_case.ElisaTestCase.setUp(self)
        dfr = defer.maybeDeferred(self.get_component)
        dfr.addCallback(lambda result: setattr(self, 'component', result))

        return dfr

    def tearDown(self):
        if self.component is not None:
            return self.component.clean()
