#!/usr/bin/env python3
"""Service Registry functional tests with hybrid architecture.

Tests both HTTP API (external) and Docker SDK (internal) service operations.
"""

import sys
import os
import unittest
import time

# Add src to path for imports
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..', '..', 'src'))

from blackant import BlackAntAuth, ServiceRegistry


class TestServiceOperations(unittest.TestCase):
    """Test service registry operations with hybrid architecture."""

    @classmethod
    def setUpClass(cls):
        """Set up test environment."""
        # Get credentials from environment variables
        test_user = os.getenv("BLACKANT_TEST_USER", "admin")
        test_password = os.getenv("BLACKANT_TEST_PASSWORD")

        if not test_password:
            raise unittest.SkipTest("BLACKANT_TEST_PASSWORD not set in environment")

        cls.auth = BlackAntAuth(
            user=test_user,
            password=test_password,
            login_url=os.getenv("BLACKANT_LOGIN_URL", "http://localhost/api/auth/login")
        )
        cls.registry = ServiceRegistry(
            auth=cls.auth,
            base_url=os.getenv("BLACKANT_BASE_URL", "http://localhost")
        )

    def test_service_registry_initialization(self):
        """Test service registry initialization."""
        self.assertIsNotNone(self.registry)
        self.assertIsNotNone(self.registry.http_client)
        print(f"ServiceRegistry initialized successfully")
        print(f"Docker support available: {self.registry.has_docker_support}")

    def test_list_services_http(self):
        """Test service listing via HTTP API."""
        try:
            services = self.registry.list()
            self.assertIsInstance(services, list)
            print(f"HTTP API - Found {len(services)} services")

            # Test with namespace parameter
            namespace_services = self.registry.list(namespace="default")
            self.assertIsInstance(namespace_services, list)
            print(f"HTTP API - Found {len(namespace_services)} services in 'default' namespace")

        except Exception as e:
            # Expected if service backend isn't fully configured
            print(f"HTTP service listing not available: {e}")

    def test_docker_service_operations(self):
        """Test Docker SDK service operations if available."""
        if not self.registry.has_docker_support:
            print("Docker SDK support not available - skipping Docker tests")
            return

        try:
            # Test Docker service listing
            docker_services = self.registry.list_docker_services()
            self.assertIsInstance(docker_services, list)
            print(f"Docker SDK - Found {len(docker_services)} services")

            # Test filtered listing
            filtered_services = self.registry.list_docker_services(
                filters={'label': 'test=true'}
            )
            self.assertIsInstance(filtered_services, list)
            print(f"Docker SDK - Found {len(filtered_services)} test services")

        except Exception as e:
            print(f"Docker service operations failed: {e}")
            # This is expected if Docker daemon isn't accessible

    def test_docker_service_creation(self):
        """Test Docker service creation if available."""
        if not self.registry.has_docker_support:
            print("Docker SDK support not available - skipping service creation test")
            return

        test_service_config = {
            "name": "blackant-test-service",
            "image": "hello-world:latest",
            "environments": {"TEST": "true"},
            "labels": {"test": "true", "created_by": "blackant_sdk"},
            "replicas": 1
        }

        try:
            # Create test service
            service_id = self.registry.create_service_with_docker(test_service_config)

            if service_id:
                self.assertIsInstance(service_id, str)
                self.assertNotEqual(service_id, "")
                print(f"Docker SDK - Test service created: {service_id}")

                # Wait a moment for service to initialize
                time.sleep(2)

                # Check if service is running
                is_running = self.registry.is_docker_service_running(service_id)
                print(f"Docker SDK - Service running status: {is_running}")

                # Get service object
                service = self.registry.get_docker_service(service_id)
                if service:
                    print(f"Docker SDK - Service name: {service.name}")
                    print(f"Docker SDK - Service ID: {service.id}")

                # Clean up - remove test service
                removed = self.registry.remove_docker_service(service_id)
                self.assertTrue(removed)
                print(f"Docker SDK - Test service removed: {removed}")
            else:
                print("Docker SDK - Service creation returned None (expected if Docker not available)")

        except Exception as e:
            print(f"Docker service creation test failed: {e}")
            # This is expected if Docker daemon isn't accessible or images aren't available

    def test_service_management_operations(self):
        """Test service management operations."""
        # Test HTTP API operations that should work
        try:
            # Test service listing (should work even if empty)
            services = self.registry.list()
            self.assertIsInstance(services, list)

            # Test with various parameters
            id_services = self.registry.list(service_id="nonexistent")
            self.assertIsInstance(id_services, list)

            name_services = self.registry.list(service_name="nonexistent")
            self.assertIsInstance(name_services, list)

            print("HTTP API service management operations working")

        except Exception as e:
            print(f"Service management operations failed: {e}")

    def test_hybrid_architecture(self):
        """Test that both HTTP API and Docker SDK approaches coexist."""
        print("Testing hybrid architecture...")

        # HTTP API should always be available
        self.assertIsNotNone(self.registry.http_client)
        print("OK HTTP client available")

        # Docker SDK may or may not be available
        docker_available = self.registry.has_docker_support
        print(f"OK Docker SDK support: {docker_available}")

        if docker_available:
            self.assertIsNotNone(self.registry.service_dao)
            print("OK ServiceManagerDAO available")
        else:
            print("OK ServiceManagerDAO not available (expected in some environments)")

        # Both approaches should be callable without errors
        try:
            http_services = self.registry.list()
            print(f"OK HTTP API call successful: {len(http_services)} services")
        except Exception as e:
            print(f"OK HTTP API call handled: {e}")

        try:
            docker_services = self.registry.list_docker_services()
            print(f"OK Docker SDK call successful: {len(docker_services)} services")
        except Exception as e:
            print(f"OK Docker SDK call handled: {e}")


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