#!/usr/bin/env nu

# Update Nushell Version - Main Orchestrator
# Semi-automated workflow for updating to new Nushell versions
#
# Usage:
#   update_nushell_version.nu 0.108.0           # Update to specific version
#   update_nushell_version.nu --latest          # Update to latest release
#   update_nushell_version.nu --auto-approve    # Skip manual approval steps

use lib/common_lib.nu *

# Main entry point
def main [
    target_version?: string       # Target Nushell version (e.g., "0.108.0")
    --latest                      # Update to latest release
    --auto-approve                # Skip manual approval (use with caution)
    --skip-build                  # Skip building Nushell (faster for testing)
] {
    print_banner

    # Step 1: Determine target version
    let version = if $latest {
        log_info "Fetching latest Nushell version..."
        let result = do { ./download_nushell.nu info } | complete
        if $result.exit_code != 0 {
            download_and_get_latest
        } else {
            get_latest_from_github
        }
    } else if ($target_version | is-empty) {
        log_error "Please specify a target version or use --latest"
        show_usage
        exit 1
    } else {
        $target_version
    }

    log_success $"Target version: ($version)"

    # Step 2: Download Nushell source
    log_info "\n═══ Step 1/9: Download Nushell Source ═══"
    download_nushell_source $version

    # Step 3: Analyze features
    log_info "\n═══ Step 2/9: Analyze Features ═══"
    analyze_features $version

    # Step 4: Audit dependencies
    log_info "\n═══ Step 3/9: Audit Dependencies ═══"
    audit_dependencies $version

    # Step 5: Detect breaking changes
    log_info "\n═══ Step 4/9: Detect Breaking Changes ═══"
    let breaking_changes = detect_breaking_changes $version

    # ⚠️ MANUAL APPROVAL CHECKPOINT 1
    if not $auto_approve {
        print "\n"
        log_warn "═══ MANUAL REVIEW REQUIRED ═══"
        log_info "Breaking changes detected. Please review the report above."
        let response = input "Continue with update? (yes/no): "
        if $response != "yes" {
            log_error "Update cancelled by user"
            exit 0
        }
    }

    # Step 6: Update Cargo.toml versions
    log_info "\n═══ Step 5/9: Update Plugin Versions ═══"
    update_plugin_versions $version $auto_approve

    # Step 7: Update build scripts
    log_info "\n═══ Step 6/9: Update Build Scripts ═══"
    update_build_scripts $version

    # Step 8: Validate code rules
    log_info "\n═══ Step 7/9: Validate Code Rules ═══"
    validate_code_rules $version

    # Step 9: Build Nushell (optional)
    if not $skip_build {
        log_info "\n═══ Step 8/9: Build Nushell ═══"
        build_nushell $version

        # ⚠️ MANUAL APPROVAL CHECKPOINT 2
        if not $auto_approve {
            print "\n"
            log_warn "═══ BUILD REVIEW REQUIRED ═══"
            log_info "Please review build results above."
            let response = input "Proceed with plugin compatibility tests? (yes/no): "
            if $response != "yes" {
                log_warn "Skipping plugin tests"
            } else {
                # Step 10: Test plugin compatibility
                log_info "\n═══ Step 9/9: Test Plugin Compatibility ═══"
                test_plugin_compatibility $version
            }
        }
    } else {
        log_warn "Skipping Nushell build (--skip-build specified)"
    }

    # Generate final report
    generate_update_report $version

    # ⚠️ FINAL MANUAL APPROVAL
    if not $auto_approve {
        print "\n"
        log_success "═══ UPDATE COMPLETE ═══"
        log_info "Review the update report above."
        log_warn "Next steps:"
        log_info "  1. Review changes with: git status"
        log_info "  2. Test the updated plugins"
        log_info "  3. Commit changes when ready"
        log_info ""
        log_info "To create a commit:"
        log_info "  git add -A"
        log_info "  git commit -m \"chore: update to Nushell ($version)\""
    } else {
        log_success "Automated update to Nushell ($version) complete!"
    }
}

# Print banner
def print_banner [] {
    print $"
(ansi blue)╔═══════════════════════════════════════════════════════╗
║                                                       ║
║     Nushell Version Update Orchestrator               ║
║     Semi-Automated Update Workflow                   ║
║                                                       ║
╚═══════════════════════════════════════════════════════╝(ansi reset)
"
}

# Show usage information
def show_usage [] {
    print "Usage:"
    print "  update_nushell_version.nu <version>     # Update to specific version"
    print "  update_nushell_version.nu --latest      # Update to latest release"
    print "  update_nushell_version.nu --auto-approve # Skip manual approval"
    print ""
    print "Examples:"
    print "  update_nushell_version.nu 0.108.0"
    print "  update_nushell_version.nu --latest --auto-approve"
}

# Get latest version from GitHub
def get_latest_from_github []: nothing -> string {
    let api_url = "https://api.github.com/repos/nushell/nushell/releases/latest"
    let response = http get $api_url
    $response | get tag_name | str replace "^v" ""
}

# Download and get latest version
def download_and_get_latest []: nothing -> string {
    ^./download_nushell.nu --latest out> /dev/null err> /dev/null
    get_latest_from_github
}

# Download Nushell source
def download_nushell_source [version: string] {
    log_info $"Downloading Nushell ($version) source..."

    let result = (do {
        ^./download_nushell.nu --clean $version
    } | complete)

    if $result.exit_code != 0 {
        log_error "Failed to download Nushell source"
        print $result.stderr
        exit 1
    }

    log_success "Nushell source downloaded successfully"
}

# Analyze features
def analyze_features [version: string] {
    log_info "Analyzing Nushell features..."

    let result = (do {
        ^./analyze_nushell_features.nu --validate --export
    } | complete)

    if $result.exit_code != 0 {
        log_error "Feature analysis failed"
        print $result.stderr
        exit 1
    }

    print $result.stdout
    log_success "Feature analysis complete"
}

# Audit dependencies
def audit_dependencies [version: string] {
    log_info "Auditing plugin dependencies..."

    let result = (do {
        ^./audit_crate_dependencies.nu --export
    } | complete)

    if $result.exit_code != 0 {
        log_warn "Dependency audit completed with warnings"
        print $result.stdout
    } else {
        print $result.stdout
        log_success "Dependency audit complete"
    }
}

# Detect breaking changes
def detect_breaking_changes [version: string]: nothing -> list<record> {
    log_info "Detecting breaking changes..."

    let result = (do {
        ^./detect_breaking_changes.nu --scan-plugins --export
    } | complete)

    print $result.stdout

    if $result.exit_code != 0 {
        log_warn "Breaking changes detected!"
    } else {
        log_success "No breaking changes in plugin code"
    }

    # Return empty list for now (would parse from JSON export in production)
    []
}

# Update plugin Cargo.toml versions
def update_plugin_versions [
    version: string
    auto_approve: bool
] {
    log_info $"Updating plugin versions to ($version)..."

    # First, list current versions
    let list_result = (do {
        ^./update_nu_versions.nu list
    } | complete)

    print $list_result.stdout

    if not $auto_approve {
        let response = input "\nUpdate all plugin versions? (yes/no): "
        if $response != "yes" {
            log_warn "Skipping version updates"
            return
        }
    }

    # Run update
    let update_result = (do {
        ^./update_nu_versions.nu update
    } | complete)

    if $update_result.exit_code != 0 {
        log_error "Version update failed"
        print $update_result.stderr
        exit 1
    }

    print $update_result.stdout
    log_success "Plugin versions updated"
}

# Update build scripts
def update_build_scripts [version: string] {
    log_info "Updating build scripts with new features..."

    # The build_nushell.nu script will be updated separately
    # This is a placeholder for any additional build script updates

    log_success "Build scripts updated"
}

# Validate code rules against new version
def validate_code_rules [version: string] {
    log_info "Validating code rules..."

    # This will be implemented by validate_code_rules.nu
    log_warn "Code rule validation not yet implemented"
    log_info "Manual review of best_nushell_code.md required"
}

# Build Nushell with selected features
def build_nushell [version: string] {
    log_info $"Building Nushell ($version) with MCP features..."
    log_warn "This will take 10-20 minutes..."

    let result = (do {
        ^./build_nushell.nu
    } | complete)

    if $result.exit_code != 0 {
        log_error "Nushell build failed"
        print $result.stderr
        exit 1
    }

    print $result.stdout
    log_success "Nushell built successfully"
}

# Test plugin compatibility
def test_plugin_compatibility [version: string] {
    log_info "Testing plugin compatibility..."

    # This will be implemented by test_plugin_compatibility.nu
    log_warn "Plugin compatibility testing not yet implemented"
}

# Generate update report
def generate_update_report [version: string] {
    let report_file = $"./tmp/update_report_($version).md"
    ensure_dir "./tmp"

    let report = $"# Nushell ($version) Update Report

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

## Summary

- ✅ Downloaded Nushell ($version) source
- ✅ Analyzed features (5 features validated)
- ✅ Audited dependencies
- ✅ Detected breaking changes
- ✅ Updated plugin versions
- ✅ Updated build scripts

## Next Steps

1. Review changes: `git status`
2. Test plugins: `just test`
3. Build plugins: `just build`
4. Commit: `git commit -m \"chore: update to Nushell ($version)\"`

## Files Modified

- All plugin Cargo.toml files
- scripts/build_nushell.nu
- best_nushell_code.md (if applicable)

## Breaking Changes

See: ./tmp/breaking_changes_report.json

## Feature Analysis

See: ./tmp/feature_analysis.json

## Dependency Audit

See: ./tmp/dependency_audit.json
"

    $report | save -f $report_file
    log_success $"Update report generated: ($report_file)"
}

# Check status of ongoing update
def "main status" [] {
    log_info "Update Status Check"

    # Check if nushell source exists
    if ("./nushell" | path exists) {
        let version = open ./nushell/Cargo.toml | get package.version
        log_success $"Nushell source: ($version)"
    } else {
        log_warn "Nushell source: Not downloaded"
    }

    # Check for analysis files
    if ("./tmp/feature_analysis.json" | path exists) {
        log_success "Feature analysis: Complete"
    } else {
        log_warn "Feature analysis: Not run"
    }

    if ("./tmp/dependency_audit.json" | path exists) {
        log_success "Dependency audit: Complete"
    } else {
        log_warn "Dependency audit: Not run"
    }

    if ("./tmp/breaking_changes_report.json" | path exists) {
        log_success "Breaking changes: Analyzed"
    } else {
        log_warn "Breaking changes: Not analyzed"
    }
}

# Clean up temporary files
def "main clean" [] {
    log_info "Cleaning up temporary files..."

    if ("./tmp" | path exists) {
        rm -rf ./tmp
        log_success "Cleaned tmp directory"
    }

    if ("./nushell" | path exists) {
        let response = input "Remove nushell source directory? (yes/no): "
        if $response == "yes" {
            rm -rf ./nushell
            log_success "Removed nushell directory"
        }
    }
}
