# Extension Development Quick Start Guide

This guide provides a hands-on walkthrough for developing custom extensions using the Nickel configuration system and module loader.

## Prerequisites

1. Nickel installed (1.15.0+):

   ```bash
   # macOS
   brew install nickel

   # Linux/Other
   cargo install nickel

   # Verify
   nickel --version
   ```

2. Module loader and extension tools available:

   ```bash
   ./provisioning/core/cli/module-loader --help
   ./provisioning/tools/create-extension.nu --help
   ```

## Quick Start: Creating Your First Extension

### Step 1: Create Extension from Template

```bash
# Interactive creation (recommended for beginners)
./provisioning/tools/create-extension.nu interactive

# Or direct creation
./provisioning/tools/create-extension.nu taskserv my-app \
    --author "Your Name" \
    --description "My custom application service"
```

### Step 2: Navigate and Customize

```bash
# Navigate to your new extension
cd extensions/taskservs/my-app

# View generated files
ls -la
# main.ncl - Main taskserv definition
# contracts.ncl - Configuration contract/schema
# defaults.ncl - Default values
# README.md - Documentation template
```

### Step 3: Customize Configuration

Edit `main.ncl` to match your service requirements:

```nickel
# contracts.ncl - Define the schema
{
  MyAppConfig = {
    database_url | String,
    api_key | String,
    debug_mode | Bool,
    cpu_request | String,
    memory_request | String,
    port | Number,
  }
}

# defaults.ncl - Provide sensible defaults
{
  defaults = {
    debug_mode = false,
    cpu_request = "200m",
    memory_request = "512Mi",
    port = 3000,
  }
}

# main.ncl - Combine and export
let contracts = import "./contracts.ncl" in
let defaults = import "./defaults.ncl" in

{
  defaults = defaults,
  make_config | not_exported = fun overrides =>
    defaults.defaults & overrides,
}
```

### Step 4: Test Your Extension

```bash
# Test discovery
./provisioning/core/cli/module-loader discover taskservs | grep my-app

# Validate Nickel syntax
nickel typecheck main.ncl

# Validate extension structure
./provisioning/tools/create-extension.nu validate ../../../my-app
```

### Step 5: Use in Workspace

```bash
# Create test workspace
mkdir -p /tmp/test-my-app
cd /tmp/test-my-app

# Initialize workspace
../provisioning/tools/workspace-init.nu . init

# Load your extension
../provisioning/core/cli/module-loader load taskservs . [my-app]

# Configure in servers.ncl
cat > infra/default/servers.ncl << 'EOF'
let my_app = import "../../extensions/taskservs/my-app/main.ncl" in

{
  servers = [
    {
      hostname = "app-01",
      provider = "local",
      plan = "2xCPU-4 GB",
      zone = "local",
      storages = [{ total = 25 }],
      taskservs = [
        my_app.make_config {
          database_url = "postgresql://db:5432/myapp",
          api_key = "secret-key",
          debug_mode = false,
        }
      ],
    }
  ]
}
EOF

# Test configuration
nickel export infra/default/servers.ncl
```

## Common Extension Patterns

### Database Service Extension

```bash
# Create database service
./provisioning/tools/create-extension.nu taskserv company-db \
    --author "Your Company" \
    --description "Company-specific database service"

# Customize for PostgreSQL with company settings
cd extensions/taskservs/company-db
```

Edit the schema:

```nickel
# Database service configuration schema
let CompanyDbConfig = {
  # Database settings
  database_name | String = "company_db",
  postgres_version | String = "13",

  # Company-specific settings
  backup_schedule | String = "0 2 * * *",
  compliance_mode | Bool = true,
  encryption_enabled | Bool = true,

  # Connection settings
  max_connections | Number = 100,
  shared_buffers | String = "256 MB",

  # Storage settings
  storage_size | String = "100Gi",
  storage_class | String = "fast-ssd",
} | {
  # Validation contracts
  database_name | String,
  max_connections | std.contract.from_validator (fun x => x > 0),
} in
CompanyDbConfig
```

### Monitoring Service Extension

```bash
# Create monitoring service
./provisioning/tools/create-extension.nu taskserv company-monitoring \
    --author "Your Company" \
    --description "Company-specific monitoring and alerting"
```

Customize for Prometheus with company dashboards:

```nickel
# Monitoring service configuration
let AlertManagerConfig = {
  smtp_server | String,
  smtp_port | Number = 587,
  smtp_auth_enabled | Bool = true,
} in

let CompanyMonitoringConfig = {
  # Prometheus settings
  retention_days | Number = 30,
  storage_size | String = "50Gi",

  # Company dashboards
  enable_business_metrics | Bool = true,
  enable_compliance_dashboard | Bool = true,

  # Alert routing
  alert_manager_config | AlertManagerConfig,

  # Integration settings
  slack_webhook | String | optional,
  email_notifications | Array String,
} in
CompanyMonitoringConfig
```

### Legacy System Integration

```bash
# Create legacy integration
./provisioning/tools/create-extension.nu taskserv legacy-bridge \
    --author "Your Company" \
    --description "Bridge for legacy system integration"
```

Customize for mainframe integration:

