#!/data/data/com.qflistudio.azure/files/usr/bin/bash
# shellcheck shell=bash

if [ -z "${BASH_VERSION:-}" ]; then
    echo "The 'termux-scoped-env-variable.bash' script must be run from a 'bash' shell."; return 64 2>/dev/null|| exit 64 # EX__USAGE
fi

##
# `termux_core__bash__termux_scoped_env_variable__show_help`
##
termux_core__bash__termux_scoped_env_variable__show_help() {

    cat <<'HELP_EOF'
termux-scoped-env-variable.bash can be used to get/set/unset variable
names and values for `TERMUX*__` and other scoped environment
variables exported by different Termux runtime components, with
support for fallback values and validation of values.


Usage:
  termux-scoped-env-variable.bash <command> <args...>


Available commands:
    get-name                     Get Termux scoped variable name.
    get-value                    Get Termux scoped variable value.
    set-value                    Set Termux scoped variable value.
    unset-value                  Unset Termux scoped variable value.



get-name:
  termux-scoped-env-variable.bash get-name \
    <output_mode> \
    <scoped_var_scope_mode> <scoped_var_sub_name>



get-value:
  termux-scoped-env-variable.bash get-value \
    <output_mode> \
    <scoped_var_scope_mode> <scoped_var_sub_name> \
    <extended_validator> [<default_values...>]



set-value:
  termux-scoped-env-variable.bash set-value \
    <scoped_var_scope_mode> <scoped_var_sub_name> \
    <value_to_set>



unset-value:
  termux-scoped-env-variable.bash unset-value \
    <scoped_var_scope_mode> <scoped_var_sub_name>



Available arguments:
- `output_mode`: The output mode for the command.
  If set to a valid environment variable name (like `TERMUX__VAR`) or
  a bash array variable (like `TERMUX__ARRAY[0]`), then output will be
  set to the variable.
  Otherwise, it must be set to `>` so that output is printed to
  `stdout`, or set to `-` so that output is not printed at all and
  only exit code is returned.
- `scoped_var_scope_mode`: The scope mode of the scoped environment
  variable name to get/set/unset.
- `scoped_var_sub_name`: The sub name of the scoped environment
  variable name to get/set/unset after the scope name.
- `extended_validator`: The extended validator for whether a
  particular variable value is valid and should be returned or not.
- `default_values`: One or more fallback default values. This may
  optionally be a placeholder value that gets replaced during build
  time.
- `value_to_set`: The value to set to the scoped environment variable.



The `get-name` command type returns the name of the Termux scoped
environment variable generated depending on the variable scope and sub
name passed.

The `get-value` command type returns the value for the Termux scoped
environment variable generated depending on the variable scope and sub
name passed. First its value is read from the environment, followed by
reading the optional values passed as `default_values`, and whichever
value first matches the `extended_validator` is returned and if no
value matches, then the call will return with exit code
`81` (`C_EX__NOT_FOUND`). If the `scoped_var_scope_mode` argument is
not set, then the environment variable is not read and only any
default values passed are checked.

The `set-value` command type sets the value of the Termux scoped
environment variable generated to the value passed as `value_to_set`.

The `unset-value` command type unsets the value of the Termux scoped
environment variable generated by running the `unset` command.

The `set-value` and `unset-value` command types are not available if
executing the `termux-scoped-env-variable.bash` script as they will
not have any effect on the calling process environment and are only
available if the script is sourced and the
`termux_core__bash__termux_scoped_env_variable` function is called.



The scoped environment variable name to get/set/unset is generated
based on the `scoped_var_scope_mode` and `scoped_var_sub_name`
arguments.
The `scoped_var_scope_mode` argument must be equal to one of
the following formats:
- `s=<scoped_var_scope_name>`: The variable name is generated as per
  `${scoped_var_scope_name}${scoped_var_sub_name}`. The root scope
  is assumed to be part of the `scoped_var_scope_name` argument and
  Termux root scope is not prefixed to it. This can be used if
  `scoped_var_scope_name` was already generated with the Termux root
  scope or if getting a variable for an external app under a
  different root scope.
- `ss=<scoped_var_sub_scope_name>`: The variable name is generated as per
  `${root_scope_name}${scoped_var_sub_scope_name}${scoped_var_sub_name}`,
  where the `root_scope_name` is the value set in the
  `$TERMUX_ENV__S_ROOT` environment variable, with a fallback to the
  build time placeholder`TERMUX_`, and then to the
  hardcoded root scope value `TERMUX_` for the upstream Termux app.
- `cn=<scoped_var_component_name>`: The variable name is generated as
    per the component name passed from the list below, where the value
    in the bracket defines the sub scope value used for variable name
    generation.
    - `cn=termux`            (`ss="_"`)
    - `cn=termux-app`        (`ss="APP__"`)
    - `cn=termux-api-app`    (`ss="API_APP__"`)
    - `cn=termux-float-app`  (`ss="FLOAT_APP__"`)
    - `cn=termux-gui-app`    (`ss="GUI_APP__"`)
    - `cn=termux-tasker-app` (`ss="TASKER_APP__"`)
    - `cn=termux-widget-app` (`ss="WIDGET_APP__"`)
    - `cn=termux-x11-app`    (`ss="X11_APP__"`)
    - `cn=termux-core`       (`ss="CORE__"`)
    - `cn=termux-exec`       (`ss="EXEC__"`)

Optionally, only the `scoped_var_scope_mode` argument may be
passed with the `scoped_var_sub_name` argument as an empty string.
This can be used for the `get-name` command and a
`ss=<scoped_var_sub_scope_name>` formatted argument to get the
full scope name with the Termux root scope prefixed to the sub scope.



The `extended_validator` argument must be equal to one of the
following formats. The `value` refers to the values that are checked
for a match, like defined by the Termux scoped environment variable
or the `default_values`.
- `?`: Matches `value` if it is set and not empty.
- `*`: Matches `value` if it is set, or defined but empty.
- `r+=<regex>`: Matches `value` if it matches the `<regex>`.
- `r-=<regex>`: Matches `value` if it does not match the `<regex>`.
- `c+=<command>`: Matches `value` if `<command>` passed the `value` as
                  an argument exits with exit code `0`.
- `c-=<command>`: Matches `value` if `<command>` passed the `value` as
                  an argument does not exit with exit code `0`.

For the `r+=<regex>` and `r-=<regex>` formats, the leading `r+=` or
`r-=` characters are removed from `extended_validator` and
remaining part is matched against the `value` with the bash `=~` if
conditional. The `<regex>` argument must be a valid POSIX extended
regular expression (`REG_EXTENDED`).
For example, the argument `r+='^((/)|((/[^/]+)+))$'` would match a
`value` that is a valid absolute path (including rootfs `/`).
For more info, check:
- https://www.gnu.org/software/bash/manual/html_node/Conditional-Constructs.html#index-_005b_005b
- https://www.man7.org/linux/man-pages/man3/regex.3.html
- https://www.man7.org/linux/man-pages/man7/regex.7.html

For the `c+=<command>` and `c-=<command>` formats, the leading `c+=`
or `c-=` characters are removed from `extended_validator` and
remaining part is passed as an argument to `<command>` and executed.
The `<command>` string must be set to an executable in `$PATH`,
or a path to an executable, or a function name in the current
execution environment, optionally followed with arguments.
This is checked with the `command -v` command and if that fails, then
the first argument is checked to see if its an absolute or relative
path to an executable (`+x`) file. For more info, check:
- https://pubs.opengroup.org/onlinepubs/9699919799/utilities/command.html

The `value` is passed as the last argument to `<command>`, or the
first if `<command>` itself does not have any argument.
Any arguments in `<command>` itself should be quoted with single or
double quotes if they have whitespace (IFS) characters, like
`c+='value_validator "some arg"`.
The `stdout` and `stderr` streams are not redirected to
`/dev/null` when executing the command, and must be manually done
in the function if required or the quiet `-q` options be used for
commands like `grep`, otherwise the `stdout` of the command will
pollute the normal result output for the matched value if it is to be
printed to `stdout`.
For example, the arguments `c+='value_validator'` and
`c+='value_validator some_arg'` would match the `value` if the
commands `value_validator "value"` and
`value_validator some_arg "value"` respectively would exit with exit
code `0`.
Note that if `termux-scoped-env-variable.bash` is being
executed, instead of the
`termux_core__bash__termux_scoped_env_variable` local function
being called, any function in the `<command>` argument must first be
exported with the `export -f <function>` command to be defined in
the executed child process, assuming if executing from a `bash` shell.
For more info, check:
- https://www.gnu.org/software/bash/manual/bash.html#Shell-Functions
- https://www.gnu.org/software/bash/manual/bash.html#index-export



**See Also:**
- https://github.com/termux/termux-core-package/blob/master/site/pages/en/projects/docs/usage/utils/termux/shell/command/environment/termux-scoped-env-variable.md
- https://github.com/termux/termux-core-package/blob/master/app/main/scripts/termux/shell/command/environment/termux-scoped-env-variable.bash.in
- https://github.com/termux/termux-packages/blob/master/packages/termux-core/app/main/scripts/termux/shell/command/environment/termux_core__bash__termux_scoped_env_variable
HELP_EOF

}

##
# `termux_core__bash__termux_scoped_env_variable__main` [`<argument...>`]
##
termux_core__bash__termux_scoped_env_variable__main() {

    local return_value

    if [ "$1" = "-h" ] || [ "$1" = "--help" ]; then
        termux_core__bash__termux_scoped_env_variable__show_help || return $?
        return 0
    elif [ "$1" = "--version" ]; then
        echo "termux-scoped-env-variable.bash version=0.4.0 org=termux project=termux-core-package"; return $?
        return 0
    elif [ "$1" = "set-value" ] || [ "$1" = "unset-value" ]; then
        echo "The '$1' command cannot be run if executing the 'termux-scoped-env-variable.bash' script." 1>&2
        return 80 # C_EX__UNSUPPORTED
    else
        termux_core__bash__termux_scoped_env_variable "$@"
        return_value=$?
        if [ $return_value -eq 64 ]; then # EX__USAGE
            echo ""
            termux_core__bash__termux_scoped_env_variable__show_help
        fi
        return $return_value
    fi

}

##### TERMUX_CORE__BASH__TERMUX_SCOPED_ENV_VARIABLE replaced at build time. (START) #####

##
# Get/Set/Unset variable names and values for `TERMUX*__` and other
# scoped environment variables exported by different Termux runtime
# components, with support for fallback values and validation of
# values.
#
# The `extended_validator` logic is based on `libalteran-sh`
# `bash___shell__validate_variable_with_extended_validator()` function.
#
# **See Also:**
# - https://github.com/termux/termux-core-package/blob/master/site/pages/en/projects/docs/usage/utils/termux/shell/command/environment/termux-scoped-env-variable.md
# - https://github.com/termux/termux-core-package/blob/master/app/main/scripts/termux/shell/command/environment/termux-scoped-env-variable.bash.in
# - https://github.com/termux/termux-packages/blob/master/packages/termux-core/app/main/scripts/termux/shell/command/environment/termux_core__bash__termux_scoped_env_variable
#
#
# `termux_core__bash__termux_scoped_env_variable` `get-name` \
#     `<output_mode>` \
#     `<scoped_var_scope_mode>` `<scoped_var_sub_name>`
# `termux_core__bash__termux_scoped_env_variable` `get-value` \
#     `<output_mode>` \
#     `<scoped_var_scope_mode>` `<scoped_var_sub_name>` \
#     `<extended_validator>` [`<default_values...>`]
# `termux_core__bash__termux_scoped_env_variable` `set-value` \
#     `<scoped_var_scope_mode>` `<scoped_var_sub_name>` \
#     `<value_to_set>`
# `termux_core__bash__termux_scoped_env_variable` `unset-value` \
#     `<scoped_var_scope_mode>` `<scoped_var_sub_name>`
##
termux_core__bash__termux_scoped_env_variable() {

    local return_value

    local command_type="${1:-}"
    local command_action="${command_type%%-*}"
    [ $# -gt 0 ] && shift 1

    if [ "$command_type" = "get-name" ]; then
        local output_mode="${1:-}"
        local scoped_var_scope_mode="${2:-}"
        local scoped_var_sub_name="${3:-}"

        if [ $# -ne 3 ]; then
            echo "Invalid argument count $# for the 'get-name' command. \
The 'termux_core__bash__termux_scoped_env_variable' function expects 3 arguments." 1>&2
            printf 'Arguments: %s\n' "$*" 1>&2
            return 64 # EX__USAGE
        fi
    elif [ "$command_type" = "get-value" ]; then
        local output_mode="${1:-}"
        local scoped_var_scope_mode="${2:-}"
        local scoped_var_sub_name="${3:-}"
        local extended_validator="${4:-}"

        local validator_arg
        local validator_mode

        if [ $# -lt 4 ]; then
            echo "Invalid argument count $# for the 'get-value' command. \
The 'termux_core__bash__termux_scoped_env_variable' function expects minimum 4 arguments." 1>&2
            printf 'Arguments: %s\n' "$*" 1>&2
            return 64 # EX__USAGE
        fi

        # Remove args before `default_values` to be used in `var_value_cur` for loop below.
        shift 4

        case "$extended_validator" in
            '?'|'*')
                validator_arg=""
                validator_mode="$extended_validator"
                ;;
            'r+='?*|'r-='?*|'c+='?*|'c-='?*)
                validator_arg="${extended_validator:3}" # 3:end
                validator_mode="${extended_validator:0:3}" # 0:3
                ;;
            *)
                echo "The extended_validator '$extended_validator' \
argument passed to 'termux_core__bash__termux_scoped_env_variable' is not valid. \
It must either be equal to \`?\` or \`*\`, or a regex that starts with \`r+=\` or \`r-=\`, \
or a executable or function that starts with \`c+=\` or \`c-=\`." 1>&2
                return 64 # EX__USAGE
                ;;
        esac
    elif [ "$command_type" = "set-value" ]; then
        local scoped_var_scope_mode="${1:-}"
        local scoped_var_sub_name="${2:-}"
        local value_to_set="${3:-}"

        if [ $# -ne 3 ]; then
            echo "Invalid argument count $# for the 'set-value' command. \
The 'termux_core__bash__termux_scoped_env_variable' function expects 3 arguments." 1>&2
            printf 'Arguments: %s\n' "$*" 1>&2
            return 64 # EX__USAGE
        fi
    elif [ "$command_type" = "unset-value" ]; then
        local scoped_var_scope_mode="${1:-}"
        local scoped_var_sub_name="${2:-}"

        if [ $# -ne 2 ]; then
            echo "Invalid argument count $# for the 'unset-value' command. \
The 'termux_core__bash__termux_scoped_env_variable' function expects 2 arguments." 1>&2
            printf 'Arguments: %s\n' "$*" 1>&2
            return 64 # EX__USAGE
        fi
    else
        echo "The command '$command_type' passed to 'termux_core__bash__termux_scoped_env_variable' is not valid." 1>&2
        return 64 # EX__USAGE
    fi

    local i
    local is_value_valid
    local scoped_var_root_scope_name=""
    local scoped_var_scope_name=""
    local scoped_var_sub_scope_name=""
    local scoped_var_name=""
    local scoped_var_set=""
    local scoped_var_value_invalid_error_suffix=""
    local var_value_cur

    # A valid environment variable name (like `TERMUX__VAR`) or a bash array variable (like `TERMUX__ARRAY[0]`).
    local valid_bash_variable_name_regex='^[a-zA-Z_][a-zA-Z0-9_]*(\[[0-9]+\])?$'


    if [ "$command_action" = "get" ]; then
        if [ "$output_mode" != ">" ] && [ "$output_mode" != "-" ]; then
            # If `output_mode` is not a valid environment variable name.
            if [[ ! "$output_mode" =~ $valid_bash_variable_name_regex ]]; then
                echo "The output_mode '$output_mode' argument passed to \
'termux_core__bash__termux_scoped_env_variable' is not a valid environment variable name, or equal to \`>\` or \`-\`." 1>&2
                return 64 # EX__USAGE
            fi
        fi
    fi


    case "$scoped_var_scope_mode" in
        s=?*) scoped_var_scope_name="${scoped_var_scope_mode:2}";; # 2:end
        ss=?*) scoped_var_sub_scope_name="${scoped_var_scope_mode:3}";; # 3:end
        '') ;;
        cn=termux) scoped_var_sub_scope_name="_";;
        cn=termux-app) scoped_var_sub_scope_name="APP__";;
        cn=termux-api-app) scoped_var_sub_scope_name="API_APP__";;
        cn=termux-float-app) scoped_var_sub_scope_name="FLOAT_APP__";;
        cn=termux-gui-app) scoped_var_sub_scope_name="GUI_APP__";;
        cn=termux-tasker-app) scoped_var_sub_scope_name="TASKER_APP__";;
        cn=termux-widget-app) scoped_var_sub_scope_name="WIDGET_APP__";;
        cn=termux-x11-app) scoped_var_sub_scope_name="X11_APP__";;
        cn=termux-core) scoped_var_sub_scope_name="CORE__";;
        cn=termux-exec) scoped_var_sub_scope_name="EXEC__";;
        *)
            echo "The scoped_var_scope_mode '$scoped_var_scope_mode' \
argument for the variable to $command_action passed to \
'termux_core__bash__termux_scoped_env_variable' is not valid. \
It must either be a supported component name starting with \`cn=\`, \
or an environment variable scope starting with \`s=\` or \`ss=\`." 1>&2
            return 64 # EX__USAGE
            ;;
    esac


    if [ -n "$scoped_var_scope_mode" ]; then
        if [ -n "$scoped_var_scope_name" ]; then
            # Generate the full name for the variable under the provided root and sub scope.
            scoped_var_name="${scoped_var_scope_name}${scoped_var_sub_name}"
        else
            # Generate the full name for the variable under the Termux root scope and provided sub scope.
            # If `TERMUX_ENV__S_ROOT` environment variable set.
            # shellcheck disable=SC2050
            if [ -n "${TERMUX_ENV__S_ROOT:-}" ]; then
                scoped_var_root_scope_name="$TERMUX_ENV__S_ROOT"
                if [[ ! "$scoped_var_root_scope_name" =~ $valid_bash_variable_name_regex ]]; then
                    echo "The TERMUX_ENV__S_ROOT environment variable value '$scoped_var_root_scope_name' \
while running 'termux_core__bash__termux_scoped_env_variable' is not a valid environment variable name." 1>&2
                    return 1
                fi
            # If `TERMUX_ENV__S_ROOT` placeholder got replaced during build time.
            elif [ "TERMUX_" != @"TERMUX_ENV__S_ROOT"@ ]; then
                scoped_var_root_scope_name="TERMUX_"
                if [[ ! "$scoped_var_root_scope_name" =~ $valid_bash_variable_name_regex ]]; then
                    echo "The TERMUX_ENV__S_ROOT build value '$scoped_var_root_scope_name' \
while running 'termux_core__bash__termux_scoped_env_variable' is not a valid environment variable name." 1>&2
                    return 1
                fi
            else
                scoped_var_root_scope_name="TERMUX_"
            fi

            scoped_var_name="${scoped_var_root_scope_name}${scoped_var_sub_scope_name}${scoped_var_sub_name}"
        fi

        if [[ ! "$scoped_var_name" =~ $valid_bash_variable_name_regex ]]; then
            echo "The name of the variable to $command_action '$scoped_var_name' generated in \
'termux_core__bash__termux_scoped_env_variable' is not a valid environment variable name." 1>&2
            return 64 # EX__USAGE
        fi


        # If command type equals `get-name`, then return the variable name and exit.
        if [ "$command_type" = "get-name" ]; then
            #echo "scoped_var_name=$scoped_var_name"
            if [ "$output_mode" = ">" ]; then
                printf "%s" "$scoped_var_name"
                return $?
            elif [ "$output_mode" != "-" ]; then
                printf -v "$output_mode" "%s" "$scoped_var_name"
                #eval "echo $output_mode=\"\${${output_mode}}\"" # Surround `${output_mode}` with `${}` in case its a base array variable name
                return $?
            else
                return 0
            fi
        elif [ "$command_type" = "set-value" ]; then
            printf -v "$scoped_var_name" "%s" "$value_to_set"
            return $?
        elif [ "$command_type" = "unset-value" ]; then
            unset "$scoped_var_name"
            return $?
        fi
    else
        if [ "$command_type" = "get-name" ] || \
            [ "$command_type" = "set-value" ] || [ "$command_type" = "unset-value" ]; then
            echo "The scoped_var_scope_mode argument for the variable \
to $command_action passed for the '$command_type' command to \
'termux_core__bash__termux_scoped_env_variable' is not set." 1>&2
            return 64 # EX__USAGE
        fi
    fi


    # If command type equals `get-value`, then find the first valid in variable name/values passed.
    if [ "$command_type" = "get-value" ]; then
        if [ "$validator_mode" = "c+=" ] || [ "$validator_mode" = "c-=" ]; then
            local command_arg_first_arg
            local -a validator_command_args=()

             # Convert command string to array.
            local -a validator_command_args=()
            termux_core__bash__set_shell_command_args_array validator_command_args \
                "extended_validator command" "$validator_arg" || return $?

            command_arg_first_arg="${validator_command_args[0]}"

            # Check if a command exists, like an executable in `$PATH`,
            # a shell function or a path to an executable.
            # - https://pubs.opengroup.org/onlinepubs/9699919799/utilities/command.html
            if ! command -v -- "$command_arg_first_arg" >/dev/null 2>&1; then
                # Check if absolute or relative path as `command -v` will only check executables under `$PATH`.
                if [[ "$command_arg_first_arg" == */* ]] && \
                        [ -f "$command_arg_first_arg" ] && [ -x "$command_arg_first_arg" ]; then
                    :
                else
                    echo "The validator command '$command_arg_first_arg' \
not found while running 'termux_core__bash__termux_scoped_env_variable' \
that is set in the extended_validator '$extended_validator' argument." 1>&2
                    return 64 # EX__USAGE
                fi
            fi
        fi

        # Loop on [`<expanded_scoped_var_name>` `<default_values>`] to
        # find the first valid value.
        i=0
        for var_value_cur in "$scoped_var_name" "$@"; do
            var_value_cur="${var_value_cur:-}"

            # If first loop, then expand the `scoped_var_name` to its value.
            if [ "$i" = 0 ] && [ -n "$scoped_var_name" ]; then
                # If mode is `*`, expand variable if it is set, or defined
                # but empty. Else if its not defined, then ignore it.
                if [ "$validator_mode" = "*" ]; then
                    eval '[ -n "${'"$scoped_var_name"'+x}" ] && scoped_var_set=1 || scoped_var_set=0'
                    if [ "$scoped_var_set" = "1" ]; then
                        var_value_cur="${!scoped_var_name:-}"
                    else
                        i=$((i + 1)); continue;
                    fi
                else
                    var_value_cur="${!scoped_var_name:-}"
                fi
            fi

            is_value_valid=0
            if [ "$validator_mode" = "r+=" ]; then
                if [[ "$var_value_cur" =~ $validator_arg ]]; then
                    is_value_valid=1
                fi
            elif [ "$validator_mode" = "r-=" ]; then
                if [[ ! "$var_value_cur" =~ $validator_arg ]]; then
                    is_value_valid=1
                fi
            elif [ "$validator_mode" = "c+=" ]; then
                # Do not use `if command; then` to preserve `set -e` failures in called function.
                return_value=0
                "${validator_command_args[@]}" "$var_value_cur" || return_value=$?
                if [ $return_value -eq 0 ]; then
                    is_value_valid=1
                else
                    is_value_valid=0 # Prevent using value overridden by called function.
                fi
            elif [ "$validator_mode" = "c-=" ]; then
                # Do not use `if ! command; then` to preserve `set -e` failures in called function.
                return_value=0
                "${validator_command_args[@]}" "$var_value_cur" || return_value=$?
                if [ $return_value -ne 0 ]; then
                    is_value_valid=1
                else
                    is_value_valid=0 # Prevent using value overridden by called function.
                fi
            else
                # If mode is `?` or `*`, and value is set,
                # or mode is `*` and value is not set.
                if [ -n "$var_value_cur" ] || [ "$validator_mode" = "*" ]; then
                    is_value_valid=1
                # Else if mode is `?`, and value is not set.
                else
                    is_value_valid=0
                fi
            fi

            if [ "$is_value_valid" = "1" ]; then
                #echo "var_value_cur=$var_value_cur"
                if [ "$output_mode" = ">" ]; then
                    printf "%s" "$var_value_cur"
                    return $?
                elif [ "$output_mode" != "-" ]; then
                    printf -v "$output_mode" "%s" "$var_value_cur"
                    #eval "echo $output_mode=\"\${${output_mode}}\"" # Surround `${output_mode}` with `${}` in case its a base array variable name
                    return $?
                else
                    return 0
                fi
            fi

            i=$((i + 1))
        done


        # If a valid value not found.

        if [ -n "$scoped_var_name" ]; then
            scoped_var_value_invalid_error_suffix=" that is read from the '\$$scoped_var_name' variable"
        fi
        if [ "$output_mode" != ">" ] && [ "$output_mode" != "-" ]; then
            # Set output variable in `output_mode` to an empty string
            # since it may already be set, as callers may try to use that
            # wrong value without checking the exit code.
            # We unset after reading the values, otherwise if
            # `scoped_var_name` is equal to output variable in
            # `output_mode`, then `scoped_var_name` would get unset before
            # its read.
            printf -v "$output_mode" "%s" "" || return $?

            echo "Failed to find a valid value to set to the '\$$output_mode' \
variable${scoped_var_value_invalid_error_suffix}." 1>&2
        else
            echo "Failed to find a valid value${scoped_var_value_invalid_error_suffix}." 1>&2
        fi
        return 81 # C_EX__NOT_FOUND
    fi

}

##
# Set a bash indexed array (`declared -a`) to shell command arguments
# defined as a string by splitting the string as normally done by the
# shell.
#
# This function is based on `libalteran-sh`
# `bash___shell__set_shell_command_args_array()`
# function, check it for more info and comments.
#
#
# `termux_core__bash__set_shell_command_args_array` \
#     `<command_args_array_variable_name>` \
#     `<command_args_label>` `<command_args_string>`
##
termux_core__bash__set_shell_command_args_array() {

    local return_value

    if [ $# -ne 3 ]; then
        echo "Invalid argument count to 'termux_core__bash__set_shell_command_args_array'"
        return 1
    fi

    local command_args_array_variable_name="$1"
    local command_args_label="$2"
    local command_args_string="$3"

    local command_arg
    local command_args_string_contains_shell_special_chars="false"
    local command_args_string_contains_space="false"
    local newline=$'\n'
    local space_containing_string_regex='[[:space:]]+'
    local shell_special_chars_containing_string_regex='[]["'\''*?!\]+'
    local xargs_command_output
    local xargs_path

    local -n  command_args_array="$command_args_array_variable_name" || return $?
    command_args_array=()


    if [[ -z "$command_args_string" ]]; then
        # Unset `nameref` to `command_args_array_variable_name`.
        unset -n  command_args_array || return $?
        return 0
    fi

    if [[ "$command_args_string" == *$'\n'* ]]; then
        # shellcheck disable=SC2028
        echo "The $command_args_label value to be \
converted to a command array cannot contain a newline '\n' character:" 1>&2
        echo "\`\`\`" 1>&2
        echo "$command_args_string" 1>&2
        echo "\`\`\`" 1>&2
        return 64 # EX__USAGE
    fi


    if [[ "$command_args_string" =~ $shell_special_chars_containing_string_regex ]]; then
        command_args_string_contains_shell_special_chars="true"
    fi
    if [[ "$command_args_string" =~ $space_containing_string_regex ]]; then
        command_args_string_contains_space="true"
    fi

    if [[ "$command_args_string_contains_shell_special_chars" == "true" ]] || \
            [[ "$command_args_string_contains_space" == "true" ]]; then

        # Use `xargs` if command args string contains whitespaces or
        # shell special characters.
        if [[ "$command_args_string_contains_shell_special_chars" == "true" ]]; then
            return_value=0
            xargs_path="$(command -v "xargs")" || return_value=$?
            if [ $return_value -ne 0 ]; then
                echo "Failed to find 'xargs' for converting $command_args_label value to a command array." 1>&2
                return $return_value
            fi

            # Android `toybox` provided `xargs` does not parse arguments
            # properly and single and double quotes around arguments
            # remain, nor do backslash escapes work.
            # Termux `findutils` package supplied `xargs` does not
            # have such issues, so we ignore the check for it only if
            # `TERMUX__PREFIX` placeholder got replaced during build time.
            # `/system/bin/xargs` may get called if current shell has
            # `/system/bin` in `$PATH` instead of or before Termux bin path.
            # shellcheck disable=SC2050
            if [[ "$xargs_path" != "/data/data/com.qflistudio.azure/files/usr/xargs" ]] || [[ "/data/data/com.qflistudio.azure/files/usr" == @"TERMUX__PREFIX"@ ]]; then
                # The logic to check if `xargs` parsing is valid is based
                # on `libalteran-sh` `bash___shell__set_is_xargs_command_args_parsing_valid()`
                # function, check it for explanation.
                return_value=0
                xargs_command_output="$(printf "%s" "'' 'arg' '' 'arg with space' 'arg surround by single quote' \"arg surround by double quote\" 'arg with '\'' single quote' 'arg with \" double quote' 'arg with \" double quote surround by single quote' \"arg with ' single quote surround by double quote\" arg\ with\ escaped\ space 'arg with backslash \\ and forward slash / surround by single quote' \"arg with backslash \\ and forward slash / surround by double quote\" \\/ \\\\ ''" | \
                    xargs -r -n1 -- printf "%s\n" && echo -n x)" || return_value=$?
                if [ $return_value -ne 0 ]; then
                    echo "Failed to check if xargs command args parsing is valid." 1>&2
                    echo "xargs_command_output=\`$xargs_command_output\`" 1>&2
                    return $return_value
                fi

                if [[ "${xargs_command_output%x}" != "${newline}arg${newline}${newline}arg with space${newline}arg surround by single quote${newline}arg surround by double quote${newline}arg with ' single quote${newline}arg with \" double quote${newline}arg with \" double quote surround by single quote${newline}arg with ' single quote surround by double quote${newline}arg with escaped space${newline}arg with backslash \ and forward slash / surround by single quote${newline}arg with backslash \\ and forward slash / surround by double quote${newline}/${newline}\\${newline}" ]]; then
                    echo "The $command_args_label value cannot be \
converted to a command array in current execution environment as it contains \
shell special characters and 'xargs' command args parsing is not valid:" 1>&2
                    echo "\`\`\`" 1>&2
                    echo "$command_args_string" 1>&2
                    echo "\`\`\`" 1>&2
                    echo "xargs path: \`$(command -v "xargs" || true)\`" 1>&2
                    echo "xargs version: \`$({ xargs --version 2>/dev/null || true; } | head -n 1)\`" 1>&2
                    return 1
                fi
            fi

            command_arg="READ_ERROR"
            return_value=0
            while IFS= read -r command_arg; return_value=$?; [[ $return_value -eq 0 ]]; do
                command_args_array+=("$command_arg")
            done < <(printf "%s\n" "$command_args_string" | \
                xargs -r -n1 -- printf "%s\n" || echo -n "CMD_ERROR")
            if [[ -n "${command_arg:-}" ]] || [ $return_value -ne 1 ]; then
                echo "Failed to create command array for \
command arguments string \`$command_args_string\`." 1>&2
                [[ -n "${command_arg:-}" ]] && echo "Error type: '$command_arg'" 1>&2
                if [[ -n ${!:-} ]]; then
                    wait "$!" || true
                fi
                return 1
            fi
        else
            # Avoid creating subshell and external call to xargs if
            # command args string contains whitespaces but does not
            # contain shell special characters and rely on whitespace
            # splitting of arguments.
            local old_ifs="$IFS"
            IFS=$' \t\n'
            # shellcheck disable=SC2206
            command_args_array=( $command_args_string )
            IFS="$old_ifs"
        fi
    else
        # Avoid creating subshell and external call to xargs if
        # command args string does not contain whitespaces or shell
        # special characters.
        command_args_array=( "$command_args_string" )
    fi

    # Unset `nameref` to `command_args_array_variable_name`.
    unset -n  command_args_array || return $?

    return 0

}

##### TERMUX_CORE__BASH__TERMUX_SCOPED_ENV_VARIABLE replaced at build time. (END) #####



##
# Check if script is sourced.
# - https://stackoverflow.com/a/28776166/14686958
# - https://stackoverflow.com/a/29835459/14686958
#
# To source the `termux-scoped-env-variable.bash` file in `$PATH`
# (with `.` or `source` command), run the following commands.
# The `command -v` command is used to find the location of the script
# file instead of directly using the `.`/`source` command to prevent
# sourcing of a (malicious) file in the current working directory with
# the same name instead of the one in `$PATH`.
# A separate function is used to source so that arguments passed to
# calling script/function are not passed to the sourced script.
# Replace `exit` with `return` if running inside a function.
# ```shell
# source_file_from_path() { local source_file="${1:-}"; [ $# -gt 0 ] && shift 1; local source_path; if source_path="$(command -v "$source_file")" && [ -n "$source_path" ]; then source "$source_path" || return $?; else echo "Failed to find the '$source_file' file to source." 1>&2; return 1; fi; }
# source_file_from_path "termux-scoped-env-variable.bash" || exit $?
# ```
##

# If script is sourced, return with success, otherwise call main function.
if (return 0 2>/dev/null); then
    return 0 # EX__SUCCESS
else
    termux_core__bash__termux_scoped_env_variable__main "$@"
    exit $?
fi
