# Development Guide

This guide covers the development workflow, testing, and best practices for the CPAP MCP Server project.

## Table of Contents

- [Development Setup](#development-setup)
- [Project Structure](#project-structure)
- [Testing](#testing)
- [Code Coverage](#code-coverage)
- [Development Workflow](#development-workflow)
- [Debugging](#debugging)
- [Working with Submodules](#working-with-submodules)
- [MCP Server Development](#mcp-server-development)
- [Performance](#performance)

## Development Setup

### Prerequisites

- Python 3.10+
- Git
- pip
- Virtual environment tool (venv, virtualenv, or conda)
- Basic understanding of MCP (Model Context Protocol)

### Initial Setup

1. **Clone the Repository with Submodules**

```bash
git clone --recursive https://github.com/dynacylabs/cpap-mcp.git
cd cpap-mcp

# If you already cloned without --recursive:
git submodule update --init --recursive
```

2. **Create Virtual Environment**

```bash
# Using venv (recommended)
python -m venv venv
source venv/bin/activate  # On Windows: venv\Scripts\activate

# Using conda
conda create -n cpap-mcp python=3.11
conda activate cpap-mcp
```

3. **Install Development Dependencies**

```bash
# Install package in editable mode
pip install -e .

# Install all development dependencies
pip install -r requirements.txt
```

4. **Verify Installation**

```bash
# Install cpap-py first (required dependency)
pip install -e submodules/cpap-py

# Run tests
./run_tests.sh unit

# Check imports
python -c "from cpap_mcp import server; print('Success!')"
```

### Important: cpap-py Dependency

The server depends on the `cpap-py` library. You must install it before running tests or the server:

```bash
# Install from submodule (development)
pip install -e submodules/cpap-py

# Or install from PyPI (if published)
pip install cpap-py
```

### IDE Setup

#### VS Code

Recommended extensions:
- Python (Microsoft)
- Pylance
- Python Test Explorer
- Coverage Gutters
- GitLens

Recommended settings (`.vscode/settings.json`):

```json
{
    "python.testing.pytestEnabled": true,
    "python.testing.unittestEnabled": false,
    "python.linting.enabled": true,
    "python.linting.ruffEnabled": true,
    "python.formatting.provider": "black",
    "python.analysis.typeCheckingMode": "basic",
    "editor.formatOnSave": true,
    "editor.rulers": [100],
    "python.testing.pytestArgs": ["tests"]
}
```

#### PyCharm

1. Mark `src/` as Sources Root
2. Enable pytest as test runner
3. Configure Python 3.10+ interpreter
4. Enable type checking
5. Set Black as code formatter

## Project Structure

```
cpap-mcp/
├── src/
│   └── cpap_mcp/
│       ├── __init__.py
│       └── server.py          # Main MCP server implementation
├── tests/
│   ├── __init__.py
│   ├── conftest.py            # Pytest fixtures and configuration
│   ├── test_init.py           # Package initialization tests
│   └── test_server.py         # Server functionality tests
├── examples/
│   ├── encode_file.py         # Helper to encode CPAP files
│   └── test_client.py         # Example MCP client
├── submodules/
│   └── cpap-py/               # CPAP data parsing library
│       └── src/
│           └── cpap_py/       # Python package for CPAP data
├── pyproject.toml             # Project configuration
├── pytest.ini                 # Pytest configuration
├── requirements.txt           # Development dependencies
├── run_tests.sh              # Test runner script
├── INSTALL.md                # Installation instructions
├── CONTRIBUTING.md           # Contribution guidelines
├── DEVELOPMENT.md            # This file
├── README.md                 # Project overview
└── USAGE.md                  # Usage examples and guide

```

### Key Components

**`server.py`**: Main MCP server implementation
- Tool definitions (upload_file, list_sessions, etc.)
- Request handlers
- CPAP data processing logic

**`tests/`**: Test suite
- Unit tests for individual functions
- Integration tests for full workflows
- Test fixtures and mock data

**`submodules/cpap-py/`**: CPAP data parsing library
- ResMed device support
- Session data parsing
- Event detection

## Testing

### Test Organization

Tests are organized by type using pytest markers:

- **Unit tests** (`@pytest.mark.unit`): Fast, isolated tests with mocked dependencies
- **Integration tests** (`@pytest.mark.integration`): Tests with real CPAP data
- **Slow tests** (`@pytest.mark.slow`): Long-running tests

### Running Tests

```bash
# Run all tests
./run_tests.sh all

# Run only unit tests (fast - recommended during development)
./run_tests.sh unit

# Run integration tests
./run_tests.sh integration

# Run specific test file
./run_tests.sh tests/test_server.py

# Run specific test
./run_tests.sh -k test_upload_file

# Run with verbose output
pytest tests/ -v

# Run with print statements visible
pytest tests/ -v -s
```

### Writing Tests

#### Unit Test Example

```python
import pytest
from cpap_mcp.server import serialize_datetime
from datetime import datetime

# Mark as unit test
pytestmark = pytest.mark.unit

def test_serialize_datetime():
    """Test datetime serialization."""
    dt = datetime(2024, 1, 1, 12, 30)
    result = serialize_datetime(dt)
    assert result == "2024-01-01T12:30:00"
```

#### Async Test Example

```python
import pytest

@pytest.mark.asyncio
async def test_async_tool():
    """Test async MCP tool."""
    from cpap_mcp.server import list_tools
    
    tools = await list_tools()
    assert len(tools) > 0
```

#### Using Fixtures

```python
def test_with_temp_dir(temp_dir):
    """Test using temp directory fixture."""
    test_file = temp_dir / "test.txt"
    test_file.write_text("test data")
    assert test_file.exists()
```

### Test Coverage

```bash
# Run tests with coverage
./run_tests.sh coverage

# View HTML coverage report
open htmlcov/index.html  # macOS
xdg-open htmlcov/index.html  # Linux

# Show coverage in terminal
pytest tests/ --cov=cpap_mcp --cov-report=term-missing
```

Coverage goals:
- **Overall**: >80%
- **New features**: >90%
- **Critical paths**: 100%

## Code Coverage

### Checking Coverage

```bash
# Generate coverage report
coverage run -m pytest tests/
coverage report

# Generate HTML report
coverage html
```

### Improving Coverage

1. Identify uncovered lines: `coverage report -m`
2. Write tests for uncovered code
3. Focus on critical paths first
4. Consider edge cases

## Development Workflow

### 1. Create a Branch

```bash
git checkout -b feature/my-new-feature
```

### 2. Make Changes

Edit code following project style guidelines.

### 3. Run Tests Frequently

```bash
# Quick check during development
./run_tests.sh unit

# Full check before committing
./run_tests.sh all
```

### 4. Format Code

```bash
# Auto-format with Black
black src/ tests/

# Check linting
ruff check src/ tests/
```

### 5. Commit Changes

```bash
git add .
git commit -m "feat: add new MCP tool for event analysis"
```

### 6. Push and Create PR

```bash
git push origin feature/my-new-feature
# Then create PR on GitHub
```

## Debugging

### Debugging MCP Server

#### Running Server Standalone

```bash
# Run server directly
python -m cpap_mcp.server

# With debugging output
PYTHONUNBUFFERED=1 python -m cpap_mcp.server
```

#### Testing with Example Client

```bash
# Use the example client
cd examples
python test_client.py
```

#### VS Code Debugging

Add to `.vscode/launch.json`:

```json
{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Debug MCP Server",
            "type": "python",
            "request": "launch",
            "module": "cpap_mcp.server",
            "console": "integratedTerminal",
            "justMyCode": false
        },
        {
            "name": "Debug Tests",
            "type": "python",
            "request": "launch",
            "module": "pytest",
            "args": ["tests/", "-v"],
            "console": "integratedTerminal",
            "justMyCode": false
        }
    ]
}
```

### Common Issues

**Submodule not found**:
```bash
git submodule update --init --recursive
```

**Import errors**:
```bash
pip install -e .
```

**Test failures**:
```bash
# Clean test cache
rm -rf .pytest_cache __pycache__ tests/__pycache__

# Reinstall dependencies
pip install -r requirements.txt
```

## Working with Submodules

### Updating Submodules

```bash
# Update all submodules to latest
git submodule update --remote --recursive

# Update specific submodule
cd submodules/cpap-py
git pull origin main
cd ../..
git add submodules/cpap-py
git commit -m "chore: update cpap-py submodule"
```

### Making Changes to Submodules

If you need to modify `cpap-py`:

```bash
cd submodules/cpap-py
git checkout -b feature/my-change
# Make changes
git commit -m "feat: add new feature"
git push origin feature/my-change
# Create PR in cpap-py repo
```

## MCP Server Development

### Adding a New Tool

1. **Define the tool** in `list_tools()`:

```python
Tool(
    name="my_new_tool",
    description="Description of what the tool does",
    inputSchema={
        "type": "object",
        "properties": {
            "param1": {
                "type": "string",
                "description": "First parameter"
            }
        },
        "required": ["param1"]
    }
)
```

2. **Implement the handler** in `call_tool()`:

```python
elif name == "my_new_tool":
    param1 = arguments["param1"]
    result = process_data(param1)
    return [TextContent(type="text", text=json.dumps(result))]
```

3. **Write tests**:

```python
@pytest.mark.asyncio
async def test_my_new_tool():
    from cpap_mcp.server import call_tool
    
    result = await call_tool("my_new_tool", {"param1": "test"})
    assert result is not None
```

### MCP Protocol Reference

- [MCP Specification](https://spec.modelcontextprotocol.io/)
- [Python SDK Documentation](https://github.com/modelcontextprotocol/python-sdk)

## Performance

### Profiling

```bash
# Profile test execution
pytest tests/ --profile

# Profile specific function
python -m cProfile -o output.prof -m cpap_mcp.server

# Analyze profile
python -m pstats output.prof
```

### Optimization Tips

1. **Lazy loading**: Load CPAP data only when needed
2. **Caching**: Cache parsed session data
3. **Async operations**: Use async for I/O operations
4. **Batch processing**: Process multiple sessions together

### Memory Management

```bash
# Check memory usage during tests
pytest tests/ --memray

# Monitor memory in production
python -m memory_profiler cpap_mcp/server.py
```

## Code Quality

### Pre-commit Checks

Before committing, run:

```bash
# Format code
black src/ tests/

# Check linting
ruff check src/ tests/

# Run tests
./run_tests.sh all

# Check types (optional)
mypy src/
```

### Automated Checks

These checks run automatically in CI/CD:
- Code formatting (Black)
- Linting (Ruff)
- Tests (pytest)
- Coverage (pytest-cov)

## Release Process

### Version Bumping

Update version in `pyproject.toml`:

```toml
[project]
version = "0.2.0"
```

### Creating a Release

```bash
# Tag the release
git tag -a v0.2.0 -m "Release version 0.2.0"
git push origin v0.2.0

# Build distribution
python -m build

# Upload to PyPI (maintainers only)
python -m twine upload dist/*
```

## Additional Resources

- [MCP Documentation](https://modelcontextprotocol.io/)
- [cpap-py Library](../submodules/cpap-py/README.md)
- [CPAP Data Formats](https://www.apneaboard.com/wiki/index.php/OSCAR)
- [Python Testing Best Practices](https://docs.pytest.org/en/stable/goodpractices.html)

## Getting Help

- Check [GitHub Issues](https://github.com/dynacylabs/cpap-mcp/issues)
- Review [Contributing Guide](CONTRIBUTING.md)
- Read [Usage Guide](USAGE.md)
- Email: info@dynacylabs.com
