#!/usr/bin/env nu

# Unified Checksums Generation Script
# Creates unified checksums.txt for BOTH nushell-full and plugins-only distributions
# This ensures both package types are included in a single checksums file

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

# Format file size for display
def format_size [bytes: int] {
    if $bytes < 1024 {
        $"($bytes)B"
    } else if $bytes < (1024 * 1024) {
        let kb = ($bytes / 1024)
        $"($kb)KB"
    } else if $bytes < (1024 * 1024 * 1024) {
        let mb = ($bytes / (1024 * 1024) | round -p 1)
        $"($mb)MB"
    } else {
        let gb = ($bytes / (1024 * 1024 * 1024) | round -p 1)
        $"($gb)GB"
    }
}

def main [
    --output (-o): string = "./bin_archives"  # Output directory containing packages
    --platforms: string = ""                   # Comma-separated list of platforms (optional, auto-detect if empty)
    --force (-f)                              # Overwrite existing checksums.txt
] {
    log_info "🔐 Unified Checksums Generation for bin_archives"
    log_info "=================================================="
    log_debug $"force flag value: ($force)"

    # Validate environment
    validate_nushell_version

    if not ($output | path exists) {
        log_error $"Output directory does not exist: ($output)"
        exit 1
    }

    log_info $"📂 Scanning directory: ($output)"

    # Find all distribution packages (both nushell-full and plugins-only)
    let all_archives = (
        (glob $"($output)/nushell-full-*.tar.gz")
        | append (glob $"($output)/nushell-full-*.zip")
        | append (glob $"($output)/plugins-only-*.tar.gz")
        | append (glob $"($output)/plugins-only-*.zip")
    )

    if ($all_archives | length) == 0 {
        log_warn "No distribution packages found in ($output)"
        log_warn "Expected patterns:"
        log_warn "  - nushell-full-*.tar.gz"
        log_warn "  - nushell-full-*.zip"
        log_warn "  - plugins-only-*.tar.gz"
        log_warn "  - plugins-only-*.zip"
        exit 1
    }

    let archive_count = ($all_archives | length)
    log_success $"Found ($archive_count) distribution packages:"
    $all_archives | each {|archive|
        let filename = ($archive | path basename)
        try {
            let stat_info = (stat $archive)
            let size_bytes = ($stat_info | get size)
            let size = (format_size $size_bytes)
            log_info $"  ✓ ($filename) ($size)"
        } catch {
            log_info $"  ✓ ($filename)"
        }
    }

    # Check if checksums.txt already exists
    let checksums_file = $"($output)/checksums.txt"
    if ($checksums_file | path exists) {
        log_debug $"Existing checksums file found, will be overwritten: ($checksums_file)"
    }

    log_info ""
    log_info "📊 Generating checksums..."

    # Generate SHA256 checksums for all packages
    let checksum_data = $all_archives
    | each {|archive|
        let filename = $archive | path basename
        log_debug $"Computing SHA256 for: ($filename)"
        try {
            let hash = (open $archive --raw | hash sha256)
            {
                filename: $filename,
                hash: $hash
            }
        } catch {|err|
            log_error $"Failed to compute checksum for ($filename): ($err.msg)"
            null
        }
    }
    | compact

    if ($checksum_data | length) == 0 {
        log_error "Failed to generate checksums for any packages"
        exit 1
    }

    # Format checksums in standard sha256sum format
    let checksums_content = ($checksum_data
    | each {|item| $"($item.hash)  ($item.filename)" }
    | str join "\n") + "\n"  # Ensure trailing newline

    # Write checksums file
    try {
        $checksums_content | save -f $checksums_file
        let pkg_count = ($checksum_data | length)
        log_success $"✅ Unified checksums.txt created"
        log_success $"📄 File: ($checksums_file)"
        log_success $"📦 Packages included: ($pkg_count)"
        log_info ""
        log_info "Checksums content:"
        log_info "===================="
        $checksums_content | print
        log_info "===================="
    } catch {|err|
        log_error $"Failed to write checksums file: ($err.msg)"
        exit 1
    }

    # Verification: Read back and validate
    log_info ""
    log_info "✓ Verification:"
    try {
        let read_checksums = open $checksums_file
        let line_count = ($read_checksums | lines | length)
        log_success $"✅ Checksums file verified ($line_count) entries"

        # Extract package names and verify they match
        let packages_in_checksums = $read_checksums
        | lines
        | where {|line| ($line | str length) > 0 }
        | each {|line|
            let parts = ($line | split row "  ")
            if ($parts | length) >= 2 {
                $parts | get 1
            }
        }

        log_success $"Packages in checksums:"
        $packages_in_checksums | each {|pkg|
            log_info $"  • ($pkg)"
        }
    } catch {|err|
        log_error $"Verification failed: ($err.msg)"
        exit 1
    }

    log_success "🎉 Unified checksums generation complete!"
}

# Call main (arguments are passed from the command line)
main
