# Services Package

The services package provides a clean, protocol-based architecture for all Trax platform services. This design ensures testability, maintainability, and easy service composition.

## Architecture Overview

### Protocol-Based Design

All services implement well-defined protocols using Python's `Protocol` class. This enables:

- **Easy Testing**: Mock implementations can be swapped in for testing
- **Service Composition**: Services can be combined and configured flexibly
- **Dependency Injection**: Clean separation of concerns and easy testing
- **Interface Stability**: Clear contracts between service layers

### Service Hierarchy

```
Services Package
├── protocols.py          # All service protocol definitions
├── factories.py          # Service factory functions
├── mocks.py             # Mock implementations for testing
├── __init__.py          # Package exports
├── youtube_service.py    # YouTube metadata service
├── media_service.py      # Media processing service
├── transcription_service.py # Audio transcription service
├── enhancement/          # AI enhancement services
└── export_service.py     # Export and formatting services
```

## Core Services

### YouTube Service

Extracts metadata from YouTube videos.

```python
from src.services import create_youtube_service

# Create service with default configuration
youtube_service = create_youtube_service()

# Extract metadata from a video
metadata = await youtube_service.extract_metadata("https://youtube.com/watch?v=...")

# Batch extract from multiple videos
results = await youtube_service.batch_extract([
    "https://youtube.com/watch?v=video1",
    "https://youtube.com/watch?v=video2"
])
```

### Media Service

Handles media download, preprocessing, and database operations.

```python
from src.services import create_media_service

media_service = create_media_service()

# Download and process media
media_file = await media_service.process_media_pipeline(
    url="https://example.com/audio.mp3",
    output_dir=Path("/tmp/output")
)

# Check file validity
is_valid = await media_service.validate_file_size(
    file_path=Path("/tmp/audio.wav"),
    max_size_mb=500
)
```

### Transcription Service

Converts audio to text using AI models.

```python
from src.services import create_transcription_service, TranscriptionConfig

transcription_service = create_transcription_service()

# Transcribe audio file
result = await transcription_service.transcribe_audio(
    audio_path=Path("/tmp/audio.wav"),
    config=TranscriptionConfig(model="whisper-large-v3")
)

# Create and manage transcription jobs
job = await transcription_service.create_transcription_job(media_file)
status = await transcription_service.get_job_status(job.id)
```

### Enhancement Service

Improves transcript quality using AI.

```python
from src.services import create_enhancement_service

enhancement_service = create_enhancement_service()

# Enhance transcript
enhanced = await enhancement_service.enhance_transcript(
    "this is a raw transcript with issues"
)

# Batch enhance multiple transcripts
results = await enhancement_service.enhance_transcript_batch([
    "transcript 1",
    "transcript 2"
])
```

### Export Service

Formats and exports transcripts in various formats.

```python
from src.services import create_export_service, ExportFormat

export_service = create_export_service()

# Export in different formats
json_result = await export_service.export_transcript(
    transcription_result,
    Path("/tmp/output.json"),
    ExportFormat.JSON
)

txt_result = await export_service.export_transcript(
    transcription_result,
    Path("/tmp/output.txt"),
    ExportFormat.TXT
)
```

### Batch Processor

Manages batch processing workflows.

```python
from src.services import create_batch_processor

batch_processor = create_batch_processor()

# Add tasks to batch
task_id = await batch_processor.add_task(
    "transcription",
    {"url": "https://youtube.com/watch?v=...", "priority": "high"}
)

# Process all tasks
await batch_processor.process_tasks(max_workers=4)

# Check progress
progress = await batch_processor.get_progress()
print(f"Completed: {progress.completed_tasks}/{progress.total_tasks}")
```

## Factory Functions

### Individual Service Creation

```python
from src.services import (
    create_youtube_service,
    create_media_service,
    create_transcription_service,
    create_enhancement_service,
    create_export_service,
    create_batch_processor
)

# Create services with default configuration
youtube_service = create_youtube_service()
media_service = create_media_service()
transcription_service = create_transcription_service()
enhancement_service = create_enhancement_service()
export_service = create_export_service()
batch_processor = create_batch_processor()
```

### Service Container Creation

```python
from src.services import create_service_container, create_minimal_service_container

# Create complete service container
services = create_service_container()
# Contains: youtube, media, transcription, enhancement, export, batch_processor

# Create minimal container for core functionality
core_services = create_minimal_service_container()
# Contains: youtube, media, transcription
```

### Custom Configuration

```python
from src.services import create_transcription_service
from src.services.protocols import TranscriptionConfig

# Create service with custom configuration
config = TranscriptionConfig(
    model="whisper-large-v3",
    language="en",
    task="transcribe",
    temperature=0.0
)

transcription_service = create_transcription_service(config=config)
```

## Testing with Mock Services

### Using Mock Services

```python
from src.services.mocks import create_mock_service_container

# Create mock services for testing
mock_services = create_mock_service_container()

# Use mock services in tests
youtube_service = mock_services["youtube_service"]
metadata = await youtube_service.extract_metadata("https://youtube.com/watch?v=...")
```

### Individual Mock Services

```python
from src.services.mocks import (
    create_mock_youtube_service,
    create_mock_media_service,
    create_mock_transcription_service
)

# Create specific mock services
mock_youtube = create_mock_youtube_service()
mock_media = create_mock_media_service()
mock_transcription = create_mock_transcription_service()
```

### Custom Mock Data

```python
from src.services.mocks import create_mock_youtube_service

# Create mock service with custom data
custom_data = {
    "title": "Custom Video Title",
    "duration": 300,
    "channel": "Custom Channel"
}

mock_service = create_mock_youtube_service(mock_data=custom_data)
metadata = await mock_service.extract_metadata("https://youtube.com/watch?v=...")
# Returns custom_data instead of default mock data
```

## Protocol Validation

### Validate Service Implementation

```python
from src.services.protocols import validate_protocol_implementation

# Check if a service implements its protocol correctly
is_valid = validate_protocol_implementation(
    youtube_service,
    YouTubeServiceProtocol
)

if not is_valid:
    print("Service does not implement protocol correctly")
```

### Get Missing Methods

```python
from src.services.protocols import get_missing_methods

# Find missing methods in a service implementation
missing = get_missing_methods(youtube_service, YouTubeServiceProtocol)

if missing:
    print(f"Missing methods: {missing}")
```

## Best Practices

### Service Composition

1. **Use Factory Functions**: Always use factory functions to create services
2. **Dependency Injection**: Pass dependencies through constructor parameters
3. **Protocol Compliance**: Ensure all services implement their protocols correctly
4. **Error Handling**: Handle errors gracefully and provide meaningful messages

### Testing

1. **Use Mock Services**: Use mock services for unit and integration tests
2. **Test Protocols**: Verify that services implement their protocols correctly
3. **Test Workflows**: Test complete workflows, not just individual methods
4. **Mock External Dependencies**: Mock external APIs and database calls

### Configuration

1. **Environment Variables**: Use environment variables for sensitive configuration
2. **Default Values**: Provide sensible defaults for all configuration options
3. **Validation**: Validate configuration values at startup
4. **Documentation**: Document all configuration options and their effects

## Error Handling

All services follow consistent error handling patterns:

```python
try:
    result = await service.operation()
except ServiceError as e:
    logger.error(f"Service operation failed: {e}")
    # Handle service-specific errors
except Exception as e:
    logger.error(f"Unexpected error: {e}")
    # Handle unexpected errors
```

## Performance Considerations

1. **Async Operations**: All I/O operations are asynchronous
2. **Progress Callbacks**: Use progress callbacks for long-running operations
3. **Batch Processing**: Use batch operations when processing multiple items
4. **Caching**: Implement appropriate caching strategies for expensive operations

## Migration Guide

### From Old Service Architecture

1. **Update Imports**: Use new factory functions instead of direct instantiation
2. **Protocol Compliance**: Ensure services implement required protocols
3. **Testing**: Update tests to use mock services
4. **Configuration**: Use new configuration patterns

### Example Migration

```python
# Old way
from src.services.youtube_service import YouTubeMetadataService
service = YouTubeMetadataService()

# New way
from src.services import create_youtube_service
service = create_youtube_service()
```

## Contributing

When adding new services:

1. **Define Protocol**: Create a protocol in `protocols.py`
2. **Implement Service**: Create concrete implementation
3. **Add Factory Function**: Add factory function in `factories.py`
4. **Create Mock**: Add mock implementation in `mocks.py`
5. **Write Tests**: Create comprehensive tests
6. **Update Documentation**: Update this README

## Support

For questions or issues:

1. Check the protocol definitions in `protocols.py`
2. Review the factory functions in `factories.py`
3. Examine the mock implementations in `mocks.py`
4. Run the test suite to verify functionality
5. Check the main project documentation
