#!/usr/bin/env nu

# Build script for syntaxis Leptos WASM dashboard
#
# USAGE:
#   build-dashboard.nu check-install      # Check if prerequisites are installed
#   build-dashboard.nu install            # Install missing prerequisites
#   build-dashboard.nu build              # Build dashboard release
#   build-dashboard.nu build --dev        # Build dashboard (dev/debug mode)
#
# This script handles:
# 1. Checking prerequisites (wasm32 target, wasm-bindgen-cli, trunk, pnpm)
# 2. Installing missing tools if requested
# 3. Building WASM artifacts with Trunk
# 4. Ensuring output structure is correct (pkg/, styles/, index.html)

use std log

def check_command [cmd: string] {
    # Check if a command is available in PATH
    try {
        which $cmd | is-not-empty
        true
    } catch {
        false
    }
}

def check_rustup_target [target: string] {
    # Check if a rustup target is installed
    try {
        rustup target list | grep -q $target
        true
    } catch {
        false
    }
}

def print_header [title: string] {
    print ""
    print "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
    print $"🎨 ($title)"
    print "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
    print ""
}

def print_section [title: string] {
    print $"  📌 ($title)"
}

def print_success [msg: string] {
    print $"  ✅ ($msg)"
}

def print_info [msg: string] {
    print $"  ℹ️  ($msg)"
}

def print_warning [msg: string] {
    print $"  ⚠️  ($msg)"
}

def print_error [msg: string] {
    print $"  ❌ ($msg)"
}

def check_prerequisites [] {
    # Check if all required tools are installed
    print_header "Checking Prerequisites"

    mut all_ok = true

    # Check wasm32 target
    print_section "Rust WASM Target (wasm32-unknown-unknown)"
    if (check_rustup_target "wasm32-unknown-unknown") {
        print_success "wasm32-unknown-unknown target installed"
    } else {
        print_warning "wasm32-unknown-unknown target NOT installed"
        all_ok = false
    }

    # Check wasm-bindgen-cli
    print_section "wasm-bindgen-cli"
    if (check_command "wasm-bindgen") {
        let version = (wasm-bindgen --version | str trim)
        print_success $"($version) found"
    } else {
        print_warning "wasm-bindgen-cli NOT installed"
        all_ok = false
    }

    # Check trunk
    print_section "trunk (Leptos build tool)"
    if (check_command "trunk") {
        let version = (trunk --version | str trim)
        print_success $"($version) found"
    } else {
        print_warning "trunk NOT installed"
        all_ok = false
    }

    # Check pnpm
    print_section "pnpm (Package manager for UnoCSS)"
    if (check_command "pnpm") {
        let version = (pnpm --version | str trim)
        print_success $"pnpm ($version) found"
    } else {
        print_warning "pnpm NOT installed"
        all_ok = false
    }

    # Check current directory
    print_section "Project structure"
    if ("Trunk.toml" | path exists) {
        print_success "Trunk.toml found"
    } else {
        print_warning "Trunk.toml NOT found (should be in core/)"
        all_ok = false
    }

    if ("index.html" | path exists) {
        print_success "index.html found"
    } else {
        print_warning "index.html NOT found (should be in core/)"
        all_ok = false
    }

    if ("package.json" | path exists) {
        print_success "package.json found"
    } else {
        print_warning "package.json NOT found (should be in core/)"
        all_ok = false
    }

    print ""
    if $all_ok {
        print "✅ All prerequisites are installed and ready!"
        print ""
        return 0
    } else {
        print "❌ Some prerequisites are missing."
        print "    Run: build-dashboard.nu install"
        print ""
        return 1
    }
}

def install_prerequisites [] {
    # Install missing prerequisites
    print_header "Installing Prerequisites"

    # Install wasm32 target if missing
    if not (check_rustup_target "wasm32-unknown-unknown") {
        print_section "Installing wasm32-unknown-unknown target..."
        try {
            rustup target add wasm32-unknown-unknown
            print_success "wasm32-unknown-unknown target installed"
        } catch { |err|
            print_error $"Failed to install wasm32 target: ($err)"
            return 1
        }
    }

    # Install wasm-bindgen-cli if missing
    if not (check_command "wasm-bindgen") {
        print_section "Installing wasm-bindgen-cli..."
        try {
            cargo install wasm-bindgen-cli
            print_success "wasm-bindgen-cli installed"
        } catch { |err|
            print_error $"Failed to install wasm-bindgen-cli: ($err)"
            return 1
        }
    }

    # Install trunk if missing
    if not (check_command "trunk") {
        print_section "Installing trunk..."
        try {
            cargo install trunk
            print_success "trunk installed"
        } catch { |err|
            print_error $"Failed to install trunk: ($err)"
            return 1
        }
    }

    # Install pnpm if missing
    if not (check_command "pnpm") {
        print_section "Installing pnpm..."
        try {
            npm install -g pnpm
            print_success "pnpm installed"
        } catch { |err|
            print_warning $"Failed to install pnpm globally: ($err)"
            print_info "Trying to install via cargo..."
            try {
                cargo install pnpm
                print_success "pnpm installed via cargo"
            } catch { |err2|
                print_error $"Failed to install pnpm: ($err2)"
                return 1
            }
        }
    }

    print ""
    print "✅ Prerequisites installation complete!"
    print ""
    return 0
}

