# Copyright (c) 2020-202x The virtualenv developers
#
# Permission is hereby granted, free of charge, to any person obtaining
# a copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject to
# the following conditions:
#
# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

# virtualenv activation module:
# - Activate with `overlay use activate.nu`
# - Deactivate with `deactivate`, as usual
#
# To customize the overlay name, call `overlay use activate.nu as foo`, but then `deactivate` won't work -
# you'd need to run `overlay hide foo` manually. Do not activate with `use activate.nu *`; that does not
# create an overlay and deactivation will fail.

module warning {
    export-env {
        const file = path self
        error make -u {
            msg: $"`($file | path basename)` is meant to be used with `overlay use`, not `source`"
        }
    }

}

use warning

export-env {

    let nu_ver = (version | get version | split row '.' | take 2 | each { into int })
        if $nu_ver.0 == 0 and $nu_ver.1 < 106 {
            error make {
                msg: 'virtualenv Nushell activation requires Nushell 0.106 or greater.'
            }
    }

    def is-string [x] {
        ($x | describe) == 'string'
    }

    def has-env [...names] {
        $names | each {|n| $n in $env } | all {|i| $i }
    }

    def is-env-true [name: string] {
        if (has-env $name) {
            let val = ($env | get --optional $name)
            if ($val | describe) == 'bool' {
                $val
            } else {
                not ($val | is-empty)
            }
        } else {
            false
        }
    }

    let virtual_env = {{ VIRTUAL_ENV_DIR }}
    let bin = '{{ BIN_NAME }}'
    let path_name = if (has-env 'Path') { 'Path' } else { 'PATH' }
    let venv_path = ([$virtual_env $bin] | path join)
    let new_path = ($env | get $path_name | prepend $venv_path)
    let virtual_env_prompt = if ('{{ VIRTUAL_PROMPT }}' | is-empty) {
        ($virtual_env | path basename)
    } else {
        '{{ VIRTUAL_PROMPT }}'
    }
    let new_env = { $path_name: $new_path VIRTUAL_ENV: $virtual_env VIRTUAL_ENV_PROMPT: $virtual_env_prompt }
    let old_prompt_command = if (has-env 'PROMPT_COMMAND') { $env.PROMPT_COMMAND } else { '' }
    let new_env = if (is-env-true 'VIRTUAL_ENV_DISABLE_PROMPT') {
        $new_env
    } else {
        let virtual_prefix = $'(char lparen)($virtual_env_prompt)(char rparen) '
        let new_prompt = if (has-env 'PROMPT_COMMAND') {
            if ('closure' in ($old_prompt_command | describe)) {
                {|| $'($virtual_prefix)(do $old_prompt_command)' }
            } else {
                {|| $'($virtual_prefix)($old_prompt_command)' }
            }
        } else {
            {|| $'($virtual_prefix)' }
        }
        $new_env | merge { PROMPT_COMMAND: $new_prompt VIRTUAL_PREFIX: $virtual_prefix }
    }
    load-env $new_env
}

export alias pydoc = python -m pydoc
# If deactivate errors "not an active overlay": activate with `overlay use activate.nu` not `use activate.nu *`; for custom names use `overlay hide NAME`
export alias deactivate = overlay hide activate
