"""
Isolated tests for validation functionality without importing the full package.

Author: Vasiliy Zdanovskiy
email: vasilyvz@gmail.com
"""

import json
import os
import tempfile
import unittest
from pathlib import Path
from typing import Dict, Any

# Add the project root to the path
import sys
sys.path.insert(0, str(Path(__file__).parent.parent))

# Import only the validation modules directly
from mcp_proxy_adapter.core.config_validator import ConfigValidator
from mcp_proxy_adapter.core.errors import ConfigError, ValidationResult


class TestIsolatedValidation(unittest.TestCase):
    """Test validation functionality in isolation."""
    
    def setUp(self):
        """Set up test environment."""
        self.temp_dir = tempfile.mkdtemp()
        self.validator = ConfigValidator()
        
    def tearDown(self):
        """Clean up test environment."""
        import shutil
        shutil.rmtree(self.temp_dir, ignore_errors=True)
    
    def test_ssl_validation_with_missing_certificates(self):
        """Test SSL validation with missing certificates."""
        config_data = {
            "server": {"host": "0.0.0.0", "port": 8000, "protocol": "https", "debug": False, "log_level": "INFO"},
            "logging": {"level": "INFO", "file": None, "log_dir": "./logs", "log_file": "test.log",
                       "error_log_file": "error.log", "access_log_file": "access.log", "max_file_size": "10MB",
                       "backup_count": 5, "format": "%(asctime)s - %(message)s", "date_format": "%Y-%m-%d %H:%M:%S",
                       "console_output": True, "file_output": True},
            "commands": {"auto_discovery": True, "commands_directory": "./commands", "catalog_directory": "./catalog",
                        "plugin_servers": [], "auto_install_dependencies": True, "enabled_commands": ["health"],
                        "disabled_commands": [], "custom_commands_path": "./commands"},
            "transport": {"type": "https", "port": None, "verify_client": False, "chk_hostname": True},
            "proxy_registration": {"enabled": False, "proxy_url": "https://localhost:3004", "server_id": "test",
                                 "server_name": "Test", "description": "Test", "version": "1.0.0",
                                 "registration_timeout": 30, "retry_attempts": 3, "retry_delay": 5,
                                 "auto_register_on_startup": True, "auto_unregister_on_shutdown": True},
            "debug": {"enabled": False, "level": "WARNING"},
            "security": {"enabled": False, "tokens": {}, "roles": {}, "roles_file": None},
            "roles": {"enabled": False, "config_file": None, "default_policy": {"deny_by_default": False,
                "require_role_match": False, "case_sensitive": False, "allow_wildcard": False},
                "auto_load": False, "validation_enabled": False},
            "ssl": {
                "enabled": True,  # SSL enabled
                "cert_file": None,  # But no cert file
                "key_file": None,   # And no key file
                "ca_cert": None
            }
        }
        
        results = self.validator.validate_config(config_data)
        
        # Should have errors about missing SSL files
        errors = [r for r in results if r.level == "error"]
        ssl_errors = [e for e in errors if "SSL" in e.message and ("cert_file" in e.message or "key_file" in e.message)]
        
        self.assertGreater(len(ssl_errors), 0, "Should have SSL errors for missing certificate files")
        self.assertTrue(any("SSL is enabled but cert_file is not specified" in e.message for e in ssl_errors))
        self.assertTrue(any("SSL is enabled but key_file is not specified" in e.message for e in ssl_errors))
        
        print("✅ SSL validation correctly detects missing certificate files")
    
    def test_ssl_validation_with_nonexistent_certificates(self):
        """Test SSL validation with non-existent certificate files."""
        config_data = {
            "server": {"host": "0.0.0.0", "port": 8000, "protocol": "https", "debug": False, "log_level": "INFO"},
            "logging": {"level": "INFO", "file": None, "log_dir": "./logs", "log_file": "test.log",
                       "error_log_file": "error.log", "access_log_file": "access.log", "max_file_size": "10MB",
                       "backup_count": 5, "format": "%(asctime)s - %(message)s", "date_format": "%Y-%m-%d %H:%M:%S",
                       "console_output": True, "file_output": True},
            "commands": {"auto_discovery": True, "commands_directory": "./commands", "catalog_directory": "./catalog",
                        "plugin_servers": [], "auto_install_dependencies": True, "enabled_commands": ["health"],
                        "disabled_commands": [], "custom_commands_path": "./commands"},
            "transport": {"type": "https", "port": None, "verify_client": False, "chk_hostname": True},
            "proxy_registration": {"enabled": False, "proxy_url": "https://localhost:3004", "server_id": "test",
                                 "server_name": "Test", "description": "Test", "version": "1.0.0",
                                 "registration_timeout": 30, "retry_attempts": 3, "retry_delay": 5,
                                 "auto_register_on_startup": True, "auto_unregister_on_shutdown": True},
            "debug": {"enabled": False, "level": "WARNING"},
            "security": {"enabled": False, "tokens": {}, "roles": {}, "roles_file": None},
            "roles": {"enabled": False, "config_file": None, "default_policy": {"deny_by_default": False,
                "require_role_match": False, "case_sensitive": False, "allow_wildcard": False},
                "auto_load": False, "validation_enabled": False},
            "ssl": {
                "enabled": True,  # SSL enabled
                "cert_file": "/nonexistent/cert.crt",  # Non-existent cert file
                "key_file": "/nonexistent/key.key",    # Non-existent key file
                "ca_cert": None
            }
        }
        
        results = self.validator.validate_config(config_data)
        
        # Should have errors about non-existent SSL files
        errors = [r for r in results if r.level == "error"]
        ssl_errors = [e for e in errors if "SSL" in e.message and "does not exist" in e.message]
        
        self.assertGreater(len(ssl_errors), 0, "Should have SSL errors for non-existent certificate files")
        self.assertTrue(any("/nonexistent/cert.crt" in e.message for e in ssl_errors))
        self.assertTrue(any("/nonexistent/key.key" in e.message for e in ssl_errors))
        
        print("✅ SSL validation correctly detects non-existent certificate files")
    
    def test_ssl_disabled_does_not_validate_certificates(self):
        """Test that SSL disabled does not validate certificate files."""
        config_data = {
            "server": {"host": "0.0.0.0", "port": 8000, "protocol": "http", "debug": False, "log_level": "INFO"},
            "logging": {"level": "INFO", "file": None, "log_dir": "./logs", "log_file": "test.log",
                       "error_log_file": "error.log", "access_log_file": "access.log", "max_file_size": "10MB",
                       "backup_count": 5, "format": "%(asctime)s - %(message)s", "date_format": "%Y-%m-%d %H:%M:%S",
                       "console_output": True, "file_output": True},
            "commands": {"auto_discovery": True, "commands_directory": "./commands", "catalog_directory": "./catalog",
                        "plugin_servers": [], "auto_install_dependencies": True, "enabled_commands": ["health"],
                        "disabled_commands": [], "custom_commands_path": "./commands"},
            "transport": {"type": "http", "port": None, "verify_client": False, "chk_hostname": False},
            "proxy_registration": {"enabled": False, "proxy_url": "http://localhost:3004", "server_id": "test",
                                 "server_name": "Test", "description": "Test", "version": "1.0.0",
                                 "registration_timeout": 30, "retry_attempts": 3, "retry_delay": 5,
                                 "auto_register_on_startup": True, "auto_unregister_on_shutdown": True},
            "debug": {"enabled": False, "level": "WARNING"},
            "security": {"enabled": False, "tokens": {}, "roles": {}, "roles_file": None},
            "roles": {"enabled": False, "config_file": None, "default_policy": {"deny_by_default": False,
                "require_role_match": False, "case_sensitive": False, "allow_wildcard": False},
                "auto_load": False, "validation_enabled": False},
            "ssl": {
                "enabled": False,  # SSL disabled
                "cert_file": "/nonexistent/cert.crt",  # Non-existent cert file - should not be validated
                "key_file": "/nonexistent/key.key",    # Non-existent key file - should not be validated
                "ca_cert": None
            }
        }
        
        results = self.validator.validate_config(config_data)
        
        # Should NOT have errors about SSL files when SSL is disabled
        errors = [r for r in results if r.level == "error"]
        ssl_errors = [e for e in errors if "SSL" in e.message]
        
        self.assertEqual(len(ssl_errors), 0, "Should not have SSL errors when SSL is disabled")
        
        print("✅ SSL validation correctly skips validation when SSL is disabled")
    
    def test_roles_validation_with_missing_config_file(self):
        """Test roles validation with missing config file."""
        config_data = {
            "server": {"host": "0.0.0.0", "port": 8000, "protocol": "http", "debug": False, "log_level": "INFO"},
            "logging": {"level": "INFO", "file": None, "log_dir": "./logs", "log_file": "test.log",
                       "error_log_file": "error.log", "access_log_file": "access.log", "max_file_size": "10MB",
                       "backup_count": 5, "format": "%(asctime)s - %(message)s", "date_format": "%Y-%m-%d %H:%M:%S",
                       "console_output": True, "file_output": True},
            "commands": {"auto_discovery": True, "commands_directory": "./commands", "catalog_directory": "./catalog",
                        "plugin_servers": [], "auto_install_dependencies": True, "enabled_commands": ["health"],
                        "disabled_commands": [], "custom_commands_path": "./commands"},
            "transport": {"type": "http", "port": None, "verify_client": False, "chk_hostname": False},
            "proxy_registration": {"enabled": False, "proxy_url": "http://localhost:3004", "server_id": "test",
                                 "server_name": "Test", "description": "Test", "version": "1.0.0",
                                 "registration_timeout": 30, "retry_attempts": 3, "retry_delay": 5,
                                 "auto_register_on_startup": True, "auto_unregister_on_shutdown": True},
            "debug": {"enabled": False, "level": "WARNING"},
            "security": {"enabled": False, "tokens": {}, "roles": {}, "roles_file": None},
            "roles": {
                "enabled": True,  # Roles enabled
                "config_file": None,  # But no config file
                "default_policy": {"deny_by_default": False, "require_role_match": False,
                                  "case_sensitive": False, "allow_wildcard": False},
                "auto_load": False, "validation_enabled": False
            }
        }
        
        results = self.validator.validate_config(config_data)
        
        # Should have errors about roles
        errors = [r for r in results if r.level == "error"]
        roles_errors = [e for e in errors if "roles" in e.message.lower()]
        
        self.assertGreater(len(roles_errors), 0, "Should have roles errors")
        self.assertTrue(any("Roles are enabled but config_file is not specified" in e.message for e in roles_errors))
        
        print("✅ Roles validation correctly detects missing config file")
    
    def test_security_validation_without_auth(self):
        """Test security validation without authentication methods."""
        config_data = {
            "server": {"host": "0.0.0.0", "port": 8000, "protocol": "http", "debug": False, "log_level": "INFO"},
            "logging": {"level": "INFO", "file": None, "log_dir": "./logs", "log_file": "test.log",
                       "error_log_file": "error.log", "access_log_file": "access.log", "max_file_size": "10MB",
                       "backup_count": 5, "format": "%(asctime)s - %(message)s", "date_format": "%Y-%m-%d %H:%M:%S",
                       "console_output": True, "file_output": True},
            "commands": {"auto_discovery": True, "commands_directory": "./commands", "catalog_directory": "./catalog",
                        "plugin_servers": [], "auto_install_dependencies": True, "enabled_commands": ["health"],
                        "disabled_commands": [], "custom_commands_path": "./commands"},
            "transport": {"type": "http", "port": None, "verify_client": False, "chk_hostname": False},
            "proxy_registration": {"enabled": False, "proxy_url": "http://localhost:3004", "server_id": "test",
                                 "server_name": "Test", "description": "Test", "version": "1.0.0",
                                 "registration_timeout": 30, "retry_attempts": 3, "retry_delay": 5,
                                 "auto_register_on_startup": True, "auto_unregister_on_shutdown": True},
            "debug": {"enabled": False, "level": "WARNING"},
            "security": {
                "enabled": True,  # Security enabled
                "tokens": {},     # But no tokens
                "roles": {},      # And no roles
                "roles_file": None  # And no roles file
            },
            "roles": {"enabled": False, "config_file": None, "default_policy": {"deny_by_default": False,
                "require_role_match": False, "case_sensitive": False, "allow_wildcard": False},
                "auto_load": False, "validation_enabled": False}
        }
        
        results = self.validator.validate_config(config_data)
        
        # Should have warnings about security
        warnings = [r for r in results if r.level == "warning"]
        security_warnings = [w for w in warnings if "Security is enabled but no authentication methods" in w.message]
        
        self.assertGreater(len(security_warnings), 0, "Should have security warnings")
        
        print("✅ Security validation correctly detects missing authentication methods")
    
    def test_validation_summary_generation(self):
        """Test validation summary generation."""
        config_data = {
            "server": {"host": "0.0.0.0", "port": 8000, "protocol": "http", "debug": False, "log_level": "INFO"},
            "logging": {"level": "INFO", "file": None, "log_dir": "./logs", "log_file": "test.log",
                       "error_log_file": "error.log", "access_log_file": "access.log", "max_file_size": "10MB",
                       "backup_count": 5, "format": "%(asctime)s - %(message)s", "date_format": "%Y-%m-%d %H:%M:%S",
                       "console_output": True, "file_output": True},
            "commands": {"auto_discovery": True, "commands_directory": "./commands", "catalog_directory": "./catalog",
                        "plugin_servers": [], "auto_install_dependencies": True, "enabled_commands": ["health"],
                        "disabled_commands": [], "custom_commands_path": "./commands"},
            "transport": {"type": "http", "port": None, "verify_client": False, "chk_hostname": False},
            "proxy_registration": {"enabled": False, "proxy_url": "http://localhost:3004", "server_id": "test",
                                 "server_name": "Test", "description": "Test", "version": "1.0.0",
                                 "registration_timeout": 30, "retry_attempts": 3, "retry_delay": 5,
                                 "auto_register_on_startup": True, "auto_unregister_on_shutdown": True},
            "debug": {"enabled": False, "level": "WARNING"},
            "security": {"enabled": False, "tokens": {}, "roles": {}, "roles_file": None},
            "roles": {"enabled": False, "config_file": None, "default_policy": {"deny_by_default": False,
                "require_role_match": False, "case_sensitive": False, "allow_wildcard": False},
                "auto_load": False, "validation_enabled": False}
        }
        
        results = self.validator.validate_config(config_data)
        summary = self.validator.get_validation_summary()
        
        self.assertIn("total_issues", summary)
        self.assertIn("errors", summary)
        self.assertIn("warnings", summary)
        self.assertIn("info", summary)
        self.assertIn("is_valid", summary)
        
        # For valid config, should have no errors
        self.assertEqual(summary["errors"], 0)
        self.assertTrue(summary["is_valid"])
        
        print("✅ Validation summary generation works correctly")


if __name__ == '__main__':
    print("🧪 Running Isolated Validation Tests")
    print("=" * 50)
    
    # Run tests with detailed output
    unittest.main(verbosity=2, exit=False)
    
    print("\n" + "=" * 50)
    print("✅ All isolated validation tests completed!")
