#!/usr/bin/env python
# -*- coding: utf-8 -*-
#   Copyright 2008 Agile42 GmbH - Andrea Tomasini 
#
#   Licensed under the Apache License, Version 2.0 (the "License");
#   you may not use this file except in compliance with the License.
#   You may obtain a copy of the License at
#
#       http://www.apache.org/licenses/LICENSE-2.0
#
#   Unless required by applicable law or agreed to in writing, software
#   distributed under the License is distributed on an "AS IS" BASIS,
#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#   See the License for the specific language governing permissions and
#   limitations under the License.
# 
# Authors:
#     - Andrea Tomasini <andrea.tomasini__at__agile42.com>
import unittest

import trac.ticket.model

from agilo.test import TestEnvHelper
from agilo.utils.config import AgiloConfig
import agilo.ticket.web_ui
from agilo.ticket.model import AgiloTicket
from agilo.utils import Key, Type


class MultiEnvironmentTest(unittest.TestCase):
    """
    Tests the support of agilo for multi environments, to make sure that
    agilo components are only instantiated if the environment is belonging to
    an agilo enabled Trac project
    """
    def setUp(self):
        """Initialize the environment"""
        self.teh = TestEnvHelper()
        self.env = self.teh.get_env()
        
    def teatDown(self):
        """Remove any created item"""
        self.teh.cleanup()
        
    def test_agilo_enabled_project(self):
        """Tests that the check of an agilo enabled project"""
        ac = AgiloConfig(self.env)
        ac.enable_agilo()
        self.assertTrue(ac.is_agilo_enabled)
        # Now remove agilo and verify that is not enabled
        ac.disable_agilo()
        self.assertFalse(ac.is_agilo_enabled)

    def test_ticket_module_monkey_patching(self):
        """Tests that if agilo is enabled, the TicketModule will monkey patch"""
        ac = AgiloConfig(self.env)
        ac.enable_agilo()
        tm = agilo.ticket.web_ui.AgiloTicketModule(self.env)
        self.assertTrue(issubclass(tm.get_ticket_class(), AgiloTicket), 
                        "Monkey patching failed (%s)!" % tm.get_ticket_class())
        
    def test_ticket_without_monkey_patching(self):
        """Tests that if agilo is not enabled, the TicketModule will not monkey patch"""
        ac = AgiloConfig(self.env)
        ac.disable_agilo()
        tm = agilo.ticket.web_ui.AgiloTicketModule(self.env)
        try:
            self.assertFalse(issubclass(tm.get_ticket_class(), AgiloTicket),
                             "Monkey patching failed (%s)!" % tm.get_ticket_class())
            self.assertTrue(issubclass(tm.get_ticket_class(), trac.ticket.model.Ticket), 
                            "Monkey patching failed (%s)!" % tm.get_ticket_class())
        except AttributeError, e:
            self.assertEqual("'TicketModule' object has no attribute 'get_ticket_class'",
                             str(e))
    
    def test_agilo_detection_method(self):
        """Tests the agilo detection method, based on the config"""
        ac = AgiloConfig(self.env)
        ac.disable_agilo()
        self.assertFalse(ac.is_agilo_enabled)
        self.env.config.set('components', 'agilo.scrum.web_ui.*', 'enabled')
        ac.reload()
        self.assertTrue(ac.is_agilo_enabled)
        self.env.config.set('components', 'agilo.scrum.web_ui.*', 'disabled')
        ac.reload()
        self.assertFalse(ac.is_agilo_enabled)

    def test_agilo_config_component(self):
        """Tests the behavior of the AgiloConfig component with agilo disabled"""
        ac = AgiloConfig(self.env)
        ac.disable_agilo()
        self.assertEqual(None, ac.TYPES, 
                         "Types got initialized also with agilo disabled?")
        self.assertEqual(None, ac.ALIASES, 
                         "Aliases got initialized also with agilo disabled?")
        
    def test_agilo_with_parallel_environments(self):
        """
        Tests agilo in parallel with two different environment, one with and
        one without agilo
        """
        ac_agilo = AgiloConfig(self.env)
        ac_agilo.enable_agilo()
        env_no_agilo = TestEnvHelper()
        ac_no_agilo = AgiloConfig(env_no_agilo.get_env())
        ac_no_agilo.disable_agilo()
        # Now we have two environment in the same python VM
        agilo_ticket = self.teh.create_ticket(Type.TASK,
                                              props={Key.REMAINING_TIME: '2'})
        self.assertTrue(isinstance(agilo_ticket, AgiloTicket), 
                        "Got the wrong type: %s" % type(agilo_ticket))
        non_agilo_ticket = env_no_agilo.create_ticket(Type.TASK,
                                                      props={Key.REMAINING_TIME: '2'})
        
        self.assertTrue(hasattr(agilo_ticket, '_calculated'))
        self.assertFalse(hasattr(non_agilo_ticket, '_calculated'))
        # I found no simple properties which can be checked for differences 
        # using an AgiloTicket and a trac Ticket without doing any more 
        # complicated stuff like linking. If you know some nice tests, please
        # add them here.
        # First I wanted to check if business rules are called for the trac
        # Ticket (must not) but we don't have to really different environments
        # here so that won't work either.


if __name__ == '__main__':
    #unittest.main()
    suite = unittest.TestLoader().loadTestsFromTestCase(MultiEnvironmentTest)
    #suite = unittest.TestSuite()
    #suite.addTest(TestAgiloTicket('testLinkOnDeletedTicket'))
    unittest.TextTestRunner(verbosity=0).run(suite)
