# Configuration Accessor - Provides easy access to configuration values
# This module provides helper functions to access configuration safely

use std log

# Configuration cache (note: Nushell doesn't have persistent global state)
# This is a placeholder for documentation purposes

# Get the global configuration (loads and caches on first access)
export def get-config [
    --reload = false                # Force reload configuration
    --debug = false                 # Enable debug logging
    --environment: string           # Override environment
] {
    # Always reload since Nushell doesn't have persistent global state
    use loader.nu load-provisioning-config
    load-provisioning-config --debug=$debug --environment=$environment
}

# Get a configuration value using dot notation (e.g., "paths.base")
export def config-get [
    path: string                    # Configuration path (e.g., "paths.base")
    default_value: any = null       # Default value if path not found
    --config: record                # Optional pre-loaded config
] {
    let config_data = if ($config | is-empty) {
        get-config
    } else {
        $config
    }

    use loader.nu get-config-value
    get-config-value $config_data $path $default_value
}

# Check if a configuration path exists
export def config-has [
    path: string                    # Configuration path to check
    --config: record                # Optional pre-loaded config
] {
    let config_data = if ($config | is-empty) {
        get-config
    } else {
        $config
    }

    let value = (config-get $path null --config $config_data)
    ($value | is-not-empty)
}

# Get all paths configuration as a convenient record
export def get-paths [
    --config: record                # Optional pre-loaded config
] {
    config-get "paths" {} --config $config
}

# Get debug configuration
export def get-debug [
    --config: record                # Optional pre-loaded config
] {
    config-get "debug" {} --config $config
}

# Get SOPS configuration
export def get-sops [
    --config: record                # Optional pre-loaded config
] {
    config-get "sops" {} --config $config
}

# Get validation configuration
export def get-validation [
    --config: record                # Optional pre-loaded config
] {
    config-get "validation" {} --config $config
}

# Get output configuration
export def get-output [
    --config: record                # Optional pre-loaded config
] {
    config-get "output" {} --config $config
}

# Check if debug is enabled
export def is-debug-enabled [
    --config: record                # Optional pre-loaded config
] {
    config-get "debug.enabled" false --config $config
}

# Get the base provisioning path
export def get-base-path [
    --config: record                # Optional pre-loaded config
] {
    config-get "paths.base" "/usr/local/provisioning" --config $config
}

# Get the kloud path
export def get-kloud-path [
    --config: record                # Optional pre-loaded config
] {
    config-get "paths.kloud" "" --config $config
}

# Get SOPS key search paths
export def get-sops-key-paths [
    --config: record                # Optional pre-loaded config
] {
    config-get "sops.key_search_paths" [] --config $config
}

# Find the first existing SOPS key file
export def find-sops-key [
    --config: record                # Optional pre-loaded config
] {
    let key_paths = (get-sops-key-paths --config $config)

    for path in $key_paths {
        if ($path | path exists) {
            return $path
        }
    }

    ""
}

# Set up environment variables for backward compatibility
export def setup-env-compat [
    --config: record                # Optional pre-loaded config
] {
    let config_data = if ($config | is-empty) {
        get-config
    } else {
        $config
    }

    # Set up key environment variables for backward compatibility
    $env.PROVISIONING = (config-get "paths.base" "/usr/local/provisioning" --config $config_data)
    $env.PROVISIONING_KLOUD_PATH = (config-get "paths.kloud" "" --config $config_data)
    $env.PROVISIONING_DEBUG = (config-get "debug.enabled" false --config $config_data | into string)
    $env.PROVISIONING_USE_SOPS = (config-get "sops.use_sops" "age" --config $config_data)

    # Set SOPS key if found
    let sops_key = (find-sops-key --config $config_data)
    if ($sops_key | is-not-empty) {
        $env.SOPS_AGE_KEY_FILE = $sops_key
    }
}

# Show current configuration (useful for debugging)
export def show-config [
    --section: string               # Show only a specific section
    --format: string = "yaml"       # Output format (yaml, json, table)
] {
    let config_data = (get-config)

    let output_data = if ($section | is-not-empty) {
        config-get $section {} --config $config_data
    } else {
        $config_data
    }

    match $format {
        "json" => { $output_data | to json --indent 2 | print }
        "table" => { $output_data | print }
        _ => { $output_data | to yaml | print }
    }
}

