#!/usr/bin/env nu

# Build All Plugins Script
# Builds all nu_plugin_* directories with support for cross-compilation

# Version check - mandatory for all plugin operations
def version_check [] {
    try {
        nu scripts/check_version.nu --quiet | ignore
    } catch {
        print "❌ Nushell version mismatch detected!"
        print "🔧 Run: nu scripts/check_version.nu --fix"
        exit 1
    }
}

# Get all plugin directories
def get_plugin_directories [] {
    glob "nu_plugin_*" | where ($it | path type) == "dir"
}

# Build a single plugin
def build_plugin [
    plugin_dir: string,
    target: string = "",
    use_docker: bool = false,
    verbose: bool = false
] {
    if ($target | str length) > 0 {
        print $"🔨 Building ($plugin_dir) for ($target)..."
    } else {
        print $"🔨 Building ($plugin_dir)..."
    }

    try {
        cd $plugin_dir

        mut build_cmd = ["cargo", "build", "--release"]

        if ($target | str length) > 0 and not $use_docker {
            $build_cmd = ($build_cmd | append ["--target", $target])
        }

        if $verbose {
            print $"  Command: ($build_cmd | str join ' ')"
        }

        if $use_docker {
            # Delegate to Docker cross-compilation
            let docker_result = (nu ../scripts/build_docker_cross.nu --plugin $plugin_dir --target $target | complete)
            if $docker_result.exit_code != 0 {
                error make {msg: $"Docker build failed: ($docker_result.stderr)"}
            }
        } else {
            # Native build
            run-external "cargo" ...($build_cmd | skip 1)
        }

        cd ..
        print $"✅ Created ($plugin_dir)"
        {plugin: $plugin_dir, target: $target, status: "success", error: null}
    } catch {|err|
        cd ..
        print $"❌ Error in ($plugin_dir): ($err.msg)"
        {plugin: $plugin_dir, target: $target, status: "error", error: $err.msg}
    }
}

# Check if cross-compilation is requested and delegate to build_cross.nu
def check_cross_compilation [
    target: string,
    all_targets: bool,
    docker: bool,
    native: bool,
    plugins: list<string>,
    parallel: bool,
    verbose: bool
] {
    if $all_targets or ($target | str length) > 0 {
        print "🎯 Cross-compilation requested - delegating to build_cross.nu"

        mut args = []

        if $all_targets {
            $args = ($args | append "--all-targets")
        }

        if ($target | str length) > 0 {
            $args = ($args | append ["--targets", $target])
        }

        if ($plugins | length) > 0 {
            $args = ($args | append ["--plugins", ($plugins | str join ",")])
        }

        if $docker {
            $args = ($args | append "--docker")
        }

        if $native {
            $args = ($args | append "--native")
        }

        if $parallel {
            $args = ($args | append "--parallel")
        }

        if $verbose {
            $args = ($args | append "--verbose")
        }

        # Execute cross-compilation script
        nu scripts/build_cross.nu ...$args
        return true
    }

    false
}

# Main function
def main [
    --verbose (-v)              # Verbose output
    --parallel (-p)             # Build plugins in parallel (experimental)
    --target (-t): string = ""  # Cross-compilation target (e.g., linux-amd64, darwin-arm64)
    --all-targets (-a)          # Build for all enabled cross-compilation targets
    --plugins: list<string> = [] # Specific plugins to build
    --docker (-d)               # Force use of Docker for cross-compilation
    --native (-n)               # Force native compilation only
] {
    # Mandatory version check before any plugin operations
    version_check

    # Ensure we're in the repository root directory
    if not ("nu_plugin_clipboard" | path exists) {
        error make {msg: "Please run this script from the nushell-plugins repository root directory"}
    }

    # Check if cross-compilation is requested
    let is_cross_compilation = check_cross_compilation $target $all_targets $docker $native $plugins $parallel $verbose
    if $is_cross_compilation {
        return  # Cross-compilation handled by build_cross.nu
    }

    print "🚀 Building all nushell plugins (native compilation)..."

    # Determine plugins to build
    let all_plugin_dirs = get_plugin_directories
    let plugin_dirs = if ($plugins | length) > 0 {
        $all_plugin_dirs | where $it in $plugins
    } else {
        $all_plugin_dirs
    }

    if ($plugin_dirs | length) == 0 {
        if ($plugins | length) > 0 {
            print $"❓ No matching plugins found for: ($plugins | str join ', ')"
            print $"💡 Available plugins: ($all_plugin_dirs | str join ', ')"
        } else {
            print "❓ No nu_plugin_* directories found"
        }
        return
    }

    print $"📦 Found ($plugin_dirs | length) plugins to build:"
    for dir in $plugin_dirs {
        print $"  - ($dir)"
    }

    if ($target | str length) > 0 {
        print $"🎯 Target: ($target) (native compilation)"
    } else {
        print "🎯 Target: host platform (native compilation)"
    }
    print ""

    let start_time = date now
    mut results = []

    if $parallel {
        # Experimental parallel building (may have issues with cargo lock)
        print "⚡ Building in parallel mode (experimental)..."
        $results = ($plugin_dirs | par-each {|dir| build_plugin $dir $target false $verbose})
    } else {
        # Sequential building (safer)
        for dir in $plugin_dirs {
            let result = build_plugin $dir $target false $verbose
            $results = ($results | append $result)
            print "---"
        }
    }

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

    # Summary
    print "\n📊 Build Summary:"
    let successful = $results | where status == "success"
    let failed = $results | where status == "error"

    print $"✅ Successful: ($successful | length)"
    print $"❌ Failed: ($failed | length)"
    print $"⏱️  Total time: ($duration)"

    if ($successful | length) > 0 {
        print "\n✅ Successfully built:"
        for success in $successful {
            if ($success.target | str length) > 0 {
                print $"  - ($success.plugin) → ($success.target)"
            } else {
                print $"  - ($success.plugin)"
            }
        }
    }

    if ($failed | length) > 0 {
        print "\n❌ Failed builds:"
        for failure in $failed {
            print $"  - ($failure.plugin): ($failure.error)"
        }
        exit 1
    } else {
        print "\n🎉 All plugins built successfully!"
        print "💡 Next steps:"
        print "  - Test plugins: just test"
        print "  - Collect binaries: just collect"
        print "  - Cross-compile: just build-cross-all"
    }
}

if ($env.NUSHELL_EXECUTION_CONTEXT? | default "" | str contains "run") {
    main
}