# dvmcfggen - Answers File Usage

## Overview

The answers file feature allows you to pre-populate wizard prompts using a YAML file. This enables:

- **Batch Configuration** - Generate multiple configurations with shared defaults
- **Automation** - Integrate with deployment scripts and CI/CD pipelines
- **Reproducibility** - Save and reuse configuration templates
- **Learning** - Understand what each prompt expects

## Quick Start

### 1. Use Example Files

Example answers files are provided in the `examples/` directory:

```bash
# For conventional systems
dvmcfg wizard -a examples/conventional-answers.yml

# For trunked systems
dvmcfg wizard --type trunk -a examples/trunked-answers.yml
```

### 2. Create Your Own

Copy an example file and customize it:

```bash
cp examples/conventional-answers.yml my-config-answers.yml
vim my-config-answers.yml
dvmcfg wizard -a my-config-answers.yml
```

### 3. Run Without Answers File (Default Behavior)

The answers file is completely optional. The wizard works normally without it:

```bash
dvmcfg wizard
```

## Answers File Format

Answers files are YAML format with one key-value pair per configuration option. All fields are optional.

### Conventional System Template

```yaml
# Step 2: Basic Configuration
template: enhanced
config_dir: .
system_identity: MYSITE001
network_peer_id: 100001

# Step 3: Logging Configuration
configure_logging: true
log_path: /var/log/dvm
activity_log_path: /var/log/dvm/activity
log_root: DVM
use_syslog: false
disable_non_auth_logging: false

# Step 4: Modem Configuration
modem_type: uart
modem_mode: air
serial_port: /dev/ttyUSB0
rx_level: 50
tx_level: 50
```

### Trunked System Template

```yaml
# Step 1: System Configuration
system_name: trunked_test
base_dir: .
identity: TRUNKED001
protocol: p25
vc_count: 2

# Step 2: Logging Configuration
configure_logging: true
log_path: /var/log/dvm
activity_log_path: /var/log/dvm/activity
log_root: TRUNKED
use_syslog: false
disable_non_auth_logging: false
```

## Supported Answer Keys

### ConfigWizard (Conventional Systems)

**Basic Configuration:**
- `template` - Template name (conventional, enhanced)
- `config_dir` - Configuration directory
- `system_identity` - System identity/callsign
- `network_peer_id` - Network peer ID (integer)

**Logging Configuration:**
- `configure_logging` - Enable logging (true/false)
- `log_path` - Log file directory
- `activity_log_path` - Activity log directory
- `log_root` - Log filename prefix
- `use_syslog` - Enable syslog (true/false)
- `disable_non_auth_logging` - Disable non-authoritative logging (true/false)

**Modem Configuration:**
- `modem_type` - Modem type (uart, null)
- `modem_mode` - Modem mode (air, dfsi)
- `serial_port` - Serial port path
- `rx_level` - RX level (0-100)
- `tx_level` - TX level (0-100)

**Optional Settings:**
- `rpc_config` - Configure RPC (true/false)
- `generate_rpc_password` - Generate RPC password (true/false)
- `rest_enable` - Enable REST API (true/false)
- `generate_rest_password` - Generate REST password (true/false)
- `update_lookups` - Update lookups (true/false)
- `save_lookups` - Save lookups (true/false)
- `allow_activity_transfer` - Allow activity transfer (true/false)
- `allow_diagnostic_transfer` - Allow diagnostic transfer (true/false)
- `allow_status_transfer` - Allow status transfer (true/false)

**Protocol Configuration (for Step 8/9):**
- `dmr_color_code` - DMR color code (integer)
- `dmr_network_id` - DMR network ID (integer)
- `dmr_site_id` - DMR site ID (integer)
- `dmr_site_model` - DMR site model (small, tiny, large, huge)
- `p25_nac` - P25 NAC code (hex string)
- `p25_network_id` - P25 network ID (integer)
- `p25_system_id` - P25 system ID (integer)
- `p25_rfss_id` - P25 RFSS ID (integer)
- `p25_site_id` - P25 site ID (integer)

### TrunkingWizard (Trunked Systems)

**System Configuration:**
- `system_name` - System name
- `base_dir` - Base directory
- `identity` - System identity
- `protocol` - Protocol (p25, dmr)
- `vc_count` - Number of voice channels (integer)

**Logging Configuration:**
- `configure_logging` - Enable logging (true/false)
- `log_path` - Log file directory
- `activity_log_path` - Activity log directory
- `log_root` - Log filename prefix
- `use_syslog` - Enable syslog (true/false)
- `disable_non_auth_logging` - Disable non-authoritative logging (true/false)

**Network Settings:**
- `fne_address` - FNE address
- `fne_port` - FNE port (integer)
- `fne_password` - FNE password

**Optional Settings:**
- `base_peer_id` - Base peer ID (integer)
- `base_rpc_port` - Base RPC port (integer)
- `modem_type` - Modem type (uart, null)
- `generate_rpc_password` - Generate RPC password (true/false)
- `base_rest_port` - Base REST port (integer)
- `rest_enable` - Enable REST API (true/false)
- `generate_rest_password` - Generate REST password (true/false)