# Validate current configuration and show any issues
export def validate-current-config [] {
    let config_data = (get-config --debug=true)
    print "✅ Configuration is valid"
}

# Helper functions to replace common (get-provisioning-* patterns

# Get provisioning name
export def get-provisioning-name [
    --config: record                # Optional pre-loaded config
] {
    config-get "core.name" "provisioning" --config $config
}

# Get provisioning args
export def get-provisioning-args [
    --config: record                # Optional pre-loaded config
] {
    $env.PROVISIONING_ARGS? | default ""
}

# Get provisioning output path
export def get-provisioning-out [
    --config: record                # Optional pre-loaded config
] {
    $env.PROVISIONING_OUT? | default ""
}

# Check if no-terminal mode is enabled
export def is-no-terminal [
    --config: record                # Optional pre-loaded config
] {
    config-get "debug.no_terminal" false --config $config
}

# Get work format (yaml/json)
export def get-work-format [
    --config: record                # Optional pre-loaded config
] {
    config-get "output.format" "yaml" --config $config
}

# Get providers path
export def get-providers-path [
    --config: record                # Optional pre-loaded config
] {
    config-get "paths.providers" "" --config $config
}

# Get taskservs path
export def get-taskservs-path [
    --config: record                # Optional pre-loaded config
] {
    config-get "paths.taskservs" "" --config $config
}

# Get current timestamp
export def get-now [] {
    $env.NOW? | default (date now | format date "%Y_%m_%d_%H_%M_%S")
}

# Check if metadata is enabled
export def is-metadata-enabled [
    --config: record                # Optional pre-loaded config
] {
    config-get "debug.metadata" false --config $config
}

# Check if debug check is enabled
export def is-debug-check-enabled [
    --config: record                # Optional pre-loaded config
] {
    config-get "debug.check" false --config $config
}

# Helper functions for non-PROVISIONING environment variables

# Get SSH options
export def get-ssh-options [
    --config: record                # Optional pre-loaded config
] {
    config-get "ssh.options" [] --config $config
}

# Get current infrastructure path
export def get-current-infra-path [] {
    $env.CURRENT_INFRA_PATH? | default ($env.PWD? | default "")
}

# Get current kloud path
export def get-current-kloud-path [] {
    $env.CURRENT_KLOUD_PATH? | default ""
}

# Get SOPS age key file path
export def get-sops-age-key-file [
    --config: record                # Optional pre-loaded config
] {
    let sops_key = (find-sops-key --config $config)
    if ($sops_key | is-not-empty) { $sops_key } else { "" }
}

# Get SOPS age recipients
export def get-sops-age-recipients [
    --config: record                # Optional pre-loaded config
] {
    $env.SOPS_AGE_RECIPIENTS? | default ""
}

# Get KCL module path
export def get-kcl-mod-path [
    --config: record                # Optional pre-loaded config
] {
    let config_data = if ($config | is-empty) { get-config } else { $config }
    let base_path = (config-get "paths.base" "" --config $config_data)
    let providers_path = (config-get "paths.providers" "" --config $config_data)

    [
        ($base_path | path join "kcl")
        $providers_path
        ($env.PWD? | default "")
    ] | uniq | str join ":"
}

# Get work variable for current context
export def get-wk-cnprov [] {
    $env.WK_CNPROV? | default ""
}

# Setter functions for backward compatibility

# Set debug enabled state
export def set-debug-enabled [value: bool] {
    $env.PROVISIONING_DEBUG = $value
}

# Set provisioning output path
export def set-provisioning-out [path: string] {
    $env.PROVISIONING_OUT = $path
}

# Set no-terminal mode
export def set-provisioning-no-terminal [value: bool] {
    $env.PROVISIONING_NO_TERMINAL = $value
}

# Set work context path
export def set-wk-cnprov [path: string] {
    $env.WK_CNPROV = $path
}

# Set metadata enabled state
export def set-metadata-enabled [value: bool] {
    $env.PROVISIONING_METADATA = $value
}

