"""Tests for the Git tool plugin."""

import pytest
from pathlib import Path
import tempfile
import shutil
import git
import sys
import os
import time

# Add the src directory to the Python path
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "src")))

# Import directly from the module files
from multi_swarm.plugins.base.plugin_base import PluginBase, PluginMetadata
from multi_swarm.plugins.tools.development.git import GitTool

@pytest.fixture
def temp_git_dir():
    """Create a temporary directory for Git operations."""
    temp_dir = tempfile.mkdtemp()
    yield Path(temp_dir)
    # Give the system time to release file handles
    time.sleep(0.1)
    try:
        shutil.rmtree(temp_dir)
    except PermissionError:
        pass  # Ignore permission errors during cleanup

@pytest.fixture
def test_repo(temp_git_dir):
    """Create a test repository."""
    repo_path = temp_git_dir / "test_repo"
    repo = git.Repo.init(repo_path)
    
    # Create and checkout main branch
    repo.git.checkout('-b', 'main')
    
    # Create initial commit
    readme = repo_path / "README.md"
    readme.write_text("# Test Repository")
    repo.index.add(["README.md"])
    repo.index.commit("Initial commit")
    
    yield repo_path

@pytest.fixture
def git_tool():
    """Create a Git tool instance."""
    return GitTool()

class TestGitTool:
    def test_tool_creation(self, git_tool):
        """Test Git tool creation and metadata."""
        assert git_tool.metadata.name == "git_tool"
        assert git_tool.metadata.version == "1.0.0"
        assert "git" in git_tool.metadata.tags
        assert "development" in git_tool.metadata.tags
        assert "gitpython" in git_tool.metadata.requirements
    
    def test_tool_capabilities(self, git_tool):
        """Test Git tool capabilities."""
        capabilities = git_tool.get_capabilities()
        expected_capabilities = [
            "initialize",
            "clone",
            "commit",
            "push",
            "pull",
            "status",
            "branch"
        ]
        for cap in expected_capabilities:
            assert cap in capabilities
    
    def test_repository_initialization(self, git_tool, temp_git_dir):
        """Test repository initialization."""
        repo_path = temp_git_dir / "new_repo"
        result = git_tool.initialize(str(repo_path))
        
        assert result["status"] == "success"
        assert "Initialized repository" in result["message"]
        assert git.Repo(repo_path).active_branch.name == "main"
    
    def test_commit_changes(self, git_tool, test_repo):
        """Test committing changes."""
        # Make changes
        test_file = test_repo / "test.txt"
        test_file.write_text("Modified content")
        
        # Commit changes
        result = git_tool.commit_changes(
            str(test_repo),
            "Test commit",
            ["test.txt"]
        )
        
        assert result["status"] == "success"
        assert "commit_hash" in result
    
    def test_commit_all_changes(self, git_tool, test_repo):
        """Test committing all changes without specifying files."""
        # Make changes to multiple files
        test_file = test_repo / "test.txt"
        test_file.write_text("Modified content")
        
        new_file = test_repo / "new.txt"
        new_file.write_text("New content")
        
        # Commit all changes
        result = git_tool.commit_changes(
            str(test_repo),
            "Commit all changes"
        )
        
        assert result["status"] == "success"
        assert "commit_hash" in result
    
    def test_get_status(self, git_tool, test_repo):
        """Test repository status check."""
        # Create a tracked file with changes
        test_file = test_repo / "test.txt"
        test_file.write_text("Initial content")
        repo = git.Repo(test_repo)
        repo.index.add(["test.txt"])
        repo.index.commit("Add test file")
        
        # Modify the tracked file
        test_file.write_text("Modified content")
        
        # Create an untracked file
        new_file = test_repo / "new.txt"
        new_file.write_text("New content")
        
        # Check status
        result = git_tool.get_status(str(test_repo))
        
        assert result["status"] == "success"
        assert result["is_dirty"] == True
        assert "test.txt" in result["modified_files"]
        assert "new.txt" in result["untracked_files"]
        assert result["active_branch"] == "main"
    
    def test_error_handling(self, git_tool, temp_git_dir):
        """Test error handling in Git operations."""
        # Test initialization with invalid path
        invalid_path = temp_git_dir / "invalid" / "repo"
        result = git_tool.initialize(str(invalid_path))
        assert result["status"] == "error"
        assert "error" in result
    
    def test_health_check(self, git_tool):
        """Test Git tool health check."""
        health = git_tool.health_check()
        
        assert health["status"] == "healthy"
        assert health["name"] == git_tool.metadata.name
        assert health["version"] == git_tool.metadata.version

if __name__ == "__main__":
    pytest.main([__file__, "-v"]) 