#!/usr/bin/env nu
# VAPORA CI/CD Pipeline Integration
# Validates, builds, and tests deployment artifacts
# Designed for GitHub Actions, GitLab CI, Jenkins integration
# Version: 1.0.0

def main [
    --mode: string = "multiuser"
    --artifact-dir: string = "artifacts"
    --test-deploy: bool = false
] {
    let start_time = (date now)
    print "🔧 VAPORA CI/CD Pipeline"
    print $"Mode: ($mode) | Artifact Dir: ($artifact_dir)"
    print $"Timestamp: ($start_time | format date '%Y-%m-%d %H:%M:%S')"
    print ""

    # Step 1: Validate Nickel configurations
    print "Step 1️⃣  - Validating Nickel configurations..."
    validate-nickel-configs

    # Step 2: Generate configurations
    print "Step 2️⃣  - Generating configurations..."
    generate-all-configs $artifact_dir

    # Step 3: Validate all outputs
    print "Step 3️⃣  - Validating all outputs..."
    validate-all-outputs $artifact_dir

    # Step 4: Render templates
    print "Step 4️⃣  - Rendering templates..."
    render-all-templates $artifact_dir

    # Step 5: Test deployment artifacts
    if $test_deploy {
        print "Step 5️⃣  - Testing deployment (dry-run)..."
        test-deployment-artifacts $artifact_dir
    }

    # Step 6: Generate reports
    print "Step 6️⃣  - Generating reports..."
    generate-reports $artifact_dir

    let end_time = (date now)
    let duration = ($end_time - $start_time)

    print ""
    print "✅ CI/CD Pipeline Complete"
    print $"Duration: ($duration)"
    print $"Artifacts: ($artifact_dir)"
}

def validate-nickel-configs: nothing {
    print "  🔍 Checking Nickel configurations..."

    let configs = [
        "schemas/vapora/main.ncl"
        "schemas/vapora/backend.ncl"
        "schemas/vapora/agents.ncl"
        "schemas/vapora/llm-router.ncl"
        "schemas/platform/common/helpers.ncl"
        "schemas/platform/schemas/common/server.ncl"
        "schemas/platform/schemas/common/database.ncl"
        "schemas/platform/schemas/common/monitoring.ncl"
        "schemas/platform/schemas/common/security.ncl"
        "schemas/platform/schemas/common/storage.ncl"
        "schemas/platform/configs/vapora-solo.ncl"
        "schemas/platform/configs/vapora-multiuser.ncl"
        "schemas/platform/configs/vapora-enterprise.ncl"
    ]

    $configs | each { |config|
        print $"    → ($config)"
        let result = do {
            nickel typecheck $config
        } | complete

        if $result.exit_code != 0 {
            error make {msg: $"Typecheck failed: ($result.stderr)"}
        }
        print $"      ✓ Valid"
    }

    print "  ✓ All Nickel configurations valid"
}

def generate-all-configs [artifact_dir: string] {
    print "  🔨 Generating configurations for all modes..."

    let modes = ["solo", "multiuser", "enterprise"]

    $modes | each { |mode|
        print $"    → ($mode) mode"

        let result = do {
            nickel export $"schemas/platform/configs/vapora-($mode).ncl"
        } | complete

        if $result.exit_code != 0 {
            error make {msg: $"Export failed for ($mode): ($result.stderr)"}
        }

        let output_path = ($artifact_dir | path join $"config-($mode).json")

        do {
            $result.stdout | save -f $output_path
        } | complete | if $in.exit_code != 0 {
            error make {msg: $"Failed to save config-($mode).json"}
        }

        print $"      ✓ Generated"
    }

    print "  ✓ All configurations generated"
}

def validate-all-outputs [artifact_dir: string] {
    print "  ✅ Validating all JSON outputs..."

    let json_files = [
        "config-solo.json"
        "config-multiuser.json"
        "config-enterprise.json"
    ]

    $json_files | each { |file|
        let path = ($artifact_dir | path join $file)

        if not ($path | path exists) {
            error make {msg: $"Missing file: ($file)"}
        }

        let result = do {
            open $path | to json
        } | complete

        if $result.exit_code != 0 {
            error make {msg: $"Invalid JSON: ($file)"}
        }

        print $"    ✓ ($file) valid"
    }

    print "  ✓ All JSON outputs valid"
}

def render-all-templates [artifact_dir: string] {
    print "  🎨 Rendering Jinja2 templates..."

    let modes = ["solo", "multiuser", "enterprise"]

    $modes | each { |mode|
        let config_path = ($artifact_dir | path join $"config-($mode).json")

        # TOML
        print $"    → ($mode): TOML"
        let toml_result = do {
            jinja2 schemas/platform/templates/configs/vapora.toml.j2 $config_path
        } | complete

        if $toml_result.exit_code != 0 {
            error make {msg: $"TOML rendering failed: ($toml_result.stderr)"}
        }

        do {
            $toml_result.stdout | save -f ($artifact_dir | path join $"vapora-($mode).toml")
        } | complete | if $in.exit_code != 0 {
            error make {msg: "Failed to save TOML"}
        }

        # YAML
        print $"    → ($mode): YAML"
        let yaml_result = do {
            jinja2 schemas/platform/templates/configs/vapora.yaml.j2 $config_path
        } | complete

        if $yaml_result.exit_code != 0 {
            error make {msg: $"YAML rendering failed: ($yaml_result.stderr)"}
        }

        do {
            $yaml_result.stdout | save -f ($artifact_dir | path join $"vapora-($mode).yaml")
        } | complete | if $in.exit_code != 0 {
            error make {msg: "Failed to save YAML"}
        }
    }

    # Kubernetes templates (for all modes, they're the same ConfigMap/Deployment pattern)
    print "    → Kubernetes: ConfigMap"
    let config_path = ($artifact_dir | path join "config-enterprise.json")
    let cm_result = do {
        jinja2 schemas/platform/templates/kubernetes/configmap.yaml.j2 $config_path
    } | complete

    if $cm_result.exit_code != 0 {
        error make {msg: $"ConfigMap rendering failed: ($cm_result.stderr)"}
    }

    do {
        $cm_result.stdout | save -f ($artifact_dir | path join "configmap.yaml")
    } | complete | if $in.exit_code != 0 {
        error make {msg: "Failed to save ConfigMap"}
    }

    print "    → Kubernetes: Deployment"
    let deploy_result = do {
        jinja2 schemas/platform/templates/kubernetes/deployment.yaml.j2 $config_path
    } | complete

    if $deploy_result.exit_code != 0 {
        error make {msg: $"Deployment rendering failed: ($deploy_result.stderr)"}
    }

    do {
        $deploy_result.stdout | save -f ($artifact_dir | path join "deployment.yaml")
    } | complete | if $in.exit_code != 0 {
        error make {msg: "Failed to save Deployment"}
    }

    # Docker Compose
    print "    → Docker Compose"
    let docker_path = ($artifact_dir | path join "config-solo.json")
    let dc_result = do {
        jinja2 schemas/platform/templates/docker-compose/docker-compose.yaml.j2 $docker_path
    } | complete

    if $dc_result.exit_code != 0 {
        error make {msg: $"Docker Compose rendering failed: ($dc_result.stderr)"}
    }

    do {
        $dc_result.stdout | save -f ($artifact_dir | path join "docker-compose.yml")
    } | complete | if $in.exit_code != 0 {
        error make {msg: "Failed to save Docker Compose"}
    }

    print "  ✓ All templates rendered"
}

def test-deployment-artifacts [artifact_dir: string] {
    print "  🧪 Testing deployment artifacts (dry-run)..."

    # Validate YAML with yq
    print "    → Validating YAML syntax..."
    let yaml_files = [
        "vapora-solo.yaml"
        "vapora-multiuser.yaml"
        "vapora-enterprise.yaml"
        "configmap.yaml"
        "deployment.yaml"
        "docker-compose.yml"
    ]

    $yaml_files | each { |file|
        let path = ($artifact_dir | path join $file)

        if ($path | path exists) {
            let result = do {
                yq eval '.' $path
            } | complete

            if $result.exit_code != 0 {
                error make {msg: $"Invalid YAML in ($file)"}
            }
            print $"      ✓ ($file)"
        }
    }

    # Test Kubernetes manifests with kubectl dry-run
    print "    → Testing Kubernetes manifests..."
    let cm_path = ($artifact_dir | path join "configmap.yaml")
    let deploy_path = ($artifact_dir | path join "deployment.yaml")

    if ($cm_path | path exists) {
        let result = do {
            kubectl apply -f $cm_path --dry-run=client
        } | complete

        if $result.exit_code != 0 {
            error make {msg: $"Invalid Kubernetes ConfigMap: ($result.stderr)"}
        }
        print "      ✓ ConfigMap (dry-run passed)"
    }

    if ($deploy_path | path exists) {
        let result = do {
            kubectl apply -f $deploy_path --dry-run=client
        } | complete

        if $result.exit_code != 0 {
            error make {msg: $"Invalid Kubernetes Deployment: ($result.stderr)"}
        }
        print "      ✓ Deployment (dry-run passed)"
    }

    print "  ✓ All tests passed"
}

def generate-reports [artifact_dir: string] {
    print "  📋 Generating CI/CD reports..."

    # Generate manifest
    let manifest_path = ($artifact_dir | path join "MANIFEST.md")

    let report = @"
# VAPORA Deployment Artifacts

Generated: (date now | format date '%Y-%m-%d %H:%M:%S')

## Files Generated

### Configurations
- config-solo.json
- config-multiuser.json
- config-enterprise.json

### TOML Outputs
- vapora-solo.toml
- vapora-multiuser.toml
- vapora-enterprise.toml

### YAML Outputs
- vapora-solo.yaml
- vapora-multiuser.yaml
- vapora-enterprise.yaml

### Kubernetes Manifests
- configmap.yaml
- deployment.yaml

### Docker Compose
- docker-compose.yml

## Deployment Modes

| Mode | Solo | Multiuser | Enterprise |
|------|------|-----------|------------|
| Host | 127.0.0.1 | 0.0.0.0 | 0.0.0.0 |
| Workers | 2 | 4 | 8 |
| NATS | disabled | enabled | enabled |
| Cost Tracking | disabled | enabled | enabled |
| Max Agents | 3 | 10 | 50 |

## Status

✅ All configurations generated
✅ All templates rendered
✅ All outputs validated
"@

    do {
        $report | save -f $manifest_path
    } | complete | if $in.exit_code != 0 {
        print "  ⚠️  Failed to save manifest"
    } else {
        print $"  ✓ Manifest: ($manifest_path)"
    }

    # List all artifacts
    print "  📦 Artifacts summary:"
    let artifacts = do {
        ls $artifact_dir -la
    } | complete

    if $artifacts.exit_code == 0 {
        $artifacts.stdout | lines | each { |line|
            if ($line | str contains ".json") or ($line | str contains ".yaml") or ($line | str contains ".toml") or ($line | str contains ".yml") {
                print $"    • ($line)"
            }
        }
    }
}

# Run main function
main
