
import os
import time

from agilo.test.functional.api import SingleEnvironmentTestCase
from agilo.utils.config import AgiloConfig

# Register
from agilo.test.functional.agilo_environment import AgiloFunctionalTestEnvironment

__all__ = ['AgiloTestCase']


class AgiloTestCase(SingleEnvironmentTestCase):
    
    def __init__(self, *args, **kwargs):
        super(AgiloTestCase, self).__init__(*args, **kwargs)
        self.start = None
    
    def store_time(self):
        self.start = time.time()
    
    def ensure_min_one_second_passed(self):
        if self.start is None:
            self.store_time()
        passed_time = time.time() - self.start
        if passed_time < 1:
            time.sleep(1 - passed_time)
        self.start = None
    
    def classname(self):
        return self.__class__.__name__
    
    def milestone_name(self):
        return 'MilestoneFor' + self.sprint_name()
    
    def sprint_name(self):
        return self.classname() + 'Sprint'
    
    def team_name(self):
        return self.classname() + 'Team'
    
    def first_team_member_name(self):
        return self.classname() + 'FirstMember'
    
    def second_team_member_name(self):
        return self.classname() + 'SecondMember'
    
    def setUp(self, env_key='agilo'):
        super(AgiloTestCase, self).setUp(env_key=env_key)
        self.save_configuration()
        self.tester = self.testenv.tester
        self.tester.set_testcase(self)
        
        # Backwards compatibility
        self._testenv = self.testenv
        self._tester = self.tester
        
        # If the first test tries to access the contents before browsing a site,
        # this will fail. Therefore we ensure that we go to the front page 
        # before running the tests.
        self.tester.go_to_front()
    
    def tearDown(self):
        self.restore_configuration()
        self.tester.set_testcase(None)
        super(AgiloTestCase, self).tearDown()
    
    def disable_agilo_ui_for_this_test(self):
        self.testenv.disable_agilo_ui()
    
    def tracini_file(self, mode='rb'):
        return file(self.testenv.tracini_filename(), mode)
    
    def save_configuration(self):
        self.tracini_contents = self.tracini_file().read()
    
    def set_sprint_can_start_or_end_on_weekends(self):
        # The sprint must be running only for exactly one day, otherwise 
        # confirm commitment is not possible anymore (and the total capacity
        # might be different)
        env = self.testenv.get_trac_environment()
        config = AgiloConfig(env)
        config.change_option('sprints_can_start_or_end_on_weekends', True, section='agilo-general')
        config.save()
    
    def restore_configuration(self):
        if hasattr(self, 'tracini_contents'):
            current_contents = self.tracini_file().read()
            if current_contents != self.tracini_contents:
                self.tracini_file(mode='wb').write(self.tracini_contents)
            self.tracini_contents = None
    
    def remove_all_account_manager_components_from_config(self):
        env = self._testenv.get_trac_environment()
        components = AgiloConfig(env).get_section('components')
        for name in components.get_options_by_prefix('acct_mgr', chop_prefix=False):
            components.remove_option(name, save=False)
        components.save()
    
    def disable_account_manager(self):
        self.remove_all_account_manager_components_from_config()
        config = self._testenv.get_trac_environment().config
        config.set('components', 'acct_mgr.*', 'disabled')
        config.save()