# Get provisioning work format
export def get-provisioning-wk-format [
    --config: record                # Optional pre-loaded config
] {
    config-get "output.format" "yaml" --config $config
}

# Get provisioning version
export def get-provisioning-vers [
    --config: record                # Optional pre-loaded config
] {
    config-get "core.version" "2.0.0" --config $config
}

# Get provisioning no terminal
export def get-provisioning-no-terminal [
    --config: record                # Optional pre-loaded config
] {
    config-get "debug.no_terminal" false --config $config
}

# Get provisioning generate directory path
export def get-provisioning-generate-dirpath [
    --config: record                # Optional pre-loaded config
] {
    config-get "paths.generate" "generate" --config $config
}

# Get provisioning generate defs file
export def get-provisioning-generate-defsfile [
    --config: record                # Optional pre-loaded config
] {
    config-get "paths.files.defs" "defs.nu" --config $config
}

# Get provisioning required versions file path
export def get-provisioning-req-versions [
    --config: record                # Optional pre-loaded config
] {
    config-get "paths.files.req_versions" "" --config $config
}

# Additional accessor functions for remaining variables

# Get provisioning vars path
export def get-provisioning-vars [
    --config: record                # Optional pre-loaded config
] {
    config-get "paths.files.vars" "" --config $config
}

# Get provisioning work environment path
export def get-provisioning-wk-env-path [
    --config: record                # Optional pre-loaded config
] {
    $env.PROVISIONING_WK_ENV_PATH? | default ""
}

# Get provisioning resources path
export def get-provisioning-resources [
    --config: record                # Optional pre-loaded config
] {
    config-get "paths.resources" "" --config $config
}

# Get provisioning settings source path
export def get-provisioning-settings-src-path [
    --config: record                # Optional pre-loaded config
] {
    $env.PROVISIONING_SETTINGS_SRC_PATH? | default ""
}

# Get provisioning infra path
export def get-provisioning-infra-path [
    --config: record                # Optional pre-loaded config
] {
    $env.PROVISIONING_KLOUD_PATH? | default (config-get "paths.infra" "" --config $config)
}

# Get clusters path
export def get-clusters-path [
    --config: record                # Optional pre-loaded config
] {
    config-get "paths.clusters" "" --config $config
}

# Get templates path
export def get-templates-path [
    --config: record                # Optional pre-loaded config
] {
    config-get "paths.templates" "" --config $config
}

# Get tools path
export def get-tools-path [
    --config: record                # Optional pre-loaded config
] {
    config-get "paths.tools" "" --config $config
}

# Get file viewer
export def get-file-viewer [
    --config: record                # Optional pre-loaded config
] {
    config-get "output.file_viewer" "bat" --config $config
}

# Get notify icon path
export def get-notify-icon [
    --config: record                # Optional pre-loaded config
] {
    config-get "paths.files.notify_icon" "" --config $config
}

# Get default settings file
export def get-default-settings [
    --config: record                # Optional pre-loaded config
] {
    config-get "paths.files.settings" "settings.k" --config $config
}

# Get match date format
export def get-match-date [
    --config: record                # Optional pre-loaded config
] {
    config-get "output.match_date" "%Y_%m_%d" --config $config
}

# Get provisioning module
export def get-provisioning-module [
    --config: record                # Optional pre-loaded config
] {
    $env.PROVISIONING_MODULE? | default ""
}

# Set provisioning module
export def set-provisioning-module [value: string] {
    $env.PROVISIONING_MODULE = $value
}

# Additional accessor functions for complete migration

# Get provisioning log level
export def get-provisioning-log-level [
    --config: record
] {
    config-get "debug.log_level" "" --config $config
}

# Check if debug remote is enabled
export def is-debug-remote-enabled [
    --config: record
] {
    config-get "debug.remote" false --config $config
}

# Get provisioning URL
export def get-provisioning-url [
    --config: record
] {
    config-get "core.url" "https://provisioning.systems" --config $config
}

# Get provisioning use SOPS
export def get-provisioning-use-sops [
    --config: record
] {
    config-get "sops.use_sops" "age" --config $config
}

