# Workspace and Infrastructure Detection
# Provides PWD-based inference and context management for workspace and infrastructure

# Selective imports (ADR-025 Phase 3 Layer 2).
# Name collision: get-workspace-path + list-workspaces exported by both
# user/config.nu and workspace/notation.nu. Attribute to notation.nu
# (consistent with workspace/commands.nu treatment).
use lib_provisioning/user/config.nu [get-active-workspace]
use lib_provisioning/workspace/notation.nu [get-workspace-path list-workspaces]

# Infer workspace from current working directory
# Checks if PWD is inside any registered workspace path
export def infer-workspace-from-pwd [] {
    let pwd = $env.PWD
    let workspaces = (list-workspaces)

    # Check if PWD is inside any workspace path
    for ws in $workspaces {
        let ws_path = ($ws.path)
        if ($pwd | str starts-with $ws_path) {
            return $ws.name
        }
    }

    null
}

# Get effective workspace (with fallbacks)
# Priority: TEMP_WORKSPACE → active workspace → PWD inference → error
export def get-effective-workspace [] {
    # Check temporal override first
    if ($env.TEMP_WORKSPACE? | is-not-empty) {
        return $env.TEMP_WORKSPACE
    }

    # Check active workspace
    let active = (get-active-workspace)
    if ($active | is-not-empty) {
        return $active
    }

    # Try PWD inference
    let inferred = (infer-workspace-from-pwd)
    if ($inferred | is-not-empty) {
        print $"⚠️  No active workspace, inferred from PWD: ($inferred)"
        print "💡 Activate permanently: provisioning workspace activate <name>"
        return $inferred
    }

    # Error - no workspace available
    error make {
        msg: "No workspace active or inferable from PWD. Run: provisioning workspace activate <name>"
    }
}

# Detect infrastructure from PWD
# Checks if PWD is in workspace/infra/{name}/ directory structure
export def detect-infra-from-pwd [] {
    let pwd = $env.PWD

    # Check if we're directly in an infra directory by looking for settings.ncl
    let settings_file = ([$pwd "settings.ncl"] | path join)
    if ($settings_file | path exists) {
        return ($pwd | path basename)
    }

    # Check parent directories up to workspace root
    let workspace = (infer-workspace-from-pwd)
    if ($workspace | is-empty) {
        return null
    }

    let workspace_path = (get-workspace-path $workspace)
    let infra_base = ([$workspace_path "infra"] | path join)

    # Check if PWD is under infra_base
    if ($pwd | str starts-with $infra_base) {
        let relative = ($pwd | str replace $infra_base "")
        let parts = ($relative | split row "/" | where {|x| ($x | is-not-empty)})
        if ($parts | length) > 0 {
            return ($parts | get 0)
        }
    }

    null
}

# Get effective infrastructure with fallbacks
# Priority: Explicit flag → PWD detection → default_infra → null
export def get-effective-infra [
    workspace: string
] {
    # Priority 1: PWD detection
    let pwd_infra = (detect-infra-from-pwd)
    if ($pwd_infra | is-not-empty) {
        return $pwd_infra
    }

    # Priority 2: Check for environment variable override
    if ($env.PROVISIONING_INFRA? | is-not-empty) {
        return $env.PROVISIONING_INFRA
    }

    # Priority 3: Will be handled at call site with --infra flag or default_infra
    null
}

# Check if workspace is active
export def is-workspace-active [workspace_name: string] {
    let active = (get-active-workspace)
    $active == $workspace_name
}

# Check if in workspace directory
export def is-in-workspace [workspace_name: string] {
    let pwd = $env.PWD
    let workspace_path = (get-workspace-path $workspace_name)
    $pwd | str starts-with $workspace_path
}

# Check if in specific infrastructure directory
export def is-in-infra [workspace_name: string, infra_name: string] {
    let pwd = $env.PWD
    let workspace_path = (get-workspace-path $workspace_name)
    let infra_path = ([$workspace_path "infra" $infra_name] | path join)
    $pwd | str starts-with $infra_path
}

# Get inferred context (workspace + infra)
# Returns record with both workspace and infra if detectable
export def get-inferred-context [] {
    let workspace = (infer-workspace-from-pwd)
    let infra = if ($workspace | is-not-empty) {
        detect-infra-from-pwd
    } else {
        null
    }

    {
        workspace: $workspace
        infra: $infra
    }
}
