import pytest
from pathlib import Path
import tempfile
import shutil
import yaml
from multi_swarm.plugins.base.plugin_base import PluginBase, PluginMetadata

class TestPlugin(PluginBase):
    """Test plugin implementation."""
    metadata = PluginMetadata(
        name="test_plugin",
        version="1.0.0",
        description="Test plugin for unit testing",
        author="Test Author",
        requirements=["pyyaml"],
        tags=["test", "development"],
        config_schema={
            "type": "object",
            "properties": {
                "test_setting": {"type": "string"}
            }
        }
    )
    
    def initialize(self) -> None:
        self.initialized = True
    
    def cleanup(self) -> None:
        self.initialized = False
    
    def get_capabilities(self) -> list:
        return ["test_capability"]

@pytest.fixture
def temp_config_dir():
    """Create a temporary directory for config files."""
    temp_dir = tempfile.mkdtemp()
    config_dir = Path(temp_dir) / "config"
    config_dir.mkdir()
    yield config_dir
    shutil.rmtree(temp_dir)

@pytest.fixture
def test_config(temp_config_dir):
    """Create a test configuration file."""
    config = {
        "test_setting": "test_value"
    }
    config_path = temp_config_dir / "test_plugin.yaml"
    with open(config_path, "w") as f:
        yaml.dump(config, f)
    return config_path

class TestPluginBase:
    def test_plugin_creation(self):
        """Test basic plugin creation."""
        plugin = TestPlugin()
        assert plugin.metadata.name == "test_plugin"
        assert plugin.metadata.version == "1.0.0"
        assert plugin.enabled == True
        
    def test_plugin_metadata(self):
        """Test plugin metadata validation."""
        plugin = TestPlugin()
        assert "test" in plugin.metadata.tags
        assert "pyyaml" in plugin.metadata.requirements
        assert plugin.metadata.author == "Test Author"
        
    def test_plugin_configuration(self, test_config, monkeypatch):
        """Test plugin configuration loading."""
        # Mock the config path
        monkeypatch.setattr(
            "multi_swarm.plugins.base.plugin_base.Path.__truediv__",
            lambda self, x: test_config if "test_plugin.yaml" in str(x) else self / x
        )
        
        plugin = TestPlugin()
        assert plugin.config["test_setting"] == "test_value"
        
    def test_plugin_requirements_validation(self):
        """Test requirement validation."""
        # Create plugin with invalid requirement
        class InvalidPlugin(PluginBase):
            metadata = PluginMetadata(
                name="invalid_plugin",
                version="1.0.0",
                description="Invalid plugin",
                author="Test Author",
                requirements=["invalid_package_name_123"],
                tags=[]
            )
        
        with pytest.raises(ImportError):
            InvalidPlugin()
            
    def test_plugin_initialization(self):
        """Test plugin initialization."""
        plugin = TestPlugin()
        plugin.initialize()
        assert hasattr(plugin, "initialized")
        assert plugin.initialized == True
        
    def test_plugin_cleanup(self):
        """Test plugin cleanup."""
        plugin = TestPlugin()
        plugin.initialize()
        plugin.cleanup()
        assert plugin.initialized == False
        
    def test_plugin_capabilities(self):
        """Test plugin capabilities."""
        plugin = TestPlugin()
        capabilities = plugin.get_capabilities()
        assert "test_capability" in capabilities
        
    def test_plugin_health_check(self):
        """Test plugin health check."""
        plugin = TestPlugin()
        health = plugin.health_check()
        assert health["status"] == "healthy"
        assert health["name"] == plugin.metadata.name
        assert health["version"] == plugin.metadata.version
        
    def test_plugin_config_validation(self):
        """Test configuration validation."""
        plugin = TestPlugin()
        plugin.config = {"test_setting": "valid_value"}
        assert plugin.validate_config() == True
        
        plugin.config = {"invalid_setting": "invalid_value"}
        assert plugin.validate_config() == False
        
    def test_plugin_disabled_state(self):
        """Test plugin disabled state."""
        plugin = TestPlugin()
        plugin.enabled = False
        assert plugin.enabled == False
        health = plugin.health_check()
        assert health["enabled"] == False 