import unittest
import logging
import time
from src.scaling_manager import ScalingManager
from src.simulators.resource_manager import ResourceManager, InstanceProvider

logging.basicConfig(level=logging.INFO)

class TestScalingWithResourceConstraints(unittest.TestCase):

    def setUp(self):
        self.resource_manager = ResourceManager(initial_capacity=2, failure_rate=0.7, delay_range=(0.5, 1))
        self.instance_provider = InstanceProvider()
        self.config = {
            'max_retries': 3,
            'retry_interval': 1
        }
        self.scaling_manager = ScalingManager(self.resource_manager, self.instance_provider, self.config)

    def test_scale_up_with_resource_constraints(self):
        initial_instances = self.instance_provider.get_current_instance_count()
        desired_instances = 3

        self.scaling_manager.scale_up(desired_instances)
        time.sleep(5)

        final_instances = self.instance_provider.get_current_instance_count()

        self.assertGreaterEqual(final_instances, initial_instances)  # Should scale up at least partially
        self.assertLessEqual(final_instances, desired_instances)

        self.assertEqual(self.resource_manager.get_available_resource_count() + final_instances, 2)

    def test_scale_down_with_resource_constraints(self):
        # First scale up to have instances to scale down
        self.scaling_manager.scale_up(2)
        time.sleep(2)
        desired_instances = 0
        initial_instances = self.instance_provider.get_current_instance_count()

        self.scaling_manager.scale_down(desired_instances)
        time.sleep(3)

        final_instances = self.instance_provider.get_current_instance_count()

        self.assertLessEqual(final_instances, initial_instances)  # Should scale down at least partially
        self.assertEqual(final_instances, desired_instances)

        self.assertEqual(self.resource_manager.get_available_resource_count() + final_instances, 2)

if __name__ == '__main__':
    unittest.main()