{%- let SECTION = "# =============================================================================\n#" -%}
{%- let NOT_CONFIGURED = "# -- not configured --" -%}

{%- if resolve_symlinks -%}
import os
{%- endif %}
import os.path
import subprocess
import sys

from subprocess import CalledProcessError

{{ SECTION }}
# Utility functions for zoxide.
#

# pwd based on the value of _ZO_RESOLVE_SYMLINKS.
def __zoxide_pwd() -> str:
{%- if resolve_symlinks %}
    return os.getcwd()
{%- else %}
    return $PWD
{%- endif %}

# cd + custom logic based on the value of _ZO_ECHO.
def __zoxide_cd(path: str):
    cd @(path) {%- if echo %} and print(__zoxide_pwd()) {%- endif %}

{{ SECTION }}
# Hook configuration for zoxide.
#

# Initialize hook to add new entries to the database.
{%- match hook %}
{%- when Hook::None %}
{{ NOT_CONFIGURED }}

{%- when Hook::Prompt %}
@events.on_post_prompt

{%- when Hook::Pwd %}
@events.on_chdir

{%- endmatch %}
def __zoxide_hook(**kwargs):
    zoxide add @(__zoxide_pwd())

{{ SECTION }}
# When using zoxide with --no-aliases, alias these internal functions as
# desired.
#

# Jump to a directory using only keywords.
def __zoxide_z(keywords: [str]):
    if keywords == []:
        __zoxide_cd($HOME)
    elif keywords == ['-']:
        __zoxide_cd('-')
    elif len(keywords) == 1 and os.path.isdir(keywords[0]):
        __zoxide_cd(keywords[0])
    else:
        try:
            __zoxide_cmd = subprocess.run(["zoxide", "query", "--"] + keywords, check=True, stdout=subprocess.PIPE)
        except CalledProcessError as e:
            return e.returncode

        try:
            __zoxide_result = __zoxide_cmd.stdout[:-1].decode("utf-8")
        except UnicodeDecodeError:
            print(f"zoxide: invalid unicode in result: {__zoxide_result}", file=sys.stderr)
            return 1

        __zoxide_cd(__zoxide_result)

# Jump to a directory using interactive search.
def __zoxide_zi(keywords: [str]):
    try:
        __zoxide_cmd = subprocess.run(["zoxide", "query", "-i", "--"] + keywords, check=True, stdout=subprocess.PIPE)
    except CalledProcessError as e:
        return e.returncode

    try:
        __zoxide_result = __zoxide_cmd.stdout[:-1].decode("utf-8")
    except UnicodeDecodeError:
        print(f"zoxide: invalid unicode in result: {__zoxide_result}", file=sys.stderr)
        return 1

    __zoxide_cd(__zoxide_result)


# Add a new entry to the database.
def __zoxide_za(args: [str]):
    zoxide add @(args)

# Query an entry from the database using only keywords.
def __zoxide_zq(args: [str]):
    zoxide query @(args)

# Query an entry from the database using interactive selection.
def __zoxide_zqi(args: [str]):
    zoxide query -i @(args)

# Remove an entry from the database using the exact path.
def __zoxide_zr(args: [str]):
    zoxide remove @(args)

# Remove an entry from the database using interactive selection.
def __zoxide_zri(args: [str]):
    zoxide remove -i @(args)

{{ SECTION }}
# Convenient aliases for zoxide. Disable these using --no-aliases.
#

{%- match cmd %}
{%- when Some with (cmd) %}

aliases['{{cmd}}'] = __zoxide_z
aliases['{{cmd}}i'] = __zoxide_zi
aliases['{{cmd}}a'] = __zoxide_za
aliases['{{cmd}}q'] = __zoxide_zq
aliases['{{cmd}}qi'] = __zoxide_zqi
aliases['{{cmd}}r'] = __zoxide_zr
aliases['{{cmd}}ri'] = __zoxide_zri

{%- when None %}
{{ NOT_CONFIGURED }}

{%- endmatch %}

{{ SECTION }}
# To initialize zoxide with xonsh, add the following line to your xonsh
# configuration file (usually ~/.xonshrc):
#
# execx($(zoxide init xonsh), 'exec', __xonsh__.ctx, filename='zoxide')
