# Version Loader - Load versions from Nickel sources
# Token-optimized loader for version data from various sources

# Load version from source (Nickel files)
export def load-version-from-source [
    component: string       # Component name
] {
    # Try different source locations
    let taskserv_version = (load-taskserv-version $component)
    if ($taskserv_version | is-not-empty) {
        return $taskserv_version
    }

    let core_version = (load-core-version $component)
    if ($core_version | is-not-empty) {
        return $core_version
    }

    let provider_version = (load-provider-version $component)
    if ($provider_version | is-not-empty) {
        return $provider_version
    }

    ""
}

# Load taskserv version from version.ncl files
def load-taskserv-version [component: string] {
    # Find version.ncl file for component
    let version_files = [
        $"taskservs/($component)/nickel/version.ncl"
        $"taskservs/($component)/default/nickel/version.ncl"
        $"taskservs/($component)/nickel/($component).ncl"
    ]

    for file in $version_files {
        if ($file | path exists) {
            let version = (extract-version-from-nickel $file $component)
            if ($version | is-not-empty) {
                return $version
            }
        }
    }

    ""
}

# Load core tool version
def load-core-version [component: string] {
    let core_file = "core/versions.ncl"

    if ($core_file | path exists) {
        let version = (extract-core-version-from-nickel $core_file $component)
        if ($version | is-not-empty) {
            return $version
        }
    }

    ""
}

# Load provider tool version
def load-provider-version [component: string] {
    # Check provider directories
    let providers = ["aws", "upcloud", "local"]

    for provider in $providers {
        let provider_files = [
            $"providers/($provider)/nickel/versions.ncl"
            $"providers/($provider)/versions.ncl"
        ]

        for file in $provider_files {
            if ($file | path exists) {
                let version = (extract-version-from-nickel $file $component)
                if ($version | is-not-empty) {
                    return $version
                }
            }
        }
    }

    ""
}

# Extract version from Nickel file (taskserv format)
def extract-version-from-nickel [file: string, component: string] {
    let decl_result = (^nickel $file | complete)

    if $decl_result.exit_code != 0 {
        return ""
    }

    if ($decl_result.stdout | is-empty) {
        return ""
    }

    let parse_result = (do { $decl_result.stdout | from yaml } | complete)
    if $parse_result.exit_code != 0 {
        return ""
    }

    let result = $parse_result.stdout

    # Try different version key patterns
    let version_keys = [
        $"($component)_version"
        "_version"
        "version"
    ]

    for key in $version_keys {
        let lookup_result = (do { $result | get $key } | complete)
        let version_data = if $lookup_result.exit_code == 0 { $lookup_result.stdout } else { {} }

        if ($version_data | is-not-empty) {
            # Try TaskservVersion format first
            let cv_result = (do { $version_data | get version.current } | complete)
            let current_version = if $cv_result.exit_code == 0 { $cv_result.stdout } else { "" }
            if ($current_version | is-not-empty) {
                return $current_version
            }

            # Try simple format
            let sv_result = (do { $version_data | get current } | complete)
            let simple_version = if $sv_result.exit_code == 0 { $sv_result.stdout } else { "" }
            if ($simple_version | is-not-empty) {
                return $simple_version
            }

            # Try direct string
            if ($version_data | describe) == "string" {
                return $version_data
            }
        }
    }

    ""
}

# Extract version from core versions.ncl file
def extract-core-version-from-nickel [file: string, component: string] {
    let decl_result = (^nickel $file | complete)

    if $decl_result.exit_code != 0 {
        return ""
    }

    if ($decl_result.stdout | is-empty) {
        return ""
    }

    let parse_result = (do { $decl_result.stdout | from yaml } | complete)
    if $parse_result.exit_code != 0 {
        return ""
    }

    let result = $parse_result.stdout

    # Look for component in core_versions array or individual variables
    let cv_result = (do { $result | get core_versions } | complete)
    let core_versions = if $cv_result.exit_code == 0 { $cv_result.stdout } else { [] }

    if ($core_versions | is-not-empty) {
        # Array format
        let component_data = ($core_versions | where name == $component | first | default {})
        let vc_result = (do { $component_data | get version.current } | complete)
        let version = if $vc_result.exit_code == 0 { $vc_result.stdout } else { "" }
        if ($version | is-not-empty) {
            return $version
        }
    }

    # Individual variable format (e.g., nu_version, nickel_version)
    let var_patterns = [
        $"($component)_version"
        $"($component | str replace '-' '_')_version"
    ]

    for pattern in $var_patterns {
        let vd_result = (do { $result | get $pattern } | complete)
        let version_data = if $vd_result.exit_code == 0 { $vd_result.stdout } else { {} }
        if ($version_data | is-not-empty) {
            let curr_result = (do { $version_data | get current } | complete)
            let current = if $curr_result.exit_code == 0 { $curr_result.stdout } else { "" }
            if ($current | is-not-empty) {
                return $current
            }
        }
    }

    ""
}

# Batch load multiple versions (for efficiency)
export def batch-load-versions [
    components: list<string>    # List of component names
] {
    mut results = {}

    for component in $components {
        let version = (load-version-from-source $component)
        if ($version | is-not-empty) {
            $results = ($results | upsert $component $version)
        }
    }

    $results
}

# Get all available components
export def get-all-components [] {
    let taskservs = (get-taskserv-components)
    let core_tools = (get-core-components)
    let providers = (get-provider-components)

    ($taskservs ++ $core_tools ++ $providers) | uniq
}

# Get taskserv components
def get-taskserv-components [] {
    let result = (do { glob "taskservs/*/nickel/version.ncl" } | complete)
    if $result.exit_code != 0 {
        return []
    }

    $result.stdout | each { |file|
        $file | path dirname | path dirname | path basename
    }
}

# Get core components
def get-core-components [] {
    if not ("core/versions.ncl" | path exists) {
        return []
    }

    let decl_result = (^nickel "core/versions.ncl" | complete)
    if $decl_result.exit_code != 0 or ($decl_result.stdout | is-empty) {
        return []
    }

    let parse_result = (do { $decl_result.stdout | from yaml } | complete)
    if $parse_result.exit_code != 0 {
        return []
    }

    let result = $parse_result.stdout
    $result | columns | where { |col| $col | str ends-with "_version" } | each { |col|
        $col | str replace "_version" ""
    }
}

# Get provider components (placeholder)
def get-provider-components [] {
    # TODO: Implement provider component discovery
    []
}
