#!/usr/bin/env nu

# Core distribution preparation tool - prepares core files for distribution
#
# Prepares:
# - Nushell core libraries and modules
# - Configuration templates and schemas
# - CLI wrapper scripts and entry points
# - Plugin definitions and extensions
# - Template system and utilities

use std log

def main [
    --source-root: string = ""                  # Source root directory (auto-detected if empty)
    --output-dir: string = "dist/core"          # Output directory for core distribution
    --include-dev: bool = false                 # Include development files and tools
    --minify-scripts: bool = false              # Minify Nushell scripts (remove comments/whitespace)
    --validate-syntax: bool = true              # Validate all Nushell scripts
    --generate-index: bool = true               # Generate module index files
    --bundle-plugins: bool = true               # Bundle plugin definitions
    --create-stubs: bool = false                # Create type definition stubs
    --verbose                                   # Enable verbose logging
]
{

    let repo_root = if $source_root == "" {
        ($env.PWD | path dirname | path dirname | path dirname)
    } else {
        ($source_root | path expand)
    }

    let core_config = {
        source_root: $repo_root
        output_dir: ($output_dir | path expand)
        include_dev: $include_dev
        minify_scripts: $minify_scripts
        validate_syntax: $validate_syntax
        generate_index: $generate_index
        bundle_plugins: $bundle_plugins
        create_stubs: $create_stubs
        verbose: $verbose
    }

    log info $"Starting core distribution preparation with config: ($core_config)"

    # Ensure output directory exists
    mkdir ($core_config.output_dir)

    let preparation_results = []

    try {
        # Phase 1: Discover and validate core components
        let discovery_result = discover_core_components $core_config

        let preparation_results = ($preparation_results | append { phase: "discovery", result: $discovery_result })

        if $discovery_result.status != "success" {
            log error $"Core component discovery failed: ($discovery_result.reason)"
            exit 1
        }

        # Phase 2: Prepare core libraries
        let libraries_result = prepare_core_libraries $core_config $discovery_result

        let preparation_results = ($preparation_results | append { phase: "libraries", result: $libraries_result })

        # Phase 3: Prepare CLI components
        let cli_result = prepare_cli_components $core_config $discovery_result

        let preparation_results = ($preparation_results | append { phase: "cli", result: $cli_result })

        # Phase 4: Prepare configuration system
        let config_result = prepare_configuration_system $core_config $discovery_result

        let preparation_results = ($preparation_results | append { phase: "configuration", result: $config_result })

        # Phase 5: Bundle plugins and extensions
        let plugins_result = if $core_config.bundle_plugins {
            prepare_plugin_system $core_config $discovery_result
        } else {
            { status: "skipped", reason: "plugin bundling disabled" }
        }

        let preparation_results = ($preparation_results | append { phase: "plugins", result: $plugins_result })

        # Phase 6: Generate indexes and metadata
        let index_result = if $core_config.generate_index {
            generate_core_indexes $core_config $preparation_results
        } else {
            { status: "skipped", reason: "index generation disabled" }
        }

        let preparation_results = ($preparation_results | append { phase: "indexes", result: $index_result })

        # Phase 7: Create distribution metadata
        let metadata_result = create_core_metadata $core_config $preparation_results

        let preparation_results = ($preparation_results | append { phase: "metadata", result: $metadata_result })

        let summary = {
            source_root: $core_config.source_root
            output_directory: $core_config.output_dir
            successful_phases: ($preparation_results | where {|r| $r.result.status == "success"} | length)
            total_phases: ($preparation_results | length)
            core_files_prepared: ($preparation_results | get result.files_processed | math sum)
            total_size: (get_directory_size $core_config.output_dir)
            core_config: $core_config
            phases: $preparation_results
        }

        log info $"Core distribution preparation completed successfully - ($summary.core_files_prepared) files prepared"

        return $summary

    } catch {|err|
        log error $"Core distribution preparation failed: ($err.msg)"
        exit 1
    }
}

# Discover core components in the source tree
def discover_core_components [core_config: record]
{
    log info "Discovering core components..."

    let start_time = (date now)

    try {
        # Define core component locations
        let core_locations = {
            provisioning_cli: ($core_config.source_root | path join "provisioning" "core" "nulib" "provisioning")
            core_libraries: ($core_config.source_root | path join "provisioning" "core" "nulib" "lib_provisioning")
            workflows: ($core_config.source_root | path join "provisioning" "core" "nulib" "workflows")
            servers: ($core_config.source_root | path join "provisioning" "core" "nulib" "servers")
            extensions: ($core_config.source_root | path join "provisioning" "extensions")
            config_system: ($core_config.source_root | path join "provisioning" "config.defaults.toml")
        }

        # Discover Nushell files
        let nu_files = []
        for location_name in ($core_locations | columns) {
            let location_path = ($core_locations | get $location_name)
            if ($location_path | path exists) {
                let found_files = (find $location_path -name "*.nu" -type f)
                let nu_files = ($nu_files | append ($found_files | each {|file|
                    {
                        path: $file
                        component: $location_name
                        relative_path: ($file | str replace $core_config.source_root "")
                        size: (ls $file | get 0.size)
                    }
                }))
            }
        }

        # Discover configuration files
        let config_files = (find ($core_config.source_root | path join "provisioning") -name "*.toml" -type f)

        # Discover template files
        let template_files = (find ($core_config.source_root | path join "provisioning") -name "*.j2" -o -name "*.template" -type f)

        # Validate critical components exist
        let missing_components = []
        let critical_components = ["provisioning_cli", "core_libraries"]
        for component in $critical_components {
            let component_path = ($core_locations | get $component)
            if not ($component_path | path exists) {
                let missing_components = ($missing_components | append $component)
            }
        }

        if ($missing_components | length) > 0 {
            return {
                status: "failed"
                reason: $"Missing critical components: ($missing_components | str join ', ')"
                duration: ((date now) - $start_time)
            }
        }

        {
            status: "success"
            core_locations: $core_locations
            nu_files: $nu_files
            config_files: $config_files
            template_files: $template_files
            total_nu_files: ($nu_files | length)
            total_config_files: ($config_files | length)
            total_template_files: ($template_files | length)
            duration: ((date now) - $start_time)
        }

    } catch {|err|
        {
            status: "failed"
            reason: $err.msg
            duration: ((date now) - $start_time)
        }
    }
}

# Prepare core libraries for distribution
def prepare_core_libraries [
    core_config: record
    discovery_result: record
]
{
    log info "Preparing core libraries..."

    let start_time = (date now)
    let lib_output_dir = ($core_config.output_dir | path join "lib")
    mkdir $lib_output_dir

    try {
        let prepared_files = []
        let validation_errors = []

        # Process core library files
        let core_lib_files = ($discovery_result.nu_files | where component == "core_libraries")

        for file_info in $core_lib_files {
            let processing_result = process_nushell_file $file_info $core_config $lib_output_dir

            if $processing_result.status == "success" {
                $prepared_files = ($prepared_files | append $processing_result)
            } else {
                $validation_errors = ($validation_errors | append $processing_result.errors)
            }
        }

        # Process workflow files
        let workflow_files = ($discovery_result.nu_files | where component == "workflows")

        for file_info in $workflow_files {
            let processing_result = process_nushell_file $file_info $core_config ($lib_output_dir | path join "workflows")

            if $processing_result.status == "success" {
                $prepared_files = ($prepared_files | append $processing_result)
            } else {
                $validation_errors = ($validation_errors | append $processing_result.errors)
            }
        }

        # Process server management files
        let server_files = ($discovery_result.nu_files | where component == "servers")

        for file_info in $server_files {
            let processing_result = process_nushell_file $file_info $core_config ($lib_output_dir | path join "servers")

            if $processing_result.status == "success" {
                $prepared_files = ($prepared_files | append $processing_result)
            } else {
                $validation_errors = ($validation_errors | append $processing_result.errors)
            }
        }

        let status = if ($validation_errors | length) > 0 { "partial" } else { "success" }

        {
            status: $status
            files_processed: ($prepared_files | length)
            validation_errors: ($validation_errors | length)
            prepared_files: $prepared_files
            errors: $validation_errors
            lib_output_dir: $lib_output_dir
            duration: ((date now) - $start_time)
        }

    } catch {|err|
        {
            status: "failed"
            reason: $err.msg
            duration: ((date now) - $start_time)
        }
    }
}

# Prepare CLI components for distribution
def prepare_cli_components [
    core_config: record
    discovery_result: record
]
{
    log info "Preparing CLI components..."

    let start_time = (date now)
    let cli_output_dir = ($core_config.output_dir | path join "bin")
    mkdir $cli_output_dir

    try {
        # Process main provisioning CLI
        let cli_location = ($discovery_result.core_locations.provisioning_cli)

        if ($cli_location | path exists) {
            let target_cli = ($cli_output_dir | path join "provisioning")

            # Copy CLI script
            cp $cli_location $target_cli

            # Make executable on Unix-like systems
            if $nu.os-info.name != "windows" {
                chmod +x $target_cli
            }

            # Create wrapper scripts for different environments
            create_cli_wrappers $cli_output_dir $core_config

            {
                status: "success"
                cli_prepared: $target_cli
                wrappers_created: 3  # Unix, Windows, Development
                files_processed: 4
                duration: ((date now) - $start_time)
            }
        } else {
            {
                status: "failed"
                reason: "provisioning CLI not found"
                duration: ((date now) - $start_time)
            }
        }

    } catch {|err|
        {
            status: "failed"
            reason: $err.msg
            duration: ((date now) - $start_time)
        }
    }
}

# Create CLI wrapper scripts
def create_cli_wrappers [cli_output_dir: string, core_config: record] {
    # Unix shell wrapper
    let unix_wrapper = $"#!/bin/bash
# Provisioning System CLI Wrapper
# This wrapper sets up the environment and executes the main CLI

# Set environment variables
export PROVISIONING_HOME=\"$(dirname \"$(readlink -f \"$0\")\")/../\"
export PROVISIONING_LIB=\"$PROVISIONING_HOME/lib\"
export PROVISIONING_CONFIG=\"$PROVISIONING_HOME/../config\"

# Execute the main CLI with proper library path
exec nu \"$PROVISIONING_HOME/bin/provisioning\" \"$@\"
"

    $unix_wrapper | save ($cli_output_dir | path join "provisioning.sh")
    chmod +x ($cli_output_dir | path join "provisioning.sh")

    # Windows batch wrapper
    let windows_wrapper = $"@echo off
REM Provisioning System CLI Wrapper
REM This wrapper sets up the environment and executes the main CLI

REM Set environment variables
set \"PROVISIONING_HOME=%~dp0..\\\"
set \"PROVISIONING_LIB=%PROVISIONING_HOME%lib\"
set \"PROVISIONING_CONFIG=%PROVISIONING_HOME%..\\config\"

REM Execute the main CLI
nu \"%PROVISIONING_HOME%bin\\provisioning\" %*
"

    $windows_wrapper | save ($cli_output_dir | path join "provisioning.bat")

    # Development wrapper (preserves source paths)
    let dev_wrapper = $"#!/usr/bin/env nu
# Provisioning Development CLI Wrapper
# This wrapper is used during development with source paths

# Set development paths
$env.PROVISIONING_HOME = ($env.PWD | path dirname)
$env.PROVISIONING_LIB = ($env.PROVISIONING_HOME | path join \"lib\")
$env.PROVISIONING_CONFIG = ($env.PROVISIONING_HOME | path join \"../config\")
$env.PROVISIONING_DEV = true

# Execute the main CLI
source ($env.PROVISIONING_HOME | path join \"bin\" \"provisioning\")
"

    $dev_wrapper | save ($cli_output_dir | path join "provisioning-dev.nu")
    chmod +x ($cli_output_dir | path join "provisioning-dev.nu")
}

# Prepare configuration system for distribution
def prepare_configuration_system [
    core_config: record
    discovery_result: record
]
{
    log info "Preparing configuration system..."

    let start_time = (date now)
    let config_output_dir = ($core_config.output_dir | path join "config")
    mkdir $config_output_dir

    try {
        let processed_configs = []

        # Process configuration files
        for config_file in $discovery_result.config_files {
            let config_name = ($config_file | path basename)
            let target_config = ($config_output_dir | path join $config_name)

            # Process configuration file (validate and optionally minify)
            let processing_result = process_config_file $config_file $target_config $core_config

            if $processing_result.status == "success" {
                $processed_configs = ($processed_configs | append $processing_result)
            }
        }

        # Create configuration templates
        create_config_templates $config_output_dir $core_config

        {
            status: "success"
            files_processed: ($processed_configs | length)
            config_files: $processed_configs
            templates_created: 3  # user, dev, prod
            config_output_dir: $config_output_dir
            duration: ((date now) - $start_time)
        }

    } catch {|err|
        {
            status: "failed"
            reason: $err.msg
            duration: ((date now) - $start_time)
        }
    }
}

# Process a single Nushell file
def process_nushell_file [
    file_info: record
    core_config: record
    output_dir: string
]
{
    let relative_path = ($file_info.relative_path | str trim-left "/")
    let target_file = ($output_dir | path join ($file_info.path | path basename))

    # Ensure target directory exists
    mkdir ($target_file | path dirname)

    try {
        let content = (open $file_info.path --raw)

        # Validate syntax if requested
        if $core_config.validate_syntax {
            let validation_result = validate_nu_syntax $file_info.path $content

            if $validation_result.status != "success" {
                return {
                    status: "failed"
                    file: $file_info.path
                    target: $target_file
                    errors: $validation_result.errors
                }
            }
        }

        # Process content based on configuration
        let processed_content = if $core_config.minify_scripts {
            minify_nushell_script $content $core_config
        } else {
            $content
        }

        # Filter development code if not including dev files
        let final_content = if not $core_config.include_dev {
            filter_development_code $processed_content
        } else {
            $processed_content
        }

        # Save processed file
        $final_content | save $target_file

        {
            status: "success"
            source: $file_info.path
            target: $target_file
            size: ($final_content | str length)
            component: $file_info.component
        }

    } catch {|err|
        {
            status: "failed"
            file: $file_info.path
            target: $target_file
            errors: [$err.msg]
        }
    }
}

# Validate Nushell syntax
def validate_nu_syntax [file_path: string, content: string]
{
    try {
        # Use Nushell's built-in syntax checking
        nu --check $file_path

        {
            status: "success"
            file: $file_path
        }

    } catch {|err|
        {
            status: "failed"
            file: $file_path
            errors: [$err.msg]
        }
    }
}

# Minify Nushell script by removing comments and extra whitespace
def minify_nushell_script [content: string, core_config: record]
{
    if not $core_config.minify_scripts {
        return $content
    }

    # Simple minification - remove comment lines and extra whitespace
    let lines = ($content | lines)
    let minified_lines = $lines | each {|line|
        let trimmed = ($line | str trim)
        # Keep non-comment lines and preserve some important comments
        if ($trimmed | str starts-with "#") {
            if ($trimmed | str contains "!/usr/bin") or ($trimmed | str contains "!/bin/") {
                $line  # Keep shebang lines
            } else {
                ""  # Remove comment lines
            }
        } else {
            $trimmed  # Keep code lines, trimmed
        }
    } | where $it != ""

    return ($minified_lines | str join "\n")
}

# Filter out development-specific code
def filter_development_code [content: string]
{
    let lines = ($content | lines)
    let filtered_lines = []
    let in_dev_block = false

    for line in $lines {
        # Check for development block markers
        if ($line | str contains "# DEV_START") or ($line | str contains "# DEBUG_START") {
            $in_dev_block = true
            continue
        }

        if ($line | str contains "# DEV_END") or ($line | str contains "# DEBUG_END") {
            $in_dev_block = false
            continue
        }

        # Skip lines in development blocks
        if $in_dev_block {
            continue
        }

        # Skip individual development lines
        if ($line | str contains "# DEV_ONLY") or ($line | str contains "# DEBUG") {
            continue
        }

        $filtered_lines = ($filtered_lines | append $line)
    }

    return ($filtered_lines | str join "\n")
}

# Process configuration file
def process_config_file [source_file: string, target_file: string, core_config: record]
{
    try {
        # Validate TOML syntax
        let config_data = (open $source_file)

        # Copy file (could add processing here if needed)
        cp $source_file $target_file

        {
            status: "success"
            source: $source_file
            target: $target_file
            validated: true
        }

    } catch {|err|
        {
            status: "failed"
            source: $source_file
            target: $target_file
            error: $err.msg
        }
    }
}

# Create configuration templates
def create_config_templates [config_output_dir: string, core_config: record] {
    # User configuration template
    let user_template = $"# User Configuration Template
# Copy this file to config.user.toml and customize as needed

# User-specific paths and preferences
[paths]
# Override default paths if needed
# home = \"/custom/path\"

[user]
name = \"Your Name\"
email = \"your.email@example.com\"

# Development settings
[dev]
debug = false
verbose = false
"

    $user_template | save ($config_output_dir | path join "config.user.toml.template")

    # Development configuration template
    let dev_template = $"# Development Configuration Template
# Copy this file to config.dev.toml for development environment

[general]
environment = \"development\"
debug = true
log_level = \"debug\"

[paths]
cache_ttl = 60  # Short cache for development
"

    $dev_template | save ($config_output_dir | path join "config.dev.toml.template")

    # Production configuration template
    let prod_template = $"# Production Configuration Template
# Copy this file to config.prod.toml for production environment

[general]
environment = \"production\"
debug = false
log_level = \"info\"

[security]
# Enable security features for production
strict_mode = true
"

    $prod_template | save ($config_output_dir | path join "config.prod.toml.template")
}

# Prepare plugin system for distribution
def prepare_plugin_system [
    core_config: record
    discovery_result: record
]
{
    log info "Preparing plugin system..."

    let start_time = (date now)
    let plugins_output_dir = ($core_config.output_dir | path join "plugins")
    mkdir $plugins_output_dir

    try {
        # Process extension files
        let extension_files = ($discovery_result.nu_files | where component == "extensions")
        let processed_extensions = []

        for file_info in $extension_files {
            let processing_result = process_nushell_file $file_info $core_config $plugins_output_dir

            if $processing_result.status == "success" {
                $processed_extensions = ($processed_extensions | append $processing_result)
            }
        }

        # Create plugin registry
        let plugin_registry = create_plugin_registry $processed_extensions $core_config

        {
            status: "success"
            files_processed: ($processed_extensions | length)
            extensions: $processed_extensions
            plugin_registry: $plugin_registry
            plugins_output_dir: $plugins_output_dir
            duration: ((date now) - $start_time)
        }

    } catch {|err|
        {
            status: "failed"
            reason: $err.msg
            duration: ((date now) - $start_time)
        }
    }
}

# Create plugin registry
def create_plugin_registry [processed_extensions: list, core_config: record]
{
    let plugin_registry = {
        version: "1.0.0"
        plugins: ($processed_extensions | each {|ext|
            {
                name: ($ext.target | path basename | str replace ".nu" "")
                path: ($ext.target | path basename)
                component: $ext.component
                size: $ext.size
            }
        })
        created_at: (date now)
    }

    let registry_file = ($core_config.output_dir | path join "plugins" "registry.json")
    $plugin_registry | to json | save $registry_file

    return $plugin_registry
}

# Generate core indexes and module listings
def generate_core_indexes [
    core_config: record
    preparation_results: list
]
{
    log info "Generating core indexes..."

    let start_time = (date now)

    try {
        # Generate library index
        let lib_result = ($preparation_results | where {|r| $r.phase == "libraries"} | get 0.result)
        let lib_index = generate_library_index $lib_result.prepared_files $core_config

        # Generate CLI index
        let cli_result = ($preparation_results | where {|r| $r.phase == "cli"} | get 0.result)
        let cli_index = generate_cli_index $cli_result $core_config

        # Generate main index
        let main_index = generate_main_index $preparation_results $core_config

        {
            status: "success"
            indexes_generated: ["library", "cli", "main"]
            library_index: $lib_index
            cli_index: $cli_index
            main_index: $main_index
            duration: ((date now) - $start_time)
        }

    } catch {|err|
        {
            status: "failed"
            reason: $err.msg
            duration: ((date now) - $start_time)
        }
    }
}

# Generate library index
def generate_library_index [prepared_files: list, core_config: record]
{
    let index_content = $"# Core Library Index

This file provides an index of all core library modules included in this distribution.

## Library Modules

"

    let modules = ($prepared_files | group-by component)

    let full_content = [$index_content]

    for component in ($modules | columns) {
        let component_files = ($modules | get $component)
        $full_content = ($full_content | append $"### ($component | str title-case)")
        $full_content = ($full_content | append "")

        for file in $component_files {
            let module_name = ($file.target | path basename | str replace ".nu" "")
            $full_content = ($full_content | append $"- **($module_name)**: ($file.target)")
        }

        $full_content = ($full_content | append "")
    }

    let content = ($full_content | str join "\n")
    $content | save ($core_config.output_dir | path join "lib" "INDEX.md")

    return $content
}

# Generate CLI index
def generate_cli_index [cli_result: record, core_config: record]
{
    let cli_index = $"# CLI Components Index

## Main CLI
- **provisioning**: Main provisioning CLI entry point

## Wrapper Scripts
- **provisioning.sh**: Unix/Linux shell wrapper
- **provisioning.bat**: Windows batch wrapper
- **provisioning-dev.nu**: Development wrapper

## Usage
The main CLI provides access to all provisioning functionality:
```
./bin/provisioning help
```

Generated: (date now | format date '%Y-%m-%d %H:%M:%S')
"

    $cli_index | save ($core_config.output_dir | path join "bin" "INDEX.md")
    return $cli_index
}

# Generate main index
def generate_main_index [preparation_results: list, core_config: record]
{
    let successful_phases = ($preparation_results | where {|r| $r.result.status == "success"})
    let total_files = ($successful_phases | get result.files_processed | math sum)

    let main_index = $"# Core Distribution Index

This distribution contains the core components of the Provisioning System.

## Directory Structure
- **bin/**: CLI executables and wrapper scripts
- **lib/**: Core Nushell libraries and modules
- **config/**: Configuration files and templates
- **plugins/**: Extensions and plugin definitions

## Statistics
- **Total files processed**: ($total_files)
- **Successful phases**: ($successful_phases | length)
- **Generated**: (date now | format date '%Y-%m-%d %H:%M:%S')

## Usage
To use this core distribution:
1. Add bin/ to your PATH
2. Set PROVISIONING_LIB to point to lib/
3. Configure PROVISIONING_CONFIG to point to config/
4. Run `provisioning help` to get started

For more information, see the documentation in each subdirectory.
"

    $main_index | save ($core_config.output_dir | path join "INDEX.md")
    return $main_index
}

# Create core metadata
def create_core_metadata [
    core_config: record
    preparation_results: list
]
{
    log info "Creating core metadata..."

    let start_time = (date now)

    try {
        let metadata = {
            name: "provisioning-core"
            version: (detect_version $core_config.source_root)
            type: "core-distribution"
            created_at: (date now)
            created_by: "core-distribution-tool"
            source_root: $core_config.source_root
            configuration: $core_config
            preparation_phases: ($preparation_results | each {|r|
                {
                    phase: $r.phase
                    status: $r.result.status
                    files_processed: (if "files_processed" in ($r.result | columns) { $r.result.files_processed } else { 0 })
                    duration: (if "duration" in ($r.result | columns) { $r.result.duration } else { 0 })
                }
            })
            statistics: {
                total_phases: ($preparation_results | length)
                successful_phases: ($preparation_results | where {|r| $r.result.status == "success"} | length)
                total_files: ($preparation_results | get result.files_processed | math sum)
                distribution_size: (get_directory_size $core_config.output_dir)
            }
        }

        let metadata_file = ($core_config.output_dir | path join "core-metadata.json")
        $metadata | to json | save $metadata_file

        {
            status: "success"
            metadata_file: $metadata_file
            metadata: $metadata
            duration: ((date now) - $start_time)
        }

    } catch {|err|
        {
            status: "failed"
            reason: $err.msg
            duration: ((date now) - $start_time)
        }
    }
}

# Detect version from git or other sources
def detect_version [repo_root: string]
{
    cd $repo_root

    try {
        let git_version = (git describe --tags --always --dirty 2>/dev/null | str trim)
        if $git_version != "" {
            return ($git_version | str replace "^v" "")
        }

        return $"dev-(date now | format date '%Y%m%d')"
    } catch {
        return "unknown"
    }
}

# Get directory size helper
def get_directory_size [dir: string] -> int {
    if not ($dir | path exists) {
        return 0
    }

    try {
        find $dir -type f | each {|file| ls $file | get 0.size } | math sum | if $in == null { 0 } else { $in }
    } catch {
        0
    }
}

# Show core distribution status
def "main status" [] {
    let repo_root = ($env.PWD | path dirname | path dirname | path dirname)
    let version = (detect_version $repo_root)

    # Check for core components
    let provisioning_cli = ($repo_root | path join "provisioning" "core" "nulib" "provisioning")
    let core_libraries = ($repo_root | path join "provisioning" "core" "nulib" "lib_provisioning")

    {
        repository: $repo_root
        version: $version
        core_components: {
            provisioning_cli: ($provisioning_cli | path exists)
            core_libraries: ($core_libraries | path exists)
        }
        nu_files_found: (try { find $repo_root -name "*.nu" -type f | length } catch { 0 })
        config_files_found: (try { find ($repo_root | path join "provisioning") -name "*.toml" -type f | length } catch { 0 })
        ready_for_distribution: (($provisioning_cli | path exists) and ($core_libraries | path exists))
    }
}

# Quick core preparation with minimal options
def "main quick" [output_dir: string = "dist/core"] {
    main --output-dir $output_dir --validate-syntax --generate-index
}
