#!/usr/bin/env nu

# Build Nushell with all workspace plugins
#
# This script builds the complete nushell binary with all built-in plugins
# from the nushell workspace, optimized for distribution.

use lib/common_lib.nu [log_info, log_error, log_success, log_warn, validate_nushell_version]

def main [
    --release (-r)                  # Build in release mode (default: debug)
    --features (-f): string = ""    # Additional cargo features to enable
    --target (-t): string = ""      # Build target (cross-compilation)
    --verbose (-v)                  # Enable verbose output
    --profile (-p): string = ""     # Build profile (release, dev, etc.)
] {
    log_info "🔨 Building Nushell with workspace plugins..."

    # Validate nushell version consistency first
    validate_nushell_version

    # Get nushell directory
    let nushell_dir = $"($env.PWD)/nushell"

    # Validate nushell directory exists
    if not ($nushell_dir | path exists) {
        log_error $"Nushell directory not found: ($nushell_dir)"
        exit 1
    }

    # Build cargo command with --workspace for system plugins
    mut cargo_cmd = ["cargo", "build", "--workspace"]
    log_info "📦 Building entire workspace (nushell + system plugins)"

    # Add build mode
    if $release != null {
        $cargo_cmd = ($cargo_cmd | append "--release")
        log_info "🚀 Building in release mode"
    } else {
        log_info "🛠️  Building in debug mode"
    }

    # Add profile if specified
    if ($profile | is-not-empty) {
        $cargo_cmd = ($cargo_cmd | append ["--profile", $profile])
        log_info $"📋 Using profile: ($profile)"
    }

    # Add target if specified
    if ($target | is-not-empty) {
        $cargo_cmd = ($cargo_cmd | append ["--target", $target])
        log_info $"🎯 Building for target: ($target)"
    }

    # Determine features to enable
    mut all_features = [
        "plugin"           # Enable plugin system
        "network"          # Network commands
        "sqlite"           # SQLite support
        "trash-support"    # Trash commands
        "rustls-tls"      # TLS support
        "system-clipboard" # System clipboard support
    ]

    # Add additional features if provided
    if ($features | is-not-empty) {
        let custom_features = ($features | split row ",")
        $all_features = ($all_features | append $custom_features)
    }

    # Add features to cargo command
    let features_str = ($all_features | str join ",")
    $cargo_cmd = ($cargo_cmd | append ["--features", $features_str])
    log_info $"✨ Enabled features: ($features_str)"

    # Add verbose flag if requested
    if $verbose != null {
        $cargo_cmd = ($cargo_cmd | append "--verbose")
        log_info "📢 Verbose output enabled"
    }

    # Change to nushell directory
    log_info $"📁 Working in: ($nushell_dir)"

    try {
        # Execute cargo build
        let cargo_cmd_str = ($cargo_cmd | str join " ")
        log_info $"🔨 Running: ($cargo_cmd_str)"

        cd $nushell_dir
        let result = bash -c $cargo_cmd_str

        # Determine output directory based on build mode and target
        mut target_dir = $"($nushell_dir)/target"

        if ($target | is-not-empty) {
            $target_dir = $"($target_dir)/($target)"
        }

        mut profile_dir = if $release != null {
            "release"
        } else if ($profile | is-not-empty) {
            $profile
        } else {
            "debug"
        }

        let binary_path = $"($target_dir)/($profile_dir)/nu"
        let binary_path = if $nu.os-info.name == "windows" {
            $"($binary_path).exe"
        } else {
            $binary_path
        }

        # Check if binary was created
        if ($binary_path | path exists) {
            let binary_size = (ls $binary_path | get size.0)
            log_success $"✅ Nushell binary built successfully!"
            log_info $"📄 Binary location: ($binary_path)"
            log_info $"📊 Binary size: ($binary_size)"

            # Show binary info
            try {
                let version_info = run-external $binary_path "--version" | complete
                if $version_info.exit_code == 0 {
                    log_info $"🔢 Version: ($version_info.stdout | str trim)"
                }
            } catch {
                log_warn "⚠️  Could not get version information"
            }

            # List workspace plugins that are built-in
            log_info "🧩 Built-in workspace plugins:"
            let workspace_plugins = [
                "nu_plugin_custom_values"
                "nu_plugin_example"
                "nu_plugin_formats"
                "nu_plugin_gstat"
                "nu_plugin_inc"
                "nu_plugin_polars"
                "nu_plugin_query"
                "nu_plugin_stress_internals"
            ]

            for plugin in $workspace_plugins {
                let plugin_binary = $"($target_dir)/($profile_dir)/($plugin)"
                let plugin_binary = if $nu.os-info.name == "windows" {
                    $"($plugin_binary).exe"
                } else {
                    $plugin_binary
                }

                if ($plugin_binary | path exists) {
                    let plugin_size = (ls $plugin_binary | get size.0)
                    log_info $"  ✅ ($plugin): ($plugin_size)"
                } else {
                    log_warn $"  ❌ ($plugin): not built"
                }
            }

            return {
                success: true
                binary_path: $binary_path
                target_dir: $target_dir
                profile_dir: $profile_dir
                features: $features_str
            }

        } else {
            log_error $"❌ Binary not found at expected location: ($binary_path)"
            exit 1
        }

    } catch { |err|
        log_error $"❌ Build failed: ($err.msg)"
        exit 1
    }
}