# Get provisioning use KMS
export def get-provisioning-use-kms [
    --config: record
] {
    config-get "sops.use_kms" "" --config $config
}

# Get secret provider
export def get-secret-provider [
    --config: record
] {
    config-get "sops.secret_provider" "sops" --config $config
}

# Get AI enabled
export def get-ai-enabled [
    --config: record
] {
    config-get "ai.enabled" false --config $config
}

# Get AI provider
export def get-ai-provider [
    --config: record
] {
    config-get "ai.provider" "openai" --config $config
}

# Get last error
export def get-last-error [
    --config: record
] {
    $env.PROVISIONING_LAST_ERROR? | default ""
}

# Get run taskservs path
export def get-run-taskservs-path [
    --config: record
] {
    config-get "paths.run_taskservs" "taskservs" --config $config
}

# Get run clusters path
export def get-run-clusters-path [
    --config: record
] {
    config-get "paths.run_clusters" "clusters" --config $config
}

# Get keys path
export def get-keys-path [
    --config: record
] {
    config-get "paths.files.keys" ".keys.k" --config $config
}

# Get use KCL
export def get-use-kcl [
    --config: record
] {
    config-get "tools.use_kcl" false --config $config
}

# Get use KCL plugin
export def get-use-kcl-plugin [
    --config: record
] {
    config-get "tools.use_kcl_plugin" false --config $config
}

# Get use TERA plugin
export def get-use-tera-plugin [
    --config: record
] {
    config-get "tools.use_tera_plugin" false --config $config
}

# Get extensions path
export def get-extensions-path [
    --config: record
] {
    config-get "paths.extensions" "" --config $config
}

# Get extension mode
export def get-extension-mode [
    --config: record
] {
    config-get "extensions.mode" "full" --config $config
}

# Get provisioning profile
export def get-provisioning-profile [
    --config: record
] {
    config-get "extensions.profile" "" --config $config
}

# Get allowed extensions
export def get-allowed-extensions [
    --config: record
] {
    config-get "extensions.allowed" "" --config $config
}

# Get blocked extensions
export def get-blocked-extensions [
    --config: record
] {
    config-get "extensions.blocked" "" --config $config
}

# Get custom providers
export def get-custom-providers [
    --config: record
] {
    config-get "paths.custom_providers" "" --config $config
}

# Get custom taskservs
export def get-custom-taskservs [
    --config: record
] {
    config-get "paths.custom_taskservs" "" --config $config
}

# Get core nulib path
export def get-core-nulib-path [
    --config: record
] {
    let base = (get-base-path --config $config)
    $base | path join "core" "nulib"
}

# Get prov lib path
export def get-prov-lib-path [
    --config: record
] {
    let providers = (get-providers-path --config $config)
    $providers | path join "prov_lib"
}

# Get provisioning core path
export def get-provisioning-core [
    --config: record
] {
    let base = (get-base-path --config $config)
    $base | path join "core"
}

# KMS (Key Management Service) accessor functions
export def get-kms-server [
    --config: record
] {
    config-get "kms.server" "" --config $config
}

export def get-kms-auth-method [
    --config: record
] {
    config-get "kms.auth_method" "certificate" --config $config
}

export def get-kms-client-cert [
    --config: record
] {
    config-get "kms.client_cert" "" --config $config
}

export def get-kms-client-key [
    --config: record
] {
    config-get "kms.client_key" "" --config $config
}

export def get-kms-ca-cert [
    --config: record
] {
    config-get "kms.ca_cert" "" --config $config
}

export def get-kms-api-token [
    --config: record
] {
    config-get "kms.api_token" "" --config $config
}

export def get-kms-username [
    --config: record
] {
    config-get "kms.username" "" --config $config
}

export def get-kms-password [
    --config: record
] {
    config-get "kms.password" "" --config $config
}

export def get-kms-timeout [
    --config: record
] {
    config-get "kms.timeout" "30" --config $config
}

export def get-kms-verify-ssl [
    --config: record
] {
    config-get "kms.verify_ssl" "true" --config $config
}

# Check if SSH debug mode is enabled
export def is-ssh-debug-enabled [
    --config: record
] {
    config-get "debug.ssh" false --config $config
}