#!/usr/bin/env nu
# Infrastructure Configuration Generation Script
# Generates Docker Compose, Kubernetes, Nginx, and other infrastructure configs
# from Nickel schemas for all deployment modes (solo, multiuser, enterprise)

use std log

def main [--mode: string = "all", --format: string = "all", --output-dir: string = "."] {
    let modes = if $mode == "all" {
        ["solo", "multiuser", "enterprise", "cicd"]
    } else {
        [$mode]
    }

    let formats = if $format == "all" {
        ["yaml", "json", "conf", "service"]
    } else {
        [$format]
    }

    let schema_base = "provisioning/schemas/infrastructure"
    let output_base = $output_dir

    log info $"Generating infrastructure configs for modes: ($modes | str join ', ')"
    log info $"Formats: ($formats | str join ', ')"
    log info $"Output directory: ($output_base)"

    # Create output directories
    [docker-compose kubernetes nginx prometheus systemd oci-registry] | each { |dir|
        try {
            mkdir $"($output_base)/($dir)"
        } catch { }
    }

    # 1. Generate Docker Compose configurations
    if ($formats | any { |f| $f == "yaml" or $f == "json" }) {
        log info "Generating Docker Compose configurations..."
        for mode in $modes {
            generate_docker_compose $mode $schema_base $output_base $formats
        }
    }

    # 2. Generate Kubernetes manifests
    if ($formats | any { |f| $f == "yaml" or $f == "json" }) {
        log info "Generating Kubernetes manifests..."
        for mode in $modes {
            generate_kubernetes $mode $schema_base $output_base $formats
        }
    }

    # 3. Generate Nginx configurations
    if ($formats | any { |f| $f == "conf" or $f == "json" }) {
        log info "Generating Nginx configurations..."
        for mode in $modes {
            generate_nginx $mode $schema_base $output_base $formats
        }
    }

    # 4. Generate Prometheus configurations
    if ($formats | any { |f| $f == "yaml" or $f == "json" }) {
        log info "Generating Prometheus configurations..."
        for mode in $modes {
            generate_prometheus $mode $schema_base $output_base $formats
        }
    }

    # 5. Generate Systemd service units
    if ($formats | any { |f| $f == "service" or $f == "json" }) {
        log info "Generating Systemd service units..."
        for mode in $modes {
            generate_systemd $mode $schema_base $output_base $formats
        }
    }

    # 6. Generate OCI Registry configurations
    if ($formats | any { |f| $f == "json" or $f == "yaml" }) {
        log info "Generating OCI Registry configurations..."
        for mode in $modes {
            generate_oci_registry $mode $schema_base $output_base $formats
        }
    }

    log info "✅ Infrastructure configuration generation complete!"
    log info $"Generated files: ($output_base)"
}

def generate_docker_compose [mode: string, schema_base: string, output_base: string, formats: list<string>] {
    let schema_file = $"($schema_base)/docker-compose.ncl"

    if ($formats | any { |f| $f == "yaml" }) {
        log info $"  Generating docker-compose.($mode).yaml..."
        try {
            nickel export --format yaml $schema_file
                | save $"($output_base)/docker-compose/docker-compose.($mode).yaml"
        } catch {|e|
            log error $"Failed to generate docker-compose.($mode).yaml: ($e.msg)"
        }
    }

    if ($formats | any { |f| $f == "json" }) {
        log info $"  Generating docker-compose.($mode).json..."
        try {
            nickel export --format json $schema_file
                | save $"($output_base)/docker-compose/docker-compose.($mode).json"
        } catch {|e|
            log error $"Failed to generate docker-compose.($mode).json: ($e.msg)"
        }
    }
}

def generate_kubernetes [mode: string, schema_base: string, output_base: string, formats: list<string>] {
    let schema_file = $"($schema_base)/kubernetes.ncl"
    let mode_subdir = $"($output_base)/kubernetes/($mode)"

    try {
        mkdir $mode_subdir
    } catch { }

    if ($formats | any { |f| $f == "yaml" }) {
        log info $"  Generating kubernetes/($mode)/deployment.yaml..."
        try {
            nickel export --format yaml $schema_file
                | save $"($mode_subdir)/deployment.yaml"
        } catch {|e|
            log error $"Failed to generate kubernetes manifest: ($e.msg)"
        }
    }
}

def generate_nginx [mode: string, schema_base: string, output_base: string, formats: list<string>] {
    let schema_file = $"($schema_base)/nginx.ncl"

    if ($formats | any { |f| $f == "json" }) {
        log info $"  Generating nginx.($mode).json..."
        try {
            nickel export --format json $schema_file
                | save $"($output_base)/nginx/nginx.($mode).json"
        } catch {|e|
            log error $"Failed to generate nginx config: ($e.msg)"
        }
    }
}

def generate_prometheus [mode: string, schema_base: string, output_base: string, formats: list<string>] {
    let schema_file = $"($schema_base)/prometheus.ncl"

    if ($formats | any { |f| $f == "yaml" }) {
        log info $"  Generating prometheus.($mode).yml..."
        try {
            nickel export --format yaml $schema_file
                | save $"($output_base)/prometheus/prometheus.($mode).yml"
        } catch {|e|
            log error $"Failed to generate prometheus config: ($e.msg)"
        }
    }
}

def generate_systemd [mode: string, schema_base: string, output_base: string, formats: list<string>] {
    let schema_file = $"($schema_base)/systemd.ncl"

    if ($formats | any { |f| $f == "json" }) {
        log info $"  Generating systemd.($mode).json..."
        try {
            nickel export --format json $schema_file
                | save $"($output_base)/systemd/systemd.($mode).json"
        } catch {|e|
            log error $"Failed to generate systemd units: ($e.msg)"
        }
    }
}

def generate_oci_registry [mode: string, schema_base: string, output_base: string, formats: list<string>] {
    let schema_file = $"($schema_base)/oci-registry.ncl"

    if ($formats | any { |f| $f == "json" }) {
        log info $"  Generating oci-registry.($mode).json..."
        try {
            nickel export --format json $schema_file
                | save $"($output_base)/oci-registry/oci-registry.($mode).json"
        } catch {|e|
            log error $"Failed to generate OCI registry config: ($e.msg)"
        }
    }
}
