# Example Imperative Plugin

This plugin demonstrates the **imperative pattern** with direct vARC executor calls.

## Pattern Overview

| Aspect | Implementation |
|--------|----------------|
| Template | None - all logic in PowerShell |
| Actions | Direct Invoke-vSEAL*Action calls |
| Baseline | Manual Add-vSEALBaselineEntry calls |
| Control | Full PowerShell control flow |

## When to Use

Use the imperative pattern when:

- Actions depend on previous results
- Custom logic needed between actions
- Complex branching or loops required
- Dynamic values computed at runtime
- You need maximum flexibility

## Pattern vs Alternatives

| Pattern | Config | Flexibility | Complexity |
|---------|--------|-------------|------------|
| **Declarative** | TOML only | Low | Lowest |
| **Hybrid** | TOML + PS | Medium | Medium |
| **Imperative** | PS only | Highest | Highest |

## Executor Reference

| Function | Use For | Example |
|----------|---------|---------|
| `Invoke-vSEALRegistryAction` | Set/Delete registry values | `-Action Set -Key 'HKLM:\...' -Name 'Value' -Data 1 -Type DWord` |
| `Invoke-vSEALServiceAction` | Change service start mode | `-Name 'ServiceName' -StartMode Disabled` |
| `Invoke-vSEALTaskAction` | Enable/Disable scheduled tasks | `-Name '\Path\TaskName' -Action Disable` |
| `Invoke-vSEALCommandAction` | Run shell commands | `-Command 'cmd /c ...' -Timeout 60` |

## Executor Return Structure

All executors return a consistent object:

```powershell
[PSCustomObject]@{
    Action         = 'registry.set'           # Action type
    Target         = 'HKLM:\...\ValueName'    # What was modified
    Status         = 'Success'                # Success/Failed/Skipped/Timeout
    Message        = $null                    # Error message if applicable
    Baseline       = @{ Data = ...; Type = ...}  # Original state
    Duration       = 42                       # Milliseconds
    ExitCode       = 0                        # Process exit code (command executor)
    RebootRequired = $false                   # True if exit code indicates reboot needed (e.g., 3010)
}
```

## Status Values

| Status | Meaning | Action |
|--------|---------|--------|
| `Success` | Action completed successfully | Capture baseline |
| `Failed` | Error occurred | Log warning, decide if critical |
| `Skipped` | Target doesn't exist | Often expected (mock scenarios) |
| `Timeout` | Command exceeded timeout | Log warning (command executor only) |

## Baseline Capture

**Critical pattern:** Capture baseline AFTER each successful action.

```powershell
$result = Invoke-vSEALRegistryAction -Action Set -Key '...' -Name 'Value' -Data 1 -Type DWord

if ($result.Status -eq 'Success') {
    Add-vSEALBaselineEntry -PluginId $pluginId `
        -Type Registry `
        -Target $result.Target `
        -OriginalValue $result.Baseline `
        -AppliedValue @{ Data = 1; Type = 'DWord' }
}
```

### Baseline Parameters

| Parameter | Description |
|-----------|-------------|
| `-PluginId` | Plugin folder name (e.g., 'example-imperative') |
| `-Type` | Registry, Service, Task, Command, or Custom |
| `-Target` | Resource identifier (path, service name, etc.) |
| `-OriginalValue` | State before modification (from result.Baseline) |
| `-AppliedValue` | What was set/changed |
| `-DidNotExist` | Switch - resource was created, not modified |
| `-Metadata` | Additional fields (e.g., RollbackCommand) |

## Conditional Logic Example

The imperative pattern enables complex decision making:

```powershell
# Only run secondary action if first succeeded
if ($regResult1.Status -eq 'Success') {
    $regResult2 = Invoke-vSEALRegistryAction -Action Set `
        -Key "$registryPrefix" `
        -Name 'DependentSetting' `
        -Data 1 `
        -Type DWord

    if ($regResult2.Status -eq 'Success') {
        Add-vSEALBaselineEntry -PluginId $pluginId ...
    }
}
```

## Key Points

1. **Most verbose** - requires explicit executor calls for each action
2. **Most flexible** - full PowerShell control flow available
3. **Manual baseline** - you must capture baselines yourself
4. **PluginId format** - the plugin folder name (e.g., 'example-imperative')

## See Also

- `example-declarative/plugin.ps1` - TOML-only pattern (simplest)
- `example-hybrid/plugin.ps1` - TOML + custom PS (balanced)
- Phase 17 design: vARC executor specifications
