# Smart Defaults

This document describes Fetch ML's smart defaults system, which automatically adapts configuration based on the runtime environment.

## Overview

Smart defaults eliminate the need for manual configuration tweaks when running in different environments:

- **Local Development**: Optimized for developer machines with sensible paths and localhost services
- **Container Environments**: Uses container-friendly hostnames and paths
- **CI/CD**: Optimized for automated testing with fast polling and minimal resource usage
- **Production**: Uses production-ready defaults with proper security and scaling

## Environment Detection

The system automatically detects the environment based on:

1. **CI Detection**: Checks for `CI`, `GITHUB_ACTIONS`, `GITLAB_CI` environment variables
2. **Container Detection**: Looks for `/.dockerenv`, `KUBERNETES_SERVICE_HOST`, or `CONTAINER` variables
3. **Production Detection**: Checks `FETCH_ML_ENV=production` or `ENV=production`
4. **Default**: Falls back to local development

## Default Values by Environment

### Host Configuration
- **Local**: `localhost`
- **Container/CI**: `host.docker.internal` (Docker Desktop/Colima)
- **Production**: `0.0.0.0`

### Base Paths
- **Local**: `~/ml-experiments`
- **Container/CI**: `/workspace/ml-experiments`
- **Production**: `/var/lib/fetch_ml/experiments`

### Data Directory
- **Local**: `~/ml-data`
- **Container/CI**: `/workspace/data`
- **Production**: `/var/lib/fetch_ml/data`

### Redis Address
- **Local**: `localhost:6379`
- **Container/CI**: `redis:6379` (service name)
- **Production**: `redis:6379`

### SSH Configuration
- **Local**: `~/.ssh/id_rsa` and `~/.ssh/known_hosts`
- **Container/CI**: `/workspace/.ssh/id_rsa` and `/workspace/.ssh/known_hosts`
- **Production**: `/etc/fetch_ml/ssh/id_rsa` and `/etc/fetch_ml/ssh/known_hosts`

### Worker Configuration
- **Local**: 2 workers, 5-second poll interval
- **CI**: 1 worker, 1-second poll interval (fast testing)
- **Production**: CPU core count workers, 10-second poll interval

### Log Levels
- **Local**: `info`
- **CI**: `debug` (verbose for debugging)
- **Production**: `info`

## Usage

### In Configuration Loaders

```go
// Get smart defaults for current environment
smart := config.GetSmartDefaults()

// Use smart defaults
if cfg.Host == "" {
    cfg.Host = smart.Host()
}
if cfg.BasePath == "" {
    cfg.BasePath = smart.BasePath()
}
```

### Environment Overrides

Smart defaults can be overridden with environment variables:

- `FETCH_ML_HOST` - Override host
- `FETCH_ML_BASE_PATH` - Override base path
- `FETCH_ML_REDIS_ADDR` - Override Redis address
- `FETCH_ML_ENV` - Force environment profile

### Manual Environment Selection

You can force a specific environment:

```bash
# Force production mode
export FETCH_ML_ENV=production

# Force container mode
export CONTAINER=true
```

## Implementation Details

The smart defaults system is implemented in `internal/config/smart_defaults.go`:

- `DetectEnvironment()` - Determines current environment profile
- `SmartDefaults` struct - Provides environment-aware defaults
- Helper methods for each configuration value

## Migration Guide

### For Users

No changes required - existing configurations continue to work. Smart defaults only apply when values are not explicitly set.

### For Developers

When adding new configuration options:

1. Add a method to `SmartDefaults` struct
2. Use the smart default in config loaders
3. Document the environment-specific values

Example:

```go
// Add to SmartDefaults struct
func (s *SmartDefaults) NewFeature() string {
    switch s.Profile {
    case ProfileContainer, ProfileCI:
        return "/workspace/new-feature"
    case ProfileProduction:
        return "/var/lib/fetch_ml/new-feature"
    default:
        return "./new-feature"
    }
}

// Use in config loader
if cfg.NewFeature == "" {
    cfg.NewFeature = smart.NewFeature()
}
```

## Testing

To test different environments:

```bash
# Test local defaults (default)
./bin/worker

# Test container defaults
export CONTAINER=true
./bin/worker

# Test CI defaults
export CI=true
./bin/worker

# Test production defaults
export FETCH_ML_ENV=production
./bin/worker
```

## Troubleshooting

### Wrong Environment Detection

Check environment variables:

```bash
echo "CI: $CI"
echo "CONTAINER: $CONTAINER"
echo "FETCH_ML_ENV: $FETCH_ML_ENV"
```

### Path Issues

Smart defaults expand `~` and environment variables automatically. If paths don't work as expected:

1. Check the detected environment: `config.GetSmartDefaults().GetEnvironmentDescription()`
2. Verify the path exists in the target environment
3. Override with environment variable if needed

### Container Networking

For container environments, ensure:
- Redis service is named `redis` in docker-compose
- Host networking is configured properly
- `host.docker.internal` resolves (Docker Desktop/Colima)
