# provisioning/bootstrap/install.nu
# Main bootstrap orchestrator (NO Rust required)
# Receives project root via pipeline input

# Get project root from command-line argument or input
# In Nushell scripts, arguments are passed via input when using nu <script> <arg>
let project_root = $in | default (pwd)

print "╔════════════════════════════════════════════════════════════════╗"
print "║              PROVISIONING BOOTSTRAP (Nushell)                  ║"
print "╚════════════════════════════════════════════════════════════════╝"
print ""

# ════════════════════════════════════════════════════════════════════════
# STAGE 1: SYSTEM DETECTION
# ════════════════════════════════════════════════════════════════════════

print "📊 Stage 1: System Detection"
print "─────────────────────────────────────────────────────────────────"

let system_info = (sys)
let os_type = ($system_info | get host.os_family)
let arch = ($system_info | get host.arch)
let cpu_count = ($system_info | get cpu.physical_cores | default "unknown")
let mem_gb = (($system_info | get mem.total | default 0) / (1024 * 1024 * 1024) | math round)

print $"  OS: ($os_type)"
print $"  Architecture: ($arch)"
print $"  CPU Cores: ($cpu_count)"
print $"  Memory: ($mem_gb) GB"

# Validate minimum requirements
let min_ram_gb = 2
if ($mem_gb < $min_ram_gb) {
  print $"  ❌ ERROR: Requires at least ($min_ram_gb) GB RAM (have ($mem_gb) GB)"
  exit 1
}

print "  ✅ System requirements met"
print ""

# ════════════════════════════════════════════════════════════════════════
# STAGE 2: DEPENDENCY CHECK
# ════════════════════════════════════════════════════════════════════════

print "📦 Stage 2: Checking Dependencies"
print "─────────────────────────────────────────────────────────────────"

let required_tools = [
  "git",
  "docker",
  "rustc",
  "cargo",
  "nu"
]

let missing_tools = ($required_tools | where {|tool|
  (do { which $tool } | complete).exit_code != 0
})

if ($missing_tools | is-not-empty) {
  print "  ⚠️  Missing tools:"
  $missing_tools | each {|tool| print $"    - ($tool)"}

  if ("docker" in $missing_tools) {
    print ""
    print "  📥 Docker is required. Install from: https://docs.docker.com/get-docker/"
  }

  if ("rustc" in $missing_tools) {
    print ""
    print "  📥 Rust is required. Install from: https://rustup.rs/"
    print "     Then run: rustup default stable"
  }

  print ""
  print "  ❌ Please install missing dependencies and run again"
  exit 1
}

print "  ✅ All dependencies found"

# Show versions
print ""
print "  Versions:"
let docker_version = (do { docker --version } | complete | get stdout | str trim)
print $"    Docker: ($docker_version)"

let rustc_version = (do { rustc --version } | complete | get stdout | str trim)
print $"    Rust: ($rustc_version)"

let nu_version = (do { nu --version } | complete | get stdout | str trim)
print $"    Nushell: ($nu_version)"

print ""

# ════════════════════════════════════════════════════════════════════════
# STAGE 3: CREATE DIRECTORY STRUCTURE
# ════════════════════════════════════════════════════════════════════════

print "📁 Stage 3: Creating Directory Structure"
print "─────────────────────────────────────────────────────────────────"

let workspace_name = "workspace_librecloud"
let workspace_path = ($project_root | path join $workspace_name)

# Create directories
mkdir ($workspace_path | path join "config" | path join "generated" | path join "providers") 2>/dev/null | null
mkdir ($workspace_path | path join "config" | path join "generated" | path join "platform") 2>/dev/null | null
mkdir ($workspace_path | path join ".orchestrator" | path join "data" | path join "queue") 2>/dev/null | null
mkdir ($workspace_path | path join ".kms") 2>/dev/null | null
mkdir ($workspace_path | path join ".providers") 2>/dev/null | null
mkdir ($workspace_path | path join ".taskservs") 2>/dev/null | null
mkdir ($workspace_path | path join ".clusters") 2>/dev/null | null

print "  ✅ Directory structure created"
print ""

# ════════════════════════════════════════════════════════════════════════
# STAGE 4: VALIDATE CONFIGURATION
# ════════════════════════════════════════════════════════════════════════

print "⚙️  Stage 4: Validating Configuration"
print "─────────────────────────────────────────────────────────────────"

let config_ncl = ($workspace_path | path join "config" | path join "config.ncl")

if not ($config_ncl | path exists) {
  print "  ⚠️  config.ncl not found at ($config_ncl)"
  print "  Creating default config..."

  # Use existing config.ncl if available
  let template = ($project_root | path join "workspace_librecloud" | path join "config" | path join "config.ncl")
  if ($template | path exists) {
    cp $template $config_ncl
    print "  ✅ Copied from template"
  } else {
    print "  ❌ ERROR: Cannot find config template"
    exit 1
  }
}

# Validate Nickel syntax
let typecheck_result = (do { nickel typecheck $config_ncl } | complete)
if $typecheck_result.exit_code != 0 {
  print "  ❌ Nickel configuration validation failed:"
  print $typecheck_result.stderr
  exit 1
}

print "  ✅ Configuration syntax valid"
print ""

# ════════════════════════════════════════════════════════════════════════
# STAGE 5: EXPORT CONFIGURATION
# ════════════════════════════════════════════════════════════════════════

print "📤 Stage 5: Exporting Configuration to TOML"
print "─────────────────────────────────────────────────────────────────"

# Change to project root to enable module imports
cd $project_root

# Use provisioning config export CLI command
let export_result = (do {
  nu -c $"use provisioning/core/nulib/lib_provisioning/config/export.nu *; export-all-configs ($workspace_path)"
} | complete)

if $export_result.exit_code == 0 {
  print "  ✅ Configuration exported"
} else {
  print "  ⚠️  Export output:"
  print $export_result.stdout
}
print ""

# ════════════════════════════════════════════════════════════════════════
# STAGE 6: INITIALIZE ORCHESTRATOR
# ════════════════════════════════════════════════════════════════════════

print "🚀 Stage 6: Initializing Orchestrator Service"
print "─────────────────────────────────────────────────────────────────"

let orchestrator_path = ($project_root | path join "provisioning" | path join "platform" | path join "orchestrator")

if ($orchestrator_path | path exists) {
  print "  Starting orchestrator service in background..."

  let start_result = (do {
    cd $orchestrator_path
    ./scripts/start-orchestrator.nu --background --provisioning-path ($project_root | path join "provisioning" | path join "core" | path join "cli" | path join "provisioning")
  } | complete)

  if $start_result.exit_code == 0 {
    print "  ✅ Orchestrator started"
    print "  📝 Check logs: tail -f ($orchestrator_path)/data/orchestrator.log"
  } else {
    print "  ⚠️  Orchestrator start note:"
    print $start_result.stdout
    if ($start_result.stderr | is-not-empty) {
      print $start_result.stderr
    }
  }
} else {
  print "  ⚠️  Orchestrator not found at ($orchestrator_path)"
}

print ""

# ════════════════════════════════════════════════════════════════════════
# STAGE 7: VERIFY INSTALLATION
# ════════════════════════════════════════════════════════════════════════

print "✅ Stage 7: Verification"
print "─────────────────────────────────────────────────────────────────"

# Check generated files
let files_check = [
  "config/generated/workspace.toml",
  "config/generated/providers/upcloud.toml",
  "config/generated/platform/orchestrator.toml"
]

let missing_files = ($files_check | where {|f|
  not (($workspace_path | path join $f) | path exists)
})

if ($missing_files | is-not-empty) {
  print "  ⚠️  Missing generated files:"
  $missing_files | each {|f| print $"    - ($f)"}
} else {
  print "  ✅ All configuration files generated"
}

# Check directories
let directories = [
  ".orchestrator/data/queue",
  ".kms",
  ".providers",
  ".taskservs",
  ".clusters"
]

let all_dirs_exist = ($directories | all {|d|
  ($workspace_path | path join $d) | path exists
})

if $all_dirs_exist {
  print "  ✅ All required directories created"
} else {
  print "  ⚠️  Some directories missing"
}

print ""

# ════════════════════════════════════════════════════════════════════════
# FINAL STATUS
# ════════════════════════════════════════════════════════════════════════

print "╔════════════════════════════════════════════════════════════════╗"
print "║                   BOOTSTRAP COMPLETE ✅                        ║"
print "╚════════════════════════════════════════════════════════════════╝"
print ""

print "📍 Next Steps:"
print ""
print "1. Verify configuration:"
print $"   cat ($workspace_path)/config/config.ncl"
print ""
print "2. Check orchestrator is running:"
print "   curl http://localhost:9090/health"
print ""
print "3. Start provisioning:"
print "   provisioning server create --infra sgoyol --name web-01"
print ""
print "4. Monitor workflow:"
print "   provisioning workflow monitor <workflow_id>"
print ""
print "📚 Documentation:"
print "   - User Guide: docs/user/TYPEDIALOG_PLATFORM_CONFIG_GUIDE.md"
print "   - Architecture: ARCHITECTURE_CLARIFICATION.md"
print "   - Workflow: PROVISIONING_WORKFLOW.md"
print ""
