#!/usr/bin/env nu

# Main distribution generator - orchestrates complete distribution creation
#
# Orchestrates:
# - Core library preparation
# - Platform service compilation
# - Configuration bundling
# - Documentation generation
# - Installation package creation
# - Multi-platform distribution assembly

use std log

def main [
    --version: string = ""                      # Distribution version (auto-detected if empty)
    --platforms: string = "linux,macos,windows" # Target platforms
    --variants: string = "complete,minimal"    # Distribution variants
    --output-dir: string = "dist"              # Output directory for distributions
    --build-clean                              # Clean build before generation
    --include-sources                          # Include source code in distribution
    --compress                                 # Compress final distributions
    --generate-docs                            # Generate documentation
    --parallel-builds                          # Build platforms in parallel
    --validate-output                          # Validate generated distributions
    --verbose                                  # Enable verbose logging
]: nothing -> record {

    let repo_root = ($env.PWD | path dirname | path dirname | path dirname)

    # Detect version if not provided
    let target_version = if $version == "" {
        detect_project_version $repo_root
    } else {
        $version
    }

    let target_platforms = ($platforms | split row "," | each { str trim })
    let target_variants = ($variants | split row "," | each { str trim })

    let distribution_config = {
        version: $target_version
        platforms: $target_platforms
        variants: $target_variants
        output_dir: ($output_dir | path expand)
        build_clean: $build_clean
        include_sources: $include_sources
        compress: $compress
        generate_docs: $generate_docs
        parallel_builds: $parallel_builds
        validate_output: $validate_output
        verbose: $verbose
        repo_root: $repo_root
    }

    log info $"Starting distribution generation with config: ($distribution_config)"

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

    let generation_results = []

    try {
        # Phase 1: Preparation
        let preparation_result = prepare_distribution_environment $distribution_config

        let generation_results = ($generation_results | append { phase: "preparation", result: $preparation_result })

        if $preparation_result.status != "success" {
            log error $"Distribution preparation failed: ($preparation_result.reason)"
            exit 1
        }

        # Phase 2: Core Distribution
        let core_result = generate_core_distribution $distribution_config

        let generation_results = ($generation_results | append { phase: "core", result: $core_result })

        if $core_result.status != "success" {
            log error $"Core distribution generation failed: ($core_result.reason)"
            exit 1
        }

        # Phase 3: Platform Services
        let platform_result = generate_platform_distributions $distribution_config

        let generation_results = ($generation_results | append { phase: "platform", result: $platform_result })

        if $platform_result.status != "success" {
            log error $"Platform distribution generation failed: ($platform_result.reason)"
            exit 1
        }

        # Phase 4: Documentation
        let docs_result = if $distribution_config.generate_docs {
            generate_distribution_docs $distribution_config
        } else {
            { status: "skipped", reason: "documentation generation disabled" }
        }

        let generation_results = ($generation_results | append { phase: "documentation", result: $docs_result })

        # Phase 5: Assembly
        let assembly_result = assemble_complete_distributions $distribution_config $generation_results

        let generation_results = ($generation_results | append { phase: "assembly", result: $assembly_result })

        if $assembly_result.status != "success" {
            log error $"Distribution assembly failed: ($assembly_result.reason)"
            exit 1
        }

        # Phase 6: Validation
        let validation_result = if $distribution_config.validate_output {
            validate_distributions $distribution_config $assembly_result
        } else {
            { status: "skipped", reason: "validation disabled" }
        }

        let generation_results = ($generation_results | append { phase: "validation", result: $validation_result })

        let summary = {
            version: $distribution_config.version
            platforms: ($distribution_config.platforms | length)
            variants: ($distribution_config.variants | length)
            total_distributions: ($assembly_result.distributions | length)
            successful_phases: ($generation_results | where {|r| $r.result.status == "success"} | length)
            output_directory: $distribution_config.output_dir
            total_size: ($assembly_result.total_size)
            generation_config: $distribution_config
            phases: $generation_results
        }

        log info $"Distribution generation completed successfully - ($summary.total_distributions) distributions created"

        return $summary

    } catch {|err|
        log error $"Distribution generation failed: ($err.msg)"
        exit 1
    }
}

# Detect project version from various sources
def detect_project_version [repo_root: string]: nothing -> string {
    cd $repo_root

    # Try git tags first
    let git_version = try {
        let tag = (git describe --tags --exact-match HEAD 2>/dev/null | str trim)
        if $tag != "" {
            return ($tag | str replace "^v" "")
        }
        let latest = (git describe --tags --abbrev=0 2>/dev/null | str trim)
        if $latest != "" {
            return ($latest | str replace "^v" "")
        }
        ""
    } catch {
        ""
    }

    if $git_version != "" {
        return $git_version
    }

    # Try Cargo.toml
    let cargo_version = try {
        let cargo_files = (glob **/Cargo.toml --depth 2)
        if ($cargo_files | length) > 0 {
            let cargo_data = (open ($cargo_files | get 0))
            return $cargo_data.package.version
        }
        ""
    } catch {
        ""
    }

    if $cargo_version != "" {
        return $cargo_version
    }

    # Fallback to date-based version
    return $"dev-(date now | format date '%Y%m%d')"
}

# Prepare distribution environment
def prepare_distribution_environment [distribution_config: record]: nothing -> record {
    log info "Preparing distribution environment..."

    let start_time = (date now)

    try {
        # Clean build if requested
        if $distribution_config.build_clean {
            log info "Cleaning build environment..."
            let target_dir = ($distribution_config.repo_root | path join "target")
            let dist_dir = ($distribution_config.repo_root | path join "dist")
            let packages_dir = ($distribution_config.repo_root | path join "packages")

            if ($target_dir | path exists) {
                ^rm -rf $target_dir
            }
            if ($dist_dir | path exists) {
                ^rm -rf $dist_dir
            }
            if ($packages_dir | path exists) {
                ^rm -rf $packages_dir
            }
            log info "Build environment cleaned"
        }

        # Create distribution directory structure
        let dist_structure = [
            "platform"
            "core"
            "config"
            "kcl"
            "extensions"
            "templates"
            "docs"
            "tmp"
        ]

        for dir in $dist_structure {
            mkdir ($distribution_config.output_dir | path join $dir)
        }

        # Validate dependencies
        let dependency_check = validate_distribution_dependencies $distribution_config

        if $dependency_check.missing_dependencies > 0 {
            return {
                status: "failed"
                reason: $"Missing dependencies: ($dependency_check.missing | str join ', ')"
                duration: ((date now) - $start_time)
            }
        }

        {
            status: "success"
            environment_ready: true
            directory_structure: $dist_structure
            dependency_check: $dependency_check
            duration: ((date now) - $start_time)
        }

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

# Validate distribution dependencies
def validate_distribution_dependencies [distribution_config: record]: nothing -> record {
    let required_tools = [
        { name: "nu", command: "nu --version", description: "Nushell shell" }
        { name: "git", command: "git --version", description: "Git version control" }
        { name: "cargo", command: "cargo --version", description: "Rust package manager" }
        { name: "rustc", command: "rustc --version", description: "Rust compiler" }
    ]

    let optional_tools = [
        { name: "kcl", command: "kcl version", description: "KCL configuration language" }
        { name: "docker", command: "docker --version", description: "Docker containerization" }
        { name: "tar", command: "tar --version", description: "Archive creation" }
        { name: "zip", command: "zip -v", description: "Zip compression" }
    ]

    mut available = []
    mut missing = []

    # Check required tools
    for tool in $required_tools {
        let check_result = try {
            run-external $tool.command err> /dev/null | complete
        } catch {
            { exit_code: 1 }
        }

        if $check_result.exit_code == 0 {
            $available = ($available | append $tool.name)
        } else {
            $missing = ($missing | append $tool.name)
        }
    }

    # Check optional tools
    for tool in $optional_tools {
        let check_result = try {
            run-external $tool.command err> /dev/null | complete
        } catch {
            { exit_code: 1 }
        }

        if $check_result.exit_code == 0 {
            $available = ($available | append $tool.name)
        }
    }

    {
        required_available: (($required_tools | get name) | where {|name| $name in $available} | length)
        total_required: ($required_tools | length)
        optional_available: (($optional_tools | get name) | where {|name| $name in $available} | length)
        total_optional: ($optional_tools | length)
        missing_dependencies: ($missing | length)
        available: $available
        missing: $missing
    }
}

# Generate core distribution
def generate_core_distribution [distribution_config: record]: nothing -> record {
    log info "Generating core distribution..."

    let start_time = (date now)

    try {
        # Use the build system to bundle core components
        let bundle_result = (nu ($distribution_config.repo_root | path join "src" "tools" "build" "bundle-core.nu")
            --output-dir ($distribution_config.output_dir | path join "core")
            --config-dir ($distribution_config.output_dir | path join "config")
            --validate
            --compress:$distribution_config.compress
            --exclude-dev
            --verbose:$distribution_config.verbose)

        if $bundle_result.failed > 0 {
            return {
                status: "failed"
                reason: $"Core bundling failed with ($bundle_result.failed) failures"
                bundle_result: $bundle_result
                duration: ((date now) - $start_time)
            }
        }

        # Validate KCL schemas
        let kcl_result = (nu ($distribution_config.repo_root | path join "src" "tools" "build" "validate-kcl.nu")
            --output-dir ($distribution_config.output_dir | path join "kcl")
            --format-code
            --verbose:$distribution_config.verbose)

        {
            status: "success"
            core_bundle: $bundle_result
            kcl_validation: $kcl_result
            components_bundled: $bundle_result.successful
            duration: ((date now) - $start_time)
        }

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

# Generate platform distributions
def generate_platform_distributions [distribution_config: record]: nothing -> record {
    log info "Generating platform distributions..."

    let start_time = (date now)

    try {
        # Compile platform components for each target platform
        let platform_results = if $distribution_config.parallel_builds {
            compile_platforms_parallel $distribution_config
        } else {
            compile_platforms_sequential $distribution_config
        }

        let successful_platforms = ($platform_results | where status == "success" | length)
        let total_platforms = ($platform_results | length)

        if $successful_platforms == 0 {
            return {
                status: "failed"
                reason: "No platforms compiled successfully"
                platform_results: $platform_results
                duration: ((date now) - $start_time)
            }
        }

        {
            status: (if $successful_platforms == $total_platforms { "success" } else { "partial" })
            platforms_compiled: $successful_platforms
            total_platforms: $total_platforms
            platform_results: $platform_results
            duration: ((date now) - $start_time)
        }

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

# Compile platforms in parallel
def compile_platforms_parallel [distribution_config: record]: nothing -> list {
    # For simplicity, using sequential compilation for now
    # In a real implementation, you might use background processes
    compile_platforms_sequential $distribution_config
}

# Compile platforms sequentially
def compile_platforms_sequential [distribution_config: record]: nothing -> list {
    $distribution_config.platforms | each {|platform|
        compile_single_platform $platform $distribution_config
    }
}

# Compile platform components for a single platform
def compile_single_platform [platform: string, distribution_config: record]: nothing -> record {
    log info $"Compiling platform: ($platform)"

    let start_time = (date now)
    let target_triple = get_rust_target_triple $platform

    try {
        # Compile platform components
        let compile_result = (nu ($distribution_config.repo_root | path join "src" "tools" "build" "compile-platform.nu")
            --target $target_triple
            --release
            --output-dir ($distribution_config.output_dir | path join "platform")
            --verbose:$distribution_config.verbose
            --clean:$distribution_config.build_clean)

        {
            platform: $platform
            target: $target_triple
            status: (if $compile_result.failed > 0 { "failed" } else { "success" })
            compiled_components: $compile_result.successful
            total_components: $compile_result.total
            compile_result: $compile_result
            duration: ((date now) - $start_time)
        }

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

# Get Rust target triple for platform
def get_rust_target_triple [platform: string]: nothing -> string {
    match $platform {
        "linux" => "x86_64-unknown-linux-gnu"
        "macos" => "x86_64-apple-darwin"
        "windows" => "x86_64-pc-windows-gnu"
        _ => $platform  # Assume it's already a target triple
    }
}

# Generate distribution documentation
def generate_distribution_docs [distribution_config: record]: nothing -> record {
    log info "Generating distribution documentation..."

    let start_time = (date now)

    try {
        let docs_dir = ($distribution_config.output_dir | path join "docs")
        mkdir $docs_dir

        # Generate README
        let readme_content = generate_distribution_readme $distribution_config
        $readme_content | save ($docs_dir | path join "README.md")

        # Generate installation guide
        let install_guide = generate_installation_guide $distribution_config
        $install_guide | save ($docs_dir | path join "INSTALLATION.md")

        # Generate changelog
        let changelog = generate_distribution_changelog $distribution_config
        $changelog | save ($docs_dir | path join "CHANGELOG.md")

        # Copy additional documentation
        copy_project_documentation $distribution_config $docs_dir

        {
            status: "success"
            docs_generated: ["README.md", "INSTALLATION.md", "CHANGELOG.md"]
            docs_directory: $docs_dir
            duration: ((date now) - $start_time)
        }

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

# Generate distribution README
def generate_distribution_readme [distribution_config: record]: nothing -> string {
    $"# Provisioning System v($distribution_config.version)

Cloud-native infrastructure provisioning and management system.

## Distribution Contents

This distribution includes:

- **Platform Binaries**: Core system executables for ($distribution_config.platforms | str join ', ')
- **Core Libraries**: Nushell libraries and modules
- **Configuration**: Default configuration templates
- **KCL Schemas**: Infrastructure as Code definitions
- **Documentation**: Installation and usage guides

## Quick Start

### Linux/macOS
```bash
sudo ./install.sh
```

### Windows
```cmd
install.bat
```

### Manual Installation
1. Extract the distribution archive
2. Copy binaries to your system PATH
3. Copy libraries to standard locations
4. Configure system settings

## Getting Started

After installation:
```bash
provisioning help
provisioning version
provisioning env
```

## Documentation

- **Installation Guide**: See INSTALLATION.md
- **Changelog**: See CHANGELOG.md
- **Online Documentation**: https://github.com/your-org/provisioning

## Support

For support and issues:
- GitHub: https://github.com/your-org/provisioning/issues
- Documentation: https://docs.provisioning.example.com

## License

This software is licensed under the MIT License.

---

Generated on: (date now | format date '%Y-%m-%d %H:%M:%S')
Distribution Version: ($distribution_config.version)
"
}

# Generate installation guide
def generate_installation_guide [distribution_config: record]: nothing -> string {
    $"# Installation Guide

This guide covers installation of the Provisioning System v($distribution_config.version).

## System Requirements

### Minimum Requirements
- Operating System: Linux, macOS, or Windows
- Memory: 1GB RAM
- Disk Space: 500MB free space
- Network: Internet connection for downloads

### Supported Platforms
- Linux (x86_64)
- macOS (Intel)
- Windows (x86_64)

## Installation Methods

### 1. Automated Installation (Recommended)

#### Linux/macOS
```bash
# Download and extract distribution
tar -xzf provisioning-($distribution_config.version)-linux-complete.tar.gz
cd provisioning-($distribution_config.version)-linux-complete

# Run installer
sudo ./install.sh
```

#### Windows
```cmd
REM Extract distribution
unzip provisioning-($distribution_config.version)-windows-complete.zip
cd provisioning-($distribution_config.version)-windows-complete

REM Run installer as Administrator
install.bat
```

### 2. Manual Installation

#### Step 1: Extract Distribution
Extract the distribution archive to a temporary location.

#### Step 2: Install Binaries
Copy the binaries from `platform/` to your system PATH:

**Linux/macOS:**
```bash
sudo cp platform/* /usr/local/bin/
sudo chmod +x /usr/local/bin/provisioning-*
```

**Windows:**
```cmd
copy platform\\*.exe \"C:\\Program Files\\Provisioning\\bin\\\"
```

#### Step 3: Install Libraries
Copy the core libraries:

**Linux/macOS:**
```bash
sudo mkdir -p /usr/local/lib/provisioning
sudo cp -r core/* /usr/local/lib/provisioning/
```

**Windows:**
```cmd
mkdir \"C:\\Program Files\\Provisioning\\lib\"
xcopy core\\* \"C:\\Program Files\\Provisioning\\lib\\\" /E /Y
```

#### Step 4: Install Configuration
Copy default configuration files:

**Linux/macOS:**
```bash
sudo mkdir -p /etc/provisioning
sudo cp config/* /etc/provisioning/
```

**Windows:**
```cmd
mkdir \"C:\\ProgramData\\Provisioning\"
xcopy config\\* \"C:\\ProgramData\\Provisioning\\\" /E /Y
```

## Verification

After installation, verify the system is working:

```bash
# Check version
provisioning version

# Check environment
provisioning env

# Test help system
provisioning help
```

## Configuration

### Environment Variables
- `PROVISIONING_HOME`: Installation directory
- `PROVISIONING_CONFIG`: Configuration file path
- `PROVISIONING_ENV`: Environment (dev/test/prod)

### Configuration Files
- `config.defaults.toml`: System defaults
- `config.user.toml`: User-specific settings

## Troubleshooting

### Common Issues

1. **Command not found**: Ensure binaries are in your PATH
2. **Permission denied**: Check file permissions and user privileges
3. **Missing dependencies**: Install required system packages

### Getting Help
- Run `provisioning help` for command help
- Check logs in the system log directory
- Visit https://github.com/your-org/provisioning/issues

## Uninstallation

To remove the Provisioning System:

**Linux/macOS:**
```bash
# Remove binaries
sudo rm /usr/local/bin/provisioning-*

# Remove libraries
sudo rm -rf /usr/local/lib/provisioning

# Remove configuration
sudo rm -rf /etc/provisioning
```

**Windows:**
```cmd
REM Remove installation directory
rmdir /S \"C:\\Program Files\\Provisioning\"
rmdir /S \"C:\\ProgramData\\Provisioning\"
```

---

For more detailed information, visit the online documentation.
"
}

# Generate distribution changelog
def generate_distribution_changelog [distribution_config: record]: nothing -> string {
    # This would normally generate a changelog from git history
    $"# Changelog

## v($distribution_config.version) - (date now | format date '%Y-%m-%d')

### New Features
- Complete distribution system with multi-platform support
- Automated installation scripts for all platforms
- Comprehensive configuration management

### Improvements
- Enhanced build system with parallel compilation
- Better error handling and validation
- Improved documentation and examples

### Bug Fixes
- Fixed platform-specific compatibility issues
- Resolved configuration loading problems
- Corrected installation script permissions

---

For detailed commit history, see the project repository.
"
}

# Copy project documentation
def copy_project_documentation [distribution_config: record, docs_dir: string] {
    let source_docs = [
        ($distribution_config.repo_root | path join "README.md")
        ($distribution_config.repo_root | path join "LICENSE")
        ($distribution_config.repo_root | path join "CONTRIBUTING.md")
    ]

    for doc_file in $source_docs {
        if ($doc_file | path exists) {
            let target_file = ($docs_dir | path join ($doc_file | path basename))
            cp $doc_file $target_file
        }
    }
}

# Assemble complete distributions
def assemble_complete_distributions [
    distribution_config: record
    generation_results: list
]: nothing -> record {
    log info "Assembling complete distributions..."

    let start_time = (date now)

    try {
        mut assembled_distributions = []
        mut total_size = 0

        # Create distributions for each platform-variant combination
        for platform in $distribution_config.platforms {
            for variant in $distribution_config.variants {
                let dist_result = assemble_single_distribution $platform $variant $distribution_config

                if $dist_result.status == "success" {
                    $assembled_distributions = ($assembled_distributions | append $dist_result)
                    $total_size = $total_size + $dist_result.size
                }
            }
        }

        # Create source distribution if requested
        let source_dist = if $distribution_config.include_sources {
            create_source_distribution $distribution_config
        } else {
            { status: "skipped", reason: "source distribution not requested" }
        }

        {
            status: "success"
            distributions: $assembled_distributions
            source_distribution: $source_dist
            total_distributions: ($assembled_distributions | length)
            total_size: $total_size
            duration: ((date now) - $start_time)
        }

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

# Assemble single distribution
def assemble_single_distribution [
    platform: string
    variant: string
    distribution_config: record
]: nothing -> record {
    let dist_name = $"provisioning-($distribution_config.version)-($platform)-($variant)"
    let dist_dir = ($distribution_config.output_dir | path join "tmp" $dist_name)

    try {
        # Create distribution directory
        mkdir $dist_dir

        # Copy components based on variant
        match $variant {
            "complete" => {
                copy_complete_distribution $distribution_config $dist_dir $platform
            }
            "minimal" => {
                copy_minimal_distribution $distribution_config $dist_dir $platform
            }
            _ => {
                return {
                    platform: $platform
                    variant: $variant
                    status: "failed"
                    reason: $"unknown variant: ($variant)"
                }
            }
        }

        # Create installation scripts
        create_installation_scripts $dist_dir $platform $distribution_config

        # Create archive if compression is enabled
        let final_path = if $distribution_config.compress {
            create_distribution_archive $dist_dir $distribution_config.output_dir
        } else {
            # Move directory to final location
            let final_dir = ($distribution_config.output_dir | path join $dist_name)
            mv $dist_dir $final_dir
            $final_dir
        }

        let dist_size = get_directory_size $final_path

        {
            platform: $platform
            variant: $variant
            status: "success"
            name: $dist_name
            path: $final_path
            size: $dist_size
            compressed: $distribution_config.compress
        }

    } catch {|err|
        {
            platform: $platform
            variant: $variant
            status: "failed"
            reason: $err.msg
        }
    }
}

# Copy complete distribution components
def copy_complete_distribution [distribution_config: record, dist_dir: string, platform: string] {
    # Copy all components
    let components = [
        { source: "platform", target: "platform", filter_platform: true }
        { source: "core", target: "core", filter_platform: false }
        { source: "config", target: "config", filter_platform: false }
        { source: "kcl", target: "kcl", filter_platform: false }
        { source: "docs", target: "docs", filter_platform: false }
    ]

    for component in $components {
        let source_path = ($distribution_config.output_dir | path join $component.source)
        let target_path = ($dist_dir | path join $component.target)

        if ($source_path | path exists) {
            if $component.filter_platform and $component.source == "platform" {
                copy_platform_binaries $source_path $target_path $platform
            } else {
                cp -r $source_path $target_path
            }
        }
    }
}

# Copy minimal distribution components
def copy_minimal_distribution [distribution_config: record, dist_dir: string, platform: string] {
    # Copy only essential components
    let essential_components = [
        { source: "platform", target: "platform", filter_platform: true }
        { source: "core", target: "core", filter_platform: false }
        { source: "config", target: "config", filter_platform: false }
    ]

    for component in $essential_components {
        let source_path = ($distribution_config.output_dir | path join $component.source)
        let target_path = ($dist_dir | path join $component.target)

        if ($source_path | path exists) {
            if $component.filter_platform and $component.source == "platform" {
                copy_platform_binaries $source_path $target_path $platform
            } else {
                cp -r $source_path $target_path
            }
        }
    }
}

# Copy platform-specific binaries
def copy_platform_binaries [source_path: string, target_path: string, platform: string] {
    mkdir $target_path

    let all_binaries = (ls $source_path | where type == file | get name)
    let target_suffix = get_rust_target_triple $platform

    for binary in $all_binaries {
        let binary_name = ($binary | path basename)

        # Check if binary matches the platform
        if ($binary_name | str contains $target_suffix) or not ($binary_name =~ "(linux|darwin|windows|gnu|msvc)") {
            let target_name = ($binary_name | str replace $"-($target_suffix)" "")
            cp $binary ($target_path | path join $target_name)
        }
    }
}

# Create installation scripts
def create_installation_scripts [dist_dir: string, platform: string, distribution_config: record] {
    match $platform {
        "linux" | "macos" => {
            let install_script = create_unix_install_script $distribution_config
            $install_script | save ($dist_dir | path join "install.sh")
            chmod +x ($dist_dir | path join "install.sh")
        }
        "windows" => {
            let install_script = create_windows_install_script $distribution_config
            $install_script | save ($dist_dir | path join "install.bat")
        }
        _ => {
            log warning $"No installation script for platform: ($platform)"
        }
    }
}

# Create Unix install script
def create_unix_install_script [distribution_config: record]: nothing -> string {
    $"#!/bin/bash
# Provisioning System Installation Script
# Version: ($distribution_config.version)

set -e

INSTALL_DIR=\"/usr/local\"
CONFIG_DIR=\"/etc/provisioning\"
LIB_DIR=\"$INSTALL_DIR/lib/provisioning\"

echo \"Installing Provisioning System ($distribution_config.version)...\"

# Check for root privileges
if [[ $EUID -ne 0 ]]; then
   echo \"This script must be run as root (use sudo)\"
   exit 1
fi

# Install binaries
echo \"Installing binaries...\"
mkdir -p \"$INSTALL_DIR/bin\"
cp platform/* \"$INSTALL_DIR/bin/\"
chmod +x \"$INSTALL_DIR/bin/\"*

# Install libraries
echo \"Installing libraries...\"
mkdir -p \"$LIB_DIR\"
cp -r core/* \"$LIB_DIR/\"

# Install configuration
echo \"Installing configuration...\"
mkdir -p \"$CONFIG_DIR\"
cp -r config/* \"$CONFIG_DIR/\"

echo \"Installation complete!\"
echo \"Run 'provisioning help' to get started.\"
"
}

# Create Windows install script
def create_windows_install_script [distribution_config: record]: nothing -> string {
    $"@echo off
REM Provisioning System Installation Script
REM Version: ($distribution_config.version)

echo Installing Provisioning System ($distribution_config.version)...

REM Create directories
mkdir \"C:\\Program Files\\Provisioning\\bin\" 2>NUL
mkdir \"C:\\Program Files\\Provisioning\\lib\" 2>NUL
mkdir \"C:\\ProgramData\\Provisioning\" 2>NUL

REM Install binaries
echo Installing binaries...
xcopy platform\\* \"C:\\Program Files\\Provisioning\\bin\\\" /Y /Q

REM Install libraries
echo Installing libraries...
xcopy core\\* \"C:\\Program Files\\Provisioning\\lib\\\" /Y /Q /S

REM Install configuration
echo Installing configuration...
xcopy config\\* \"C:\\ProgramData\\Provisioning\\\" /Y /Q /S

echo Installation complete!
echo Add \"C:\\Program Files\\Provisioning\\bin\" to your PATH
echo Run 'provisioning-orchestrator --help' to get started.
pause
"
}

# Create distribution archive
def create_distribution_archive [dist_dir: string, output_dir: string]: nothing -> string {
    let dist_name = ($dist_dir | path basename)
    let archive_name = $"($dist_name).tar.gz"
    let archive_path = ($output_dir | path join $archive_name)
    let parent_dir = ($dist_dir | path dirname)

    cd $parent_dir
    tar -czf $archive_path $dist_name

    # Clean up directory
    rm -rf $dist_dir

    return $archive_path
}

# Create source distribution
def create_source_distribution [distribution_config: record]: nothing -> record {
    log info "Creating source distribution..."

    try {
        let source_name = $"provisioning-($distribution_config.version)-source"
        let source_dir = ($distribution_config.output_dir | path join "tmp" $source_name)

        # Create source distribution directory
        mkdir $source_dir

        # Copy source files (excluding build artifacts and temporary files)
        let exclude_patterns = [
            "target/"
            "dist/"
            "*.tmp"
            ".git/"
            "node_modules/"
            "*.log"
        ]

        # This is a simplified copy - in practice, you'd use more sophisticated filtering
        cp -r ($distribution_config.repo_root | path join "src") ($source_dir | path join "src")
        cp ($distribution_config.repo_root | path join "README.md") ($source_dir | path join "README.md")
        cp ($distribution_config.repo_root | path join "LICENSE") ($source_dir | path join "LICENSE")

        # Create source archive
        let archive_path = create_distribution_archive $source_dir $distribution_config.output_dir

        {
            status: "success"
            name: $source_name
            path: $archive_path
            size: (get_directory_size $archive_path)
        }

    } catch {|err|
        {
            status: "failed"
            reason: $err.msg
        }
    }
}

# Validate distributions
def validate_distributions [
    distribution_config: record
    assembly_result: record
]: nothing -> record {
    log info "Validating generated distributions..."

    let start_time = (date now)

    try {
        let validation_results = $assembly_result.distributions | each {|dist|
            validate_single_distribution $dist $distribution_config
        }

        let successful_validations = ($validation_results | where status == "success" | length)
        let total_validations = ($validation_results | length)

        {
            status: (if $successful_validations == $total_validations { "success" } else { "partial" })
            validated_distributions: $successful_validations
            total_distributions: $total_validations
            validation_results: $validation_results
            duration: ((date now) - $start_time)
        }

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

# Validate single distribution
def validate_single_distribution [dist: record, distribution_config: record]: nothing -> record {
    # Use the package validation tool
    try {
        let validation_result = (nu ($distribution_config.repo_root | path join "src" "tools" "package" "validate-package.nu")
            $dist.path
            --validation-type quick
            --skip-execution
            --output-format json
            --cleanup)

        {
            distribution: $dist.name
            status: (if $validation_result.overall_status == "passed" { "success" } else { "failed" })
            validation_result: $validation_result
        }

    } catch {|err|
        {
            distribution: $dist.name
            status: "failed"
            reason: $err.msg
        }
    }
}

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

    let total_size = try {
        if ($path | path type) == "file" {
            ls $path | get 0.size
        } else {
            find $path -type f | each {|file| ls $file | get 0.size } | math sum
        }
    } catch {
        0
    }

    return ($total_size | if $in == null { 0 } else { $in })
}

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

    let dependency_check = validate_distribution_dependencies { repo_root: $repo_root }

    {
        project_version: $version
        repository: $repo_root
        supported_platforms: ["linux", "macos", "windows"]
        supported_variants: ["complete", "minimal"]
        dependencies: $dependency_check
        distribution_ready: ($dependency_check.missing_dependencies == 0)
    }
}

# Quick distribution generation
def "main quick" [
    --platform: string = "linux"               # Single platform to build
    --variant: string = "complete"             # Distribution variant
] {
    main --platforms $platform --variants $variant --parallel-builds:false
}