def build_dashboard [dev_mode: bool] {
    # Build Leptos WASM dashboard with Trunk
    print_header "Building Dashboard WASM"

    # Check prerequisites first
    if (check_prerequisites) != 0 {
        print_error "Prerequisites check failed"
        return 1
    }

    # pnpm install in core directory
    print_section "Installing pnpm dependencies..."
    try {
        if ("node_modules" | path exists) == false {
            pnpm install
            print_success "Dependencies installed"
        } else {
            print_info "Dependencies already installed"
        }
    } catch { |err|
        print_warning $"Failed to run pnpm install: ($err)"
        # Continue anyway - pnpm might not be needed if node_modules exists
    }

    # Build UnoCSS (generates app.css from Rust/HTML)
    print_section "Building CSS with UnoCSS..."
    try {
        pnpm css:build
        print_success "CSS generated"
    } catch { |err|
        print_error $"CSS build failed: ($err)"
        return 1
    }

    # Build WASM with Trunk
    print_section "Building WASM with Trunk..."
    try {
        if $dev_mode {
            print_info "Building in dev mode (unoptimized)"
            trunk build
        } else {
            print_info "Building in release mode (optimized)"
            trunk build --release
        }
        print_success "WASM build completed"
    } catch { |err|
        print_error $"WASM build failed: ($err)"
        print_info "Make sure you're running this from the core/ directory"
        return 1
    }

    # Verify build output
    print_section "Verifying build artifacts..."
    mut all_ok = true

    if ("target/site/index.html" | path exists) {
        print_success "index.html exists"
    } else {
        print_error "index.html NOT found in target/site/"
        all_ok = false
    }

    if ("target/site/pkg" | path exists) {
        let files = (glob "target/site/pkg/**/*" | length)
        print_success $"WASM artifacts generated ($files files)"
    } else {
        print_error "pkg/ directory NOT found in target/site/"
        all_ok = false
    }

    if ("target/site/styles/app.css" | path exists) {
        let size = (stat "target/site/styles/app.css" | get size)
        print_success $"CSS generated ($(($size | math) / 1024 | math round --precision 2)KB)"
    } else {
        print_error "app.css NOT found in target/site/styles/"
        all_ok = false
    }

    print ""
    if $all_ok {
        print "✅ Dashboard build successful!"
        print ""
        print "📂 Build output: core/target/site/"
        print "   - index.html: Dashboard entry point"
        print "   - pkg/: WASM artifacts (*.wasm, *.js)"
        print "   - styles/app.css: Generated styles"
        print ""
        print "🚀 Next steps:"
        print "   - Run: just dev-dashboard (starts Trunk dev server on port 8080)"
        print "   - Or:  just run-api-with-dashboard (serves dashboard from API on port 3000)"
        print ""
        return 0
    } else {
        print_error "Build verification failed"
        return 1
    }
}

def show_help [] {
    print ""
    print "🎨 syntaxis Dashboard Build Script"
    print ""
    print "USAGE:"
    print "  build-dashboard.nu check-install      # Check if prerequisites installed"
    print "  build-dashboard.nu install            # Install missing prerequisites"
    print "  build-dashboard.nu build              # Build dashboard (release mode)"
    print "  build-dashboard.nu build --dev        # Build dashboard (dev mode)"
    print "  build-dashboard.nu help               # Show this help"
    print ""
    print "PREREQUISITES:"
    print "  - Rust toolchain with wasm32-unknown-unknown target"
    print "  - wasm-bindgen-cli (for WASM JS bindings)"
    print "  - trunk (Leptos build system)"
    print "  - pnpm (for UnoCSS CSS generation)"
    print ""
    print "EXAMPLES:"
    print "  # Check if ready to build"
    print "  cd core && build-dashboard.nu check-install"
    print ""
    print "  # Install any missing tools"
    print "  cd core && build-dashboard.nu install"
    print ""
    print "  # Build release version"
    print "  cd core && build-dashboard.nu build"
    print ""
    print "  # Build debug version"
    print "  cd core && build-dashboard.nu build --dev"
    print ""
}

def main [
    action?: string     # Action: "check-install", "install", "build", "help"
    --dev               # Dev mode for build (unoptimized)
] {
    let action = ($action | default "help")

    if $action == "check-install" or $action == "check" {
        exit (check_prerequisites)
    } else if $action == "install" {
        exit (install_prerequisites)
    } else if $action == "build" {
        exit (build_dashboard $dev)
    } else if $action == "help" {
        show_help
    } else {
        print_error $"Unknown action: ($action)"
        show_help
        exit 1
    }
}