## Usage Examples

### Example 1: Single Configuration with All Defaults

```yaml
# hotspot-answers.yml
template: enhanced
config_dir: /etc/dvm/hotspot
system_identity: MY_HOTSPOT
network_peer_id: 100001
configure_logging: true
log_path: /var/log/dvm
log_root: HOTSPOT
modem_type: uart
modem_mode: air
serial_port: /dev/ttyUSB0
```

Usage:
```bash
dvmcfg wizard -a hotspot-answers.yml
```

### Example 2: Trunked System

```yaml
# trunk-p25-answers.yml
system_name: trunk_p25
base_dir: /etc/dvm/trunk
identity: TRUNK_P25
protocol: p25
vc_count: 4
configure_logging: true
log_path: /var/log/dvm
log_root: TRUNK_P25
p25_nac: 0x293
p25_network_id: 1
p25_system_id: 1
```

Usage:
```bash
dvmcfg wizard --type trunk -a trunk-p25-answers.yml
```

### Example 3: Batch Generation

Create multiple configs programmatically:

```bash
#!/bin/bash

for SITE_NUM in {1..5}; do
  SITE_ID=$((100000 + SITE_NUM))
  SITE_NAME="SITE$(printf '%03d' $SITE_NUM)"
  
  cat > /tmp/site-${SITE_NUM}-answers.yml << EOF
template: enhanced
config_dir: ./site-${SITE_NUM}
system_identity: ${SITE_NAME}
network_peer_id: ${SITE_ID}
configure_logging: true
log_root: ${SITE_NAME}
modem_type: uart
modem_mode: air
EOF
  
  dvmcfg wizard -a /tmp/site-${SITE_NUM}-answers.yml
  echo "Generated config for ${SITE_NAME}"
done
```

### Example 4: CI/CD Pipeline

```yaml
# .github/workflows/generate-test-configs.yml
name: Generate Test Configs

on: [push]

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      
      - name: Setup Python
        uses: actions/setup-python@v2
        with:
          python-version: '3.9'
      
      - name: Generate conventional config
        run: |
          python3 dvmhost/tools/dvmcfggen/dvmcfg.py wizard \
            -a examples/conventional-answers.yml
      
      - name: Generate trunked config
        run: |
          python3 dvmhost/tools/dvmcfggen/dvmcfg.py wizard \
            --type trunk \
            -a examples/trunked-answers.yml
      
      - name: Validate configs
        run: |
          python3 dvmhost/tools/dvmcfggen/dvmcfg.py validate -c config.yml
```

## Advanced Usage

### Partial Answers Files

You only need to specify the fields you want to pre-populate. Missing fields will be prompted for interactively:

```yaml
# minimal-answers.yml
system_identity: MYSITE
network_peer_id: 100001
# User will be prompted for other values
```

### Saving Generated Answers

After creating a configuration interactively, you can extract the answers:

```python
from answers_loader import AnswersLoader
from pathlib import Path

# After wizard completes
answers = {
    'template': 'enhanced',
    'system_identity': 'MYSITE001',
    'network_peer_id': 100001,
    # ... etc
}

AnswersLoader.save_answers(answers, Path('my-site-answers.yml'))
```

### Validation

Answers files are validated automatically, but you can check them manually:

```python
from answers_loader import AnswersLoader
from pathlib import Path

answers = AnswersLoader.load_answers(Path('my-answers.yml'))

# Non-strict validation (warns about unknown keys)
is_valid = AnswersLoader.validate_answers(answers, strict=False)

# Strict validation (fails on unknown keys)
is_valid = AnswersLoader.validate_answers(answers, strict=True)
```

## Key Features

### ✅ Backward Compatible
- Existing wizard usage works unchanged
- Answers file is completely optional
- No breaking changes

### ✅ Flexible
- Answer any or all questions
- Interactive prompts for missing answers
- Easy to create custom templates

### ✅ Easy to Use
- Simple YAML format
- Clear comments in example files
- Error messages for invalid files

### ✅ Reproducible
- Save and version control answers files
- Generate identical configs across systems
- Document configuration decisions

## Troubleshooting

### "Unrecognized keys in answers file"

This is a warning (not an error) if your answers file contains unknown keys. It won't stop the wizard from running. To suppress this, ensure you're only using valid keys from the lists above.

### "Error loading answers file"

Check that:
1. The file path is correct
2. The file is valid YAML (use `python3 -c "import yaml; yaml.safe_load(open('file.yml'))"`
3. The file has proper indentation (2 spaces per level)

### Answers not being used

Verify that:
1. The key name matches exactly (case-sensitive)
2. The file is being passed with `-a` or `--answers-file`
3. The value type is correct (string, integer, boolean)

## File Reference

### Core Files
- `answers_loader.py` - Utility for loading/validating answers
- `wizard.py` - ConfigWizard and TrunkingWizard classes (refactored)
- `dvmcfg.py` - CLI interface (updated with `--answers-file` support)

### Example Files
- `examples/conventional-answers.yml` - Example for conventional systems
- `examples/trunked-answers.yml` - Example for trunked systems

