import pytest
from typing import Dict, Any
from unittest.mock import patch
import os
import tempfile
import shutil
from pathlib import Path

@pytest.fixture(scope="session")
def test_root_dir():
    """Create a temporary directory for all tests."""
    temp_dir = tempfile.mkdtemp()
    yield Path(temp_dir)
    shutil.rmtree(temp_dir)

@pytest.fixture(scope="session")
def test_config_dir(test_root_dir):
    """Create a temporary configuration directory."""
    config_dir = test_root_dir / "config"
    config_dir.mkdir()
    yield config_dir

@pytest.fixture(scope="session")
def test_plugins_dir(test_root_dir):
    """Create a temporary plugins directory."""
    plugins_dir = test_root_dir / "plugins"
    plugins_dir.mkdir()
    yield plugins_dir

@pytest.fixture(scope="session")
def test_env_vars():
    """Set up test environment variables."""
    # Store original values
    original_vars = {}
    test_vars = {
        "MULTI_SWARM_CONFIG_DIR": "",  # Will be set by test_config_dir
        "MULTI_SWARM_PLUGINS_DIR": "", # Will be set by test_plugins_dir
        "MULTI_SWARM_LOG_LEVEL": "DEBUG",
        "MULTI_SWARM_TEST_MODE": "true"
    }
    
    # Save original values and set test values
    for var, value in test_vars.items():
        if var in os.environ:
            original_vars[var] = os.environ[var]
        os.environ[var] = value
    
    yield test_vars
    
    # Restore original values
    for var in test_vars:
        if var in original_vars:
            os.environ[var] = original_vars[var]
        else:
            del os.environ[var]

def pytest_configure(config):
    """Configure pytest for our tests."""
    # Add markers
    config.addinivalue_line(
        "markers", "integration: mark test as integration test"
    )
    config.addinivalue_line(
        "markers", "plugin: mark test as plugin test"
    )
    config.addinivalue_line(
        "markers", "registry: mark test as registry test"
    )

@pytest.fixture(autouse=True)
def setup_test_env(test_config_dir, test_plugins_dir, test_env_vars):
    """Automatically set up test environment for all tests."""
    # Update environment variables with actual paths
    os.environ["MULTI_SWARM_CONFIG_DIR"] = str(test_config_dir)
    os.environ["MULTI_SWARM_PLUGINS_DIR"] = str(test_plugins_dir)
    yield

@pytest.fixture
def mock_env_vars():
    """Fixture to set up mock environment variables."""
    env_vars = {
        'ANTHROPIC_API_KEY': 'mock-anthropic-key',
        'GOOGLE_API_KEY': 'mock-google-key'
    }
    with patch.dict('os.environ', env_vars):
        yield env_vars

@pytest.fixture
def mock_instructions(tmp_path):
    """Fixture to create a temporary instructions file."""
    instructions = tmp_path / "instructions.md"
    instructions.write_text("Test agent instructions")
    return str(instructions)

@pytest.fixture
def mock_tools_dir(tmp_path):
    """Fixture to create a temporary tools directory."""
    tools_dir = tmp_path / "tools"
    tools_dir.mkdir()
    return str(tools_dir)

@pytest.fixture(autouse=True)
def mock_providers(monkeypatch, mock_env_vars):
    """Automatically mock LLM providers for all tests."""
    # Mock Anthropic client
    class MockAnthropicClient:
        def messages(self):
            return self
        
        def create(self, *args, **kwargs):
            return type('Response', (), {
                'content': [type('Content', (), {'text': 'Mock Claude response'})()]
            })
    
    # Mock Gemini response
    class MockGeminiResponse:
        def __init__(self, text="Mock Gemini response"):
            self.text = text

    # Mock Gemini model
    class MockGeminiModel:
        def __init__(self, model_name):
            self.model_name = model_name
        
        def generate_content(self, content, generation_config=None):
            return MockGeminiResponse()
    
    # Mock Gemini client
    class MockGeminiClient:
        def __init__(self, model_name=None, **kwargs):
            self.model_name = model_name
        
        def GenerativeModel(self, model_name=None):
            return MockGeminiModel(model_name or self.model_name)
    
    # Patch the clients
    monkeypatch.setattr('anthropic.Anthropic', lambda *args, **kwargs: MockAnthropicClient())
    monkeypatch.setattr('google.generativeai.GenerativeModel', MockGeminiClient)