```nickel
# Legacy bridge configuration schema
let LegacyBridgeConfig = {
  # Legacy system details
  mainframe_host | String,
  mainframe_port | Number = 23,
  connection_type | [String] = "tn3270",  # "tn3270" or "direct"

  # Data transformation
  data_format | [String] = "fixed-width",  # "fixed-width", "csv", or "xml"
  character_encoding | String = "ebcdic",

  # Processing settings
  batch_size | Number = 1000,
  poll_interval_seconds | Number = 60,

  # Error handling
  retry_attempts | Number = 3,
  dead_letter_queue_enabled | Bool = true,
} in
LegacyBridgeConfig
```

## Advanced Customization

### Custom Provider Development

```bash
# Create custom cloud provider
./provisioning/tools/create-extension.nu provider company-cloud \
    --author "Your Company" \
    --description "Company private cloud provider"
```

### Complete Infrastructure Stack

```bash
# Create complete cluster configuration
./provisioning/tools/create-extension.nu cluster company-stack \
    --author "Your Company" \
    --description "Complete company infrastructure stack"
```

## Testing and Validation

### Local Testing Workflow

```bash
# 1. Create test workspace
mkdir test-workspace && cd test-workspace
../provisioning/tools/workspace-init.nu . init

# 2. Load your extensions
../provisioning/core/cli/module-loader load taskservs . [my-app, company-db]
../provisioning/core/cli/module-loader load providers . [company-cloud]

# 3. Validate loading
../provisioning/core/cli/module-loader list taskservs .
../provisioning/core/cli/module-loader validate .

# 4. Test KCL compilation
nickel export servers.ncl

# 5. Dry-run deployment
../provisioning/core/cli/provisioning server create --infra . --check
```

### Continuous Integration Testing

Create `.github/workflows/test-extensions.yml`:

```yaml
name: Test Extensions
on: [push, pull_request]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3

      - name: Install Nickel
        run: |
          curl -fsSL https://releases.nickel-lang.org/install.sh | bash
          echo "$HOME/.nickel/bin" >> $GITHUB_PATH

      - name: Install Nushell
        run: |
          curl -L https://github.com/nushell/nushell/releases/download/0.107.1/nu-0.107.1-x86_64-unknown-linux-gnu.tar.gz | tar xzf -
          sudo mv nu-0.107.1-x86_64-unknown-linux-gnu/nu /usr/local/bin/

      - name: Build core package
        run: |
          nu provisioning/tools/nickel-packager.nu build --version test

      - name: Test extension discovery
        run: |
          nu provisioning/core/cli/module-loader discover taskservs

      - name: Validate extension syntax
        run: |
          find extensions -name "*.ncl" -exec nickel typecheck {} \;

      - name: Test workspace creation
        run: |
          mkdir test-workspace
          nu provisioning/tools/workspace-init.nu test-workspace init
          cd test-workspace
          nu ../provisioning/core/cli/module-loader load taskservs . [my-app]
          nickel export servers.ncl
```

## Best Practices Summary

### 1. Extension Design

- ✅ Use descriptive names in kebab-case
- ✅ Include comprehensive validation in schemas
- ✅ Provide multiple profiles for different environments
- ✅ Document all configuration options

### 2. Dependencies

- ✅ Declare all dependencies explicitly
- ✅ Use semantic versioning
- ✅ Test compatibility with different versions

### 3. Security

- ✅ Never hardcode secrets in schemas
- ✅ Use validation to ensure secure defaults
- ✅ Follow principle of least privilege

### 4. Documentation

- ✅ Include comprehensive README
- ✅ Provide usage examples
- ✅ Document troubleshooting steps
- ✅ Maintain changelog

### 5. Testing

- ✅ Test extension discovery and loading
- ✅ Validate Nickel syntax with type checking
- ✅ Test in multiple environments
- ✅ Include CI/CD validation

## Common Issues and Solutions

### Extension Not Discovered

**Problem**: `module-loader discover` doesn't find your extension

**Solutions**:

1. Check directory structure: `extensions/taskservs/my-service/schemas/`
2. Verify `manifest.toml` exists and is valid
3. Ensure main `.ncl` file has correct name
4. Check file permissions

### Nickel Type Errors

**Problem**: Nickel type checking errors in your extension

**Solutions**:

1. Use `nickel typecheck my-service.ncl` to validate syntax
2. Check import statements are correct
3. Verify schema validation rules
4. Ensure all required fields have defaults or are provided

### Loading Failures

**Problem**: Extension loads but doesn't work correctly

**Solutions**:

1. Check generated import files: `cat taskservs.ncl`
2. Verify dependencies are satisfied
3. Test with minimal configuration first
4. Check extension manifest: `cat .manifest/taskservs.yaml`

## Next Steps

1. **Explore Examples**: Look at existing extensions in `extensions/` directory
2. **Read Advanced Docs**: Study the comprehensive guides:
   - [Nickel Packaging Guide](nickel-packaging-guide.md)
   - [Infrastructure-Specific Extensions](infrastructure-specific-extensions.md)
3. **Join Community**: Contribute to the provisioning system
4. **Share Extensions**: Publish useful extensions for others

## Support

- **Documentation**: [Package and Loader System Guide](package-and-loader-system.md)
- **Templates**: Use `./provisioning/tools/create-extension.nu list-templates`
- **Validation**: Use `./provisioning/tools/create-extension.nu validate <path>`
- **Examples**: Check `provisioning/examples/` directory

Happy extension development. 🚀