# Show build information
def "build info" [] {
    log_info "🔨 Nushell Build Information"
    log_info "==========================="
    log_info ""
    log_info "Available features:"
    log_info "  plugin           - Enable plugin system"
    log_info "  network          - Network commands (http, etc.)"
    log_info "  sqlite           - SQLite database support"
    log_info "  trash-support    - Trash/recycle bin commands"
    log_info "  rustls-tls       - TLS support with rustls"
    log_info "  system-clipboard - System clipboard integration"
    log_info "  native-tls       - TLS support with native libs"
    log_info "  static-link-openssl - Statically link OpenSSL"
    log_info ""
    log_info "Build profiles:"
    log_info "  dev      - Debug build (default)"
    log_info "  release  - Optimized release build"
    log_info "  profiling - Release with debug info"
    log_info "  ci       - CI optimized build"
    log_info ""
    log_info "Workspace plugins (built-in):"
    log_info "  nu_plugin_custom_values   - Custom value handling"
    log_info "  nu_plugin_example        - Example plugin"
    log_info "  nu_plugin_formats        - Additional file formats"
    log_info "  nu_plugin_gstat          - Git status plugin"
    log_info "  nu_plugin_inc            - Increment plugin"
    log_info "  nu_plugin_polars         - DataFrame support"
    log_info "  nu_plugin_query          - Query plugin"
    log_info "  nu_plugin_stress_internals - Stress testing"
}

# Check build dependencies
def "build deps" [] {
    log_info "🔍 Checking build dependencies..."

    # Check Rust toolchain
    try {
        let rust_version = run-external "rustc" "--version" | complete
        if $rust_version.exit_code == 0 {
            log_success $"✅ Rust: ($rust_version.stdout | str trim)"
        } else {
            log_error "❌ Rust compiler not found"
            return false
        }
    } catch {
        log_error "❌ Rust compiler not found"
        return false
    }

    # Check Cargo
    try {
        let cargo_version = run-external "cargo" "--version" | complete
        if $cargo_version.exit_code == 0 {
            log_success $"✅ Cargo: ($cargo_version.stdout | str trim)"
        } else {
            log_error "❌ Cargo not found"
            return false
        }
    } catch {
        log_error "❌ Cargo not found"
        return false
    }

    # Check nushell directory
    let nushell_dir = $"($env.PWD)/nushell"
    if ($nushell_dir | path exists) {
        log_success $"✅ Nushell source: ($nushell_dir)"
    } else {
        log_error $"❌ Nushell source not found: ($nushell_dir)"
        return false
    }

    # Check Cargo.toml
    let cargo_toml = $"($nushell_dir)/Cargo.toml"
    if ($cargo_toml | path exists) {
        log_success $"✅ Nushell Cargo.toml found"

        # Show workspace members
        try {
            let cargo_content = open $cargo_toml
            if "workspace" in $cargo_content {
                let members = $cargo_content.workspace.members | length
                log_info $"📦 Workspace members: ($members)"
            }
        } catch {
            log_warn "⚠️  Could not parse Cargo.toml"
        }
    } else {
        log_error $"❌ Nushell Cargo.toml not found: ($cargo_toml)"
        return false
    }

    log_success "✅ All build dependencies satisfied"
    return true
}