#!/usr/bin/env nu
# Version registry management for taskservs
# Handles the central version registry and integrates with taskserv configurations

use ./core.nu *
use ./taskserv.nu *
use ../interface.nu *

# Load the version registry
export def load-version-registry [
    --registry-file: string = ""
] {
    let registry_path = if ($registry_file | is-not-empty) {
        $registry_file
    } else {
        ($env.PROVISIONING | path join "core" | path join "taskservs-versions.yaml")
    }

    if not ($registry_path | path exists) {
        _print $"⚠️ Version registry not found: ($registry_path)"
        return {}
    }

    open $registry_path
}

# Update registry with latest version information
export def update-registry-versions [
    --components: list = []  # Specific components to update, empty for all
    --dry-run = false
] {
    let registry = (load-version-registry)

    if ($registry | is-empty) {
        _print "❌ Could not load version registry"
        return
    }

    let components_to_update = if ($components | is-empty) {
        $registry | transpose key value | get key
    } else {
        $components
    }

    _print $"Updating versions for ($components_to_update | length) components..."

    for component in $components_to_update {
        let component_config = if ($component in ($registry | columns)) { $registry | get $component } else { null }

        if ($component_config | is-empty) {
            _print $"⚠️ Component '($component)' not found in registry"
            continue
        }

        if ($component_config.fixed | default false) {
            _print $"🔒 Skipping pinned component: ($component)"
            continue
        }

        if ($component_config.source | is-empty) {
            _print $"⚠️ No source configured for: ($component)"
            continue
        }

        _print $"🔍 Checking latest version for: ($component)"

        let latest_versions = (fetch-versions $component_config.source --limit=5)
        if ($latest_versions | is-empty) {
            _print $"❌ Could not fetch versions for: ($component)"
            continue
        }

        let latest = ($latest_versions | get 0)
        let current = ($component_config.current_version | default "")

        if $latest != $current {
            _print $"📦 ($component): ($current) -> ($latest)"
            if not $dry_run {
                # Update registry with new version
                update-registry-component $component "current_version" $latest
                update-registry-component $component "latest_check" (date now | format date "%Y-%m-%d %H:%M:%S")
            }
        } else {
            _print $"✅ ($component): up to date at ($current)"
        }
    }

    if not $dry_run {
        _print "✅ Registry update completed"
    } else {
        _print "🔍 Dry run completed - no changes made"
    }
}

# Update a specific component field in the registry
export def update-registry-component [
    component_id: string
    field: string
    value: string
] {
    let registry_path = ($env.PROVISIONING | path join "core" | path join "taskservs-versions.yaml")

    if not ($registry_path | path exists) {
        _print $"❌ Registry file not found: ($registry_path)"
        return
    }

    let registry = (open $registry_path)
    let component_config = if ($component_id in ($registry | columns)) { $registry | get $component_id } else { null }

    if ($component_config | is-empty) {
        _print $"❌ Component '($component_id)' not found in registry"
        return
    }

    let updated_component = ($component_config | upsert $field $value)
    let updated_registry = ($registry | upsert $component_id $updated_component)

    $updated_registry | save -f $registry_path
}

# Compare registry versions with taskserv configurations
export def compare-registry-with-taskservs [
    --taskservs-path: string = ""
] {
    let registry = (load-version-registry)
    let taskserv_configs = (discover-taskserv-configurations --base-path=$taskservs_path)

    if ($registry | is-empty) or ($taskserv_configs | is-empty) {
        _print "❌ Could not load registry or taskserv configurations"
        return []
    }

    # Group taskservs by component type
    let taskserv_by_component = ($taskserv_configs | group-by { |config|
        # Extract component name from ID (handle both "component" and "server::component" formats)
        if ($config.id | str contains "::") {
            ($config.id | split row "::" | get 1)
        } else {
            $config.id
        }
    })

    let comparisons = ($registry | transpose component registry_config | each { |registry_item|
        let component = $registry_item.component
        let registry_version = ($registry_item.registry_config.current_version | default "")
        let taskservs = if ($component in ($taskserv_by_component | columns)) { $taskserv_by_component | get $component } else { [] }

        if ($taskservs | is-empty) {
            {
                component: $component
                registry_version: $registry_version
                taskserv_configs: []
                status: "unused"
                summary: "Not used in any taskservs"
            }
        } else {
            let taskserv_versions = ($taskservs | each { |ts| {
                id: $ts.id
                version: $ts.version
                file: $ts.nickel_file
                matches_registry: ($ts.version == $registry_version)
            }})

            let all_match = ($taskserv_versions | all { |ts| $ts.matches_registry })
            let any_outdated = ($taskserv_versions | any { |ts| not $ts.matches_registry })

            let status = if $all_match {
                "in_sync"
            } else if $any_outdated {
                "out_of_sync"
            } else {
                "mixed"
            }

            {
                component: $component
                registry_version: $registry_version
                taskserv_configs: $taskserv_versions
                status: $status
                summary: $"($taskserv_versions | length) taskservs, ($taskserv_versions | where matches_registry | length) in sync"
            }
        }
    })

    $comparisons
}

# Show version status summary
export def show-version-status [
    --taskservs-path: string = ""
    --format: string = "table"  # table, detail, json
] {
    let comparisons = (compare-registry-with-taskservs --taskservs-path=$taskservs_path)

    match $format {
        "table" => {
            _print "Taskserv Version Status:"
            _print ($comparisons | select component registry_version status summary | table)
        }
        "detail" => {
            for comparison in $comparisons {
                _print $"\n🔧 ($comparison.component) \\(Registry: ($comparison.registry_version)\\)"
                _print $"   Status: ($comparison.status) - ($comparison.summary)"

                if ($comparison.taskserv_configs | length) > 0 {
                    for config in $comparison.taskserv_configs {
                        let status_icon = if $config.matches_registry { "✅" } else { "❌" }
                        _print $"   ($status_icon) ($config.id): ($config.version)"
                    }
                }
            }
        }
        "json" => {
            print ($comparisons | to json -i 2)
        }
        _ => {
            _print $"❌ Unknown format: ($format). Use 'table', 'detail', or 'json'"
        }
    }
}

# Pin/unpin component in registry
export def set-registry-fixed [
    component_id: string
    fixed: bool
] {
    update-registry-component $component_id "fixed" ($fixed | into string)

    if $fixed {
        _print $"🔒 Pinned ($component_id) in registry"
    } else {
        _print $"🔓 Unpinned ($component_id) in registry"
    }
}
