# Development Guide

## Getting Started

### Prerequisites

- Python 3.8 or higher
- pip and venv
- Git

### Initial Setup

1. Clone the repository:
```bash
git clone <repository-url>
cd mcp-proxy
```

2. Create and activate virtual environment:
```bash
python3 -m venv venv
source venv/bin/activate  # On Windows: venv\Scripts\activate
```

3. Install development dependencies:
```bash
pip install -e ".[dev]"
```

## Project Structure

See [ARCHITECTURE.md](ARCHITECTURE.md) for detailed architecture documentation.

## Development Tasks

### Running Tests

```bash
# Run all tests
pytest

# Run specific test file
pytest tests/test_models.py

# Run with verbose output
pytest -v

# Run with coverage
pytest --cov=mcp_proxy --cov-report=html

# Run only unit tests
pytest -m unit

# Run only property-based tests
pytest -m property
```

### Code Formatting

```bash
# Format Python code
black src tests

# Sort imports
isort src tests

# Format everything
black src tests && isort src tests
```

### Type Checking

```bash
# Run mypy type checker
mypy src

# Check specific file
mypy src/mcp_proxy/models.py
```

### Linting

```bash
# Run flake8 linter
flake8 src tests

# Check specific file
flake8 src/mcp_proxy/models.py
```

### Running All Quality Checks

```bash
# Format, type check, and lint
black src tests && \
isort src tests && \
mypy src && \
flake8 src tests && \
pytest
```

## Code Style Guidelines

### Python Style

- Follow PEP 8 style guide
- Use Black for automatic formatting (line length: 88)
- Use isort for import sorting
- Use type hints for all function signatures
- Write docstrings for all public functions and classes

### Docstring Format

```python
def function_name(param1: str, param2: int) -> bool:
    """Brief description of function.
    
    Longer description if needed, explaining the purpose,
    behavior, and any important details.
    
    Args:
        param1: Description of param1
        param2: Description of param2
        
    Returns:
        Description of return value
        
    Raises:
        ExceptionType: When this exception is raised
    """
    pass
```

### Type Hints

Always use type hints:

```python
from typing import Optional, List, Dict

def process_data(
    data: List[str],
    config: Optional[Dict[str, Any]] = None
) -> bool:
    ...
```

### Error Handling

Use custom exceptions from `exceptions.py`:

```python
from mcp_proxy.exceptions import AuthenticationError, DcrError

def authenticate() -> None:
    try:
        # Authentication logic
        pass
    except Exception as e:
        raise AuthenticationError("Authentication failed", details=str(e))
```

## Testing Guidelines

### Unit Tests

- Test individual functions and classes
- Use fixtures from `conftest.py`
- Mock external dependencies
- Test both success and failure cases

Example:
```python
def test_valid_config(sample_config):
    """Test that valid configuration is accepted."""
    assert sample_config.log_level == "info"
    assert sample_config.retry_attempts == 3
```

### Property-Based Tests

- Use Hypothesis for property-based testing
- Test universal properties that should hold for all inputs
- Generate diverse test data

Example:
```python
from hypothesis import given, strategies as st

@given(st.text(), st.integers())
def test_message_correlation(request_id, http_id):
    """Test that message correlation works for any IDs."""
    # Test logic
    pass
```

### Test Organization

- Place tests in `tests/` directory
- Name test files `test_*.py`
- Name test functions `test_*`
- Group related tests in classes
- Use descriptive test names

## Logging

Use structured logging:

```python
from mcp_proxy.logging_config import get_logger

logger = get_logger(__name__)

logger.info("processing_request", request_id=123, method="tools/list")
logger.error("authentication_failed", error=str(e))
```

## Debugging

### Enable Debug Logging

```python
from mcp_proxy.logging_config import configure_logging

configure_logging(log_level="debug")
```

### Using Python Debugger

```python
import pdb; pdb.set_trace()  # Set breakpoint
```

### VS Code Debug Configuration

Create `.vscode/launch.json`:

```json
{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Python: Current File",
            "type": "python",
            "request": "launch",
            "program": "${file}",
            "console": "integratedTerminal",
            "justMyCode": false
        },
        {
            "name": "Python: Pytest",
            "type": "python",
            "request": "launch",
            "module": "pytest",
            "args": ["-v"],
            "console": "integratedTerminal",
            "justMyCode": false
        }
    ]
}
```

## Common Development Tasks

### Adding a New Model

1. Define model in `src/mcp_proxy/models.py`
2. Add validation using Pydantic validators
3. Export from `src/mcp_proxy/__init__.py`
4. Write tests in `tests/test_models.py`
5. Update documentation

### Adding a New Exception

1. Define exception in `src/mcp_proxy/exceptions.py`
2. Inherit from appropriate base exception
3. Export from `src/mcp_proxy/__init__.py`
4. Update error code mapping if needed
5. Document when it's raised

### Adding a New Component

1. Create module directory under `src/mcp_proxy/`
2. Define protocol interface in `protocols.py`
3. Implement concrete class in module
4. Write unit tests
5. Write integration tests
6. Update documentation

## Git Workflow

### Commit Messages

Use conventional commit format:

```
type(scope): brief description

Longer description if needed

- Bullet points for details
- Reference issues: #123
```

Types:
- `feat`: New feature
- `fix`: Bug fix
- `docs`: Documentation
- `test`: Tests
- `refactor`: Code refactoring
- `style`: Code style changes
- `chore`: Maintenance tasks

### Branch Naming

- `feature/description`: New features
- `fix/description`: Bug fixes
- `docs/description`: Documentation
- `test/description`: Tests

## Troubleshooting

### Import Errors

If you get import errors, ensure the package is installed in editable mode:

```bash
pip install -e .
```

### Test Failures

1. Check test output for specific failure
2. Run single test: `pytest tests/test_file.py::test_name -v`
3. Enable debug logging in test
4. Use debugger to step through code

### Type Checking Errors

1. Ensure all functions have type hints
2. Check for missing imports
3. Use `# type: ignore` for known issues (sparingly)
4. Update type stubs if needed

## Resources

- [Pydantic Documentation](https://docs.pydantic.dev/)
- [Pytest Documentation](https://docs.pytest.org/)
- [Hypothesis Documentation](https://hypothesis.readthedocs.io/)
- [Structlog Documentation](https://www.structlog.org/)
- [aiohttp Documentation](https://docs.aiohttp.org/)
- [JSON-RPC 2.0 Specification](https://www.jsonrpc.org/specification)
- [OAuth 2.0 DCR (RFC 7591)](https://tools.ietf.org/html/rfc7591)

## Getting Help

- Check existing documentation
- Review test examples
- Ask in team chat
- Create an issue for bugs or feature requests
