#!/usr/bin/env bash
#
#   Script name: upac
#   Description: Package manager UBLinux
#   GitLab: https://gitlab.ublinux.ru/
#   Author: Dmitry Razumov asmeron@ublinux.ru
#   Contributors: asmeron@ublinux.ru
#
#   Copyright (c) 2019-2025 UBLinux Development Team <support@ublinux.ru>
#
#   This program is free software; you can redistribute it and/or modify
#   it under the terms of the GNU General Public License as published by
#   the Free Software Foundation; either version 2 of the License, or
#   (at your option) any later version.
#
#   This program is distributed in the hope that it will be useful,
#   but WITHOUT ANY WARRANTY; without even the implied warranty of
#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#   GNU General Public License for more details.
#
#   You should have received a copy of the GNU General Public License
#   along with this program.  If not, see <http://www.gnu.org/licenses/>.

VERSION_SCRIPT=2.3

# Exit Immediately if a command fails
#set -o errexit

# Extended pattern matching: https://www.gnu.org/software/bash/manual/html_node/Pattern-Matching.html#Pattern-Matching
shopt -s extglob

#################################
###   :::   C O L O R S   :::   #
#################################
set_color(){
#http://abload.de/img/bash-color-chartmxjbp.png
    export BBC=$'\e[1;34m'
    export RBC=$'\e[1;31m'
    export WBC=$'\e[1m'
    export EC=$'\e[0m'

    export txtblk='\033[0;30m' # Black - Regular
    export txtred='\033[0;31m' # Red			# prompt: error color
    export txtgrn='\033[0;32m' # Green			# prompt: success color
    export txtylw='\033[0;33m' # Yellow			# prompt: waring color
    export txtblu='\033[0;34m' # Blue			
    export txtpur='\033[0;35m' # Purple
    export txtcyn='\033[0;36m' # Cyan			# prompt: info color
    export txtwht='\033[0;37m' # White
    export bldblk='\033[1;30m' # Black - Bold
    export bldred='\033[1;31m' # Red			# prompt: bold error color
    export bldgrn='\033[1;32m' # Green			# prompt: bold success color
    export bldylw="\033[1;33m" # Yellow                 # prompt: bold warning color
    export bldblu='\033[1;34m' # Blue				
    export bldpur='\033[1;35m' # Purple
    export bldcyn="\033[1;36m" # Cyan                   # prompt: bold info color
    export bldwht="\033[1;37m" # White			# prompt: bold default color

    export undblk='\033[4;30m' # Black - Underline
    export undred='\033[4;31m' # Red

    export bakblk='\033[40m'   # Black - Background
    export bakred='\033[41m'   # Red
    export badgrn='\033[42m'   # Green

    export txtrst='\033[0m'    # Text Reset		# prompt: default color
}


#######################################
###   :::   F U N C T I O N S   :::   #
#######################################

check_root(){
    [[ ${DEBUG} == @(yes|y|1) ]] && return 0
    if [[ ${EUID:-$(id -u)} > 0 ]]; then
	case ${1} in
	    -w  | --warning)	  shift; [[ -n ${@} ]] && prompt -w "${@}"; prompt -w "Please run as root!"; return 1 ;;
	    -wq | --warning-quit) shift; [[ -n ${@} ]] && prompt -w "${@}"; prompt -wq "Please run as root!" ;;
    	    *) 			  [[ -n ${@} ]] && prompt -w "${@}"; prompt -wq "Please run as root!" ;;
        esac
    fi
}

# Check command availability
has_command(){ command -v $1 &> /dev/null; }

i18n() {
    local key="$1"; shift
    printf "$(gettext -s "$key")" "$@"
}

# echo like ... with flag type and display message colors
prompt(){
    if [[ -z ${QUIET} ]]; then
	case ${1} in
	    -s  | --success)	  shift; echo -e "${txtgrn}$(i18n "${@}")${txtrst}" ;;						# print success message
	    -sq | --success-quit) shift; echo -e "${txtgrn}$(i18n "${@}")${txtrst}"; exit 0 ;;					# print success message
	    -e  | --error)   	  shift; echo -e "${txtred}$(i18n "ERROR:") $(i18n "${@}")${txtrst}" ;;				# print error message
	    -eq | --error-quit)   shift; echo -e "${txtred}$(i18n "ERROR:") $(i18n "${@}")${txtrst}"; exit 1 ;;			# print error message
	    -w  | --warning) 	  shift; echo -e "${txtylw}$(i18n "WARNING:") ${bldwht}$(i18n "${@}")${txtrst}" ;;		# print warning message
	    -wq | --warning-quit) shift; echo -e "${txtylw}$(i18n "WARNING:") ${bldwht}$(i18n "${@}")${txtrst}"; exit 0 ;;	# print warning message
	    -i  | --info)    	  shift; echo -e "${txtcyn}$(i18n "INFO:") ${txtcyn}$(i18n "${@}")${txtrst}" ;;			# print info message
	    -iq | --info-quit)    shift; echo -e "${txtcyn}$(i18n "INFO:") ${txtcyn}$(i18n "${@}")${txtrst}"; exit 0 ;;		# print info message
	    *)    		  echo -e "$(i18n "${@}")" ;;									# print all message
	esac
    else
	case ${1} in
	    -s  | --success)	  true ;;	# print success message
	    -sq | --success-quit) exit 0 ;;	# print success message
	    -e  | --error)   	  true ;;	# print error message
	    -eq | --error-quit)   exit 1 ;;	# print error message
	    -w  | --warning) 	  true ;;	# print warning message
	    -wq | --warning-quit) exit 0 ;;	# print warning message
	    -i  | --info)    	  true ;;	# print info message
	    -iq | --info-quit)    exit 0 ;;	# print info message
	    *)    		  true ;;	# print all message
	esac
    fi
}

usage_version(){
    #printf "%s  %s\n" "${0##*/}" "version: ${VERSION_SCRIPT}"
    cat <<EOF
${0##*/} version: ${VERSION_SCRIPT}
Copyright © 2019-2025 Dmitry Razumov
This program is free software, you can redistribute it under the terms of the GNU GPL.
EOF
}

usage(){
    cat <<EOF
Usage:  ${0##*/} [<backend>] <action> [options] <package(s)>

Backends:
 *yay		Select backend package manager yay (Default)
  pacman	Select backend package manager pacman
  pamac		Select backend package manager pamac
  ubur		Select build package from UBUR repository
  
Meta:
  help          Show this help

Options:
  -h, --help	   Show this help
      --nocolor    Show without color message
  -q, --quiet	   Quiet mode
  -V, --version	   Show package version

Use 'upac [-h --help]' with backend and action for available options
Use 'upac ubur [-h --help]' with backend and action for available options

Examples:
${0##*/} ubur --help
EOF
}

usage_ubur(){
    cat <<EOF
Usage:
  upac ubur --version
  upac ubur 		   [action] --help,-h
  upac ubur list           [options]
  upac ubur search         [options] <package(s)>
  upac ubur info           [options] <package(s)>
  upac ubur install        [options] <package(s)>
  upac ubur reinstall      [options] <package(s)>
  upac ubur remove         [options] [<package(s)>]
T:upac ubur checkupdates   [options]
T:upac ubur update,upgrade [options]
T:upac ubur clone          [options] <package(s)>
  upac ubur build          [options] [<package(s)>]
  upac ubur clean          [options] [<package(s)>]

Available actions for ubur:
  list		 Search for packages or files, multiple search terms can be specified
  search         List of all packages
  info           Display package details, multiple packages can be specified
  install        Install packages from global repositories, path or url
  reinstall      Reinstall packages from local repositories, path or url
  remove         Remove  package
T:checkupdates   Check update package
T:update,upgrade Update all packages
T:clone          Clone repository package
  build          Only build packages
  clean          Clean all sync and source packages

Examples:
${0##*/} ubur list
${0##*/} ubur install --help
EOF
}

usage_ubur_list(){
    cat <<EOF
Search for packages or files, multiple search terms can be specified

Usage:
  upac ubur list [options]

Options:
  --nosync		No synchronize packages
  --quiet, -q		Only print names
EOF
}

usage_ubur_search(){
    cat <<EOF
List of all packages

Usage:
  upac ubur list [options] <package(s)/file(s)>

Options:
  --nosync		No synchronize packages
  --quiet, -q		Only print names
EOF
}

usage_ubur_info(){
    cat <<EOF
Display package details, multiple packages can be specified

Usage:
  upac ubur info [options] <package(s)>

options:
  --nosync		No synchronize packages
EOF
}

usage_ubur_install(){
    cat <<EOF
Install packages from global repositories, path or url

Usage:
  upac ubur install [options] <package(s),group(s)>

options:
  --nosync		No synchronize packages
  --download-only	Download all packages but do not install/upgrade anything
  --no-confirm		Bypass any and all confirmation messages
EOF
}

usage_ubur_reinstall(){
    cat <<EOF
Reinstall packages from local repositories, path or url

Usage:
  upac ubur reinstall [options] <package(s),group(s)>

options:
  --nosync		No synchronize packages
  --download-only	Download all packages but do not install/upgrade anything
  --no-confirm		Bypass any and all confirmation messages
EOF
}

usage_ubur_remove(){
    cat <<EOF
Remove packages

Usage:
  upac ubur remove [options] [package(s),group(s)]

options:
  --nodeps	Remove a package without dependencies
  --no-confirm	Bypass any and all confirmation messages
EOF
}

usage_ubur_build(){
    cat <<EOF
Only build packages

Usage:
  upac ubur build [options] [package(s),group(s)]

options:
  --nosync		No synchronize packages
  --no-confirm		Bypass any and all confirmation messages
EOF
}

usage_ubur_clean(){
    cat <<EOF
Clean all or select package repository

Usage:
  upac ubur clean [package(s)]
EOF
}

help(){
    #usage_version
    if [[ ${BACKEND} == 'ubur' ]]; then
        if [[ -n ${UBUR_SEARCH} ]]; then
            usage_ubur_search
        elif [[ -n ${UBUR_LIST} ]]; then
            usage_ubur_list
        elif [[ -n ${UBUR_INFO} ]]; then
            usage_ubur_info
        elif [[ -n ${UBUR_INSTALL} ]]; then
            usage_ubur_install
        elif [[ -n ${UBUR_REINSTALL} ]]; then
            usage_ubur_reinstall
        elif [[ -n ${UBUR_REMOVE} ]]; then
            usage_ubur_remove
        elif [[ -n ${UBUR_BUILD} ]]; then
            usage_ubur_build
        elif [[ -n ${UBUR_CLEAN} ]]; then
            usage_ubur_clean
        else
            usage_ubur
        fi
    elif [[ ${BACKEND} == 'pacman' ]]; then
        usage_pacman
    elif [[ ${BACKEND} == 'yay' ]]; then
        usage_yay
    elif [[ ${BACKEND} == 'pamac' ]]; then
        usage_pamac
    else
        usage
    fi

#    [[ -n $1 ]] || usage
#    [[ $1 == "yay" ]] && usage_yay
#    [[ $1 == "pacman" ]] && usage_pacman
#    [[ $1 == "pamac" ]] && usage_pamac
    exit 0
}
usage_pacman(){
    /usr/bin/pacman --help | sed "s/pacman/upac/g"
}
usage_yay(){
    /usr/bin/yay --help | sed "s/yay/upac/g"
}
usage_pamac(){
    /usr/bin/pacman --help | sed "s/pamac/upac/g"
}

arguments(){
# Pre-process options to:
# - expand -xyz into -x -y -z
# - expand --longopt=arg into --longopt arg
    local ARGV=()
    local END_OF_OPT=
    while [[ $# -gt 0 ]]; do
	arg="$1"; shift
	case "${END_OF_OPT}${arg}" in
	    --) ARGV+=("$arg"); END_OF_OPT=1 ;;
	    --*=*)ARGV+=("${arg%%=*}" "${arg#*=}") ;;
	    --*) ARGV+=("$arg") ;;
	    -*) for i in $(seq 2 ${#arg}); do ARGV+=("-${arg:i-1:1}"); done ;;
	    *) ARGV+=("$arg") ;;
	esac
    done
    # Apply pre-processed options
    set -- "${ARGV[@]}"
    # Parse options
    local END_OF_OPT=
    local POSITIONAL_ARGS=()
    [[ -z $@ ]] && usage && exit 0
    while [[ $# -gt 0 ]]; do
	case "${END_OF_OPT}${1}" in
	    pacman | PACMAN)	BACKEND="${1,,}"; END_OF_OPT=1 ;;
	    yay | YAY)		BACKEND="${1,,}"; END_OF_OPT=1 ;;
	    pamac | PAMAC)	BACKEND="${1,,}"; END_OF_OPT=1 ;;
	    ubur | UBUR)	BACKEND="${1,,}" ;;

	    search)		[[ ${BACKEND} == 'ubur' ]] && UBUR_SEARCH=yes ;;
	    list)		[[ ${BACKEND} == 'ubur' ]] && UBUR_LIST=yes ;;
	    info)		[[ ${BACKEND} == 'ubur' ]] && UBUR_INFO=yes ;;
	    install)		[[ ${BACKEND} == 'ubur' ]] && UBUR_INSTALL=yes ;;
	    reinstall)		[[ ${BACKEND} == 'ubur' ]] && UBUR_REINSTALL=yes ;;
	    remove)		[[ ${BACKEND} == 'ubur' ]] && UBUR_REMOVE=yes ;;
	    checkupdates)	[[ ${BACKEND} == 'ubur' ]] && UBUR_CHECKUPDATES=yes ;;
	    update|upgrade)	[[ ${BACKEND} == 'ubur' ]] && UBUR_UPDATE=yes ;;
	    clone)		[[ ${BACKEND} == 'ubur' ]] && UBUR_CLONE=yes ;;
	    build)		[[ ${BACKEND} == 'ubur' ]] && UBUR_BUILD=yes ;;
	    clean)		[[ ${BACKEND} == 'ubur' ]] && UBUR_CLEAN=yes ;;
	    --nodeps)		[[ ${BACKEND} == 'ubur' ]] && UBUR_NODEPS=yes ;;
	    --nosync)		[[ ${BACKEND} == 'ubur' ]] && UBUR_NOSYNC=yes ;;
	    --download-only)	[[ ${BACKEND} == 'ubur' ]] && UBUR_INSTALL_DOWNLOAD_ONLY=yes ;;
	    --noconfirm)	[[ ${BACKEND} == 'ubur' ]] && UBUR_INSTALL_NOCONFIRM="--noconfirm" ;;
	    
	    --nocolor)          NOCOLOR=yes;;
	    -h | --help | help) help ;;
	    -q | --quiet)       QUIET=1; QUIET_SYSTEMCTL="--quiet"; QUIET_ARG="-q" ;;
	    -V | --V | --version) usage_version; exit 0 ;;
	    --stdin)            READ_STDIN=1 ;;
	    --)                 END_OF_OPT=1 ;;
	    -*|--*)             [[ -n ${BACKEND} ]] && prompt -w "Unrecognized argument, skiped: $1" >&2 || { POSITIONAL_ARGS+=("$1"); END_OF_OPT=1; } ;;
	    *)                  POSITIONAL_ARGS+=("$1") ;;
	esac
	shift
    done
    # Restore positional parameters
    set -- "${POSITIONAL_ARGS[@]}"
    REQUEST_ARGS=("${POSITIONAL_ARGS[@]}")
    [[ -n ${BACKEND} ]] || BACKEND="yay"
    [[ ${BACKEND} == 'ubur' && -n ${UBUR_REMOVE} ]] && UBUR_NOSYNC=yes
    [[ -n $@ || -n ${UBUR_LIST} || -n ${UBUR_CLEAN} || -n ${UBUR_CHECKUPDATES} || -n ${UBUR_UPDATE} ]] && PACKAGES="$@" || help
}

_init_(){
    # Define exit codes
    ERR_C=-1	# Error code
    OK_C=0 	# OK button is pressed
    CANCEL_C=1 	# Cancel button is pressed
    HELP_C=2	# Help code
    EXTRA_C=3 	# Extra button is pressed
    ESC_C=255 	# ESC button is pressed

    path_root=""
#    ROOT_DIR="/tmp/upac"

    export TEXTDOMAIN=$(basename "$0")
    export TEXTDOMAINDIR="${path_root}/usr/share/locale"

#    log_file="${path_root}/var/log/ubpac.log"
#    touch ${log_file} && chmod 666 ${log_file} >/dev/null
    
    BIN_PACMAN="/usr/bin/pacman"
    BIN_YAY="/usr/bin/yay"
    BIN_PAMAC="/usr/bin/pamac"
    CACHE_UPAC="${HOME}/.cache/${BINNAME}"
    install -dm755 ${CACHE_UPAC}
    GIT_UBUR_REPO="https://gitea.ublinux.ru/ubur"
    GIT_UBUR_REPO_SRCINFO="${GIT_UBUR_REPO}/srcinfo"
    PATH_UBUR_REPO_SRCINFO_LOCAL="${CACHE_UPAC}/srcinfo"
    EXT_MASK="pkg.tar"
}

check_access_ubur(){
    ping -c 1 -W 1 77.88.8.8 >/dev/null 2>&1 || errorexit "Not connected to internet"
}
ubur_repos_update(){
    if [[ -d ${PATH_UBUR_REPO_SRCINFO_LOCAL} ]]; then
	cd "${PATH_UBUR_REPO_SRCINFO_LOCAL}"
	git pull &>/dev/null
    else
	cd "${CACHE_UPAC}"
	git clone "${GIT_UBUR_REPO_SRCINFO}" &>/dev/null
    fi
    [[ -d ${PATH_UBUR_REPO_SRCINFO_LOCAL} ]] || return 1
    cd "${PATH_WORK}"
}
ubur_package_list(){
    #local TEXT_LIST=()
    local TEXT_LIST=
    while IFS= read -u4 PACKAGE_PKGBASE; do
	local CAT_PACKAGE=$(cat "${PACKAGE_PKGBASE}")
	while IFS= read -u5 PACKAGE_PKGNAME; do
	    if [[ -n ${QUIET} ]]; then
		TEXT_LIST+="${PACKAGE_PKGNAME}"$'\n'
	    else
		local PACKAGE_PKGVER=$(grep -E "pkgver =" <<< ${CAT_PACKAGE} | sed "s/.*pkgver = //g")
   		local PACKAGE_PKGDESC=$(sed -En "/pkgname = ${PACKAGE_PKGNAME}/,/pkgname = .*/{s/[[:blank:]]*pkgdesc = (.*)/\1/p}" <<< ${CAT_PACKAGE}) #"
		[[ -n ${PACKAGE_PKGDESC} ]] || PACKAGE_PKGDESC=$(sed -En "/pkgbase = .*/,/pkgname = .*/{s/[[:blank:]]*pkgdesc = (.*)/\1/p}" <<< ${CAT_PACKAGE}) #"
		PACKAGE_PKGDESC=${PACKAGE_PKGDESC//$'\n'/. }
		TEXT_LIST+="${PACKAGE_PKGNAME}|${PACKAGE_PKGVER}|${PACKAGE_PKGDESC}"$'\n'
	    fi
	done 5< <(grep -E "pkgname =" <<< ${CAT_PACKAGE} | sed "s/.*pkgname = //g")
    done 4< <(ls "${PATH_UBUR_REPO_SRCINFO_LOCAL}"/* 2>/dev/null)
    if [[ -n ${QUIET} ]]; then
	column  --separator '|' --table  <<< "${TEXT_LIST}"
    else
	column  --separator '|' --table-noheadings --table --table-columns PACKAGE,VERSION,DESCRIPTION --table-order PACKAGE --table-wrap DESCRIPTION <<< "${TEXT_LIST}"
	#pr -l 1 -t -3 -w 120 <<< "${TEXT_LIST}"
    fi
}
ubur_package_search(){
    local PACKAGE_PKGBASE=$1
    [[ -f ${PATH_UBUR_REPO_SRCINFO_LOCAL}/${PACKAGE_PKGBASE} ]] || return 1
}
ubur_package_search_infocompact(){
    local PACKAGE_PKGNAME=$1
    local PACKAGE_PKGBASE=$2
    local TEXT_LIST=
    if [[ -f "${PATH_UBUR_REPO_SRCINFO_LOCAL}/${PACKAGE_PKGBASE}" ]]; then
	local CAT_PACKAGE=$(cat "${PATH_UBUR_REPO_SRCINFO_LOCAL}/${PACKAGE_PKGBASE}")
	if [[ -n ${QUIET} ]]; then
	    TEXT_LIST+="${PACKAGE_PKGNAME}"$'\n'
	else
	    local PACKAGE_PKGVER=$(grep -E "pkgver =" <<< ${CAT_PACKAGE} | sed "s/.*pkgver = //g")
   	    local PACKAGE_PKGDESC=$(sed -En "/pkgname = ${PACKAGE_PKGNAME}/,/pkgname = .*/{s/[[:blank:]]*pkgdesc = (.*)/\1/p}" <<< ${CAT_PACKAGE}) #"
	    [[ -n ${PACKAGE_PKGDESC} ]] || PACKAGE_PKGDESC=$(sed -En "/pkgbase = .*/,/pkgname = .*/{s/[[:blank:]]*pkgdesc = (.*)/\1/p}" <<< ${CAT_PACKAGE}) #"
	    PACKAGE_PKGDESC=${PACKAGE_PKGDESC//$'\n'/. }
	    TEXT_LIST+="${PACKAGE_PKGNAME}|${PACKAGE_PKGVER}|${PACKAGE_PKGDESC}"$'\n'
	fi
    fi
    if [[ -n ${QUIET} ]]; then
	column  --separator '|' --table  <<< "${TEXT_LIST}"
    else
	column  --separator '|' --table-noheadings --table --table-columns PACKAGE,VERSION,DESCRIPTION --table-order PACKAGE --table-wrap DESCRIPTION <<< "${TEXT_LIST}"
    fi
}
ubur_package_info(){
    local PACKAGE_PKGNAME=$1
    local PACKAGE_PKGBASE=$2
    if [[ -f "${PATH_UBUR_REPO_SRCINFO_LOCAL}/${PACKAGE_PKGBASE}" ]]; then
	sed -En "/pkgbase = ${PACKAGE_PKGBASE}/,/pkgname = .*/{/pkgname = .*/d; p;}" "${PATH_UBUR_REPO_SRCINFO_LOCAL}/${PACKAGE_PKGBASE}"
	sed -En "/pkgname = ${PACKAGE_PKGNAME}/,/pkgname = .*/p" "${PATH_UBUR_REPO_SRCINFO_LOCAL}/${PACKAGE_PKGBASE}" | sed "\$s/pkgname = .*//"
    fi
}
ubur_package_download(){
    local PACKAGE_PKGBASE=$1
    if [[ -d ${CACHE_UPAC}/${PACKAGE_PKGBASE} ]]; then
	cd "${CACHE_UPAC}/${PACKAGE_PKGBASE}"
	git pull &>/dev/null
    else
	cd "${CACHE_UPAC}"
	git clone "${GIT_UBUR_REPO}/${PACKAGE_PKGBASE}" &>/dev/null
    fi
    cd "${PATH_WORK}"
}
ubur_package_prebuild(){
    local PACKAGE_PKGBASE=$1
    # Если в текущем каталоге откуда вызывается ubur находятся исходные файлы для сборки, то они копируются с заменой в каталог сборки ~/.cache/ubur/<package>/
    while IFS=" = " read -u4 NULL SOURCE; do
	ls "${SOURCE##*/}" &>/dev/null && cp -af "${SOURCE##*/}" "${CACHE_UPAC}/${PACKAGE_PKGBASE}/" || { prompt -w "The file '${SOURCE##*/}' was not found in the current folder."; }
    done 4< <(grep "source.* = " "${PATH_UBUR_REPO_SRCINFO_LOCAL}/${PACKAGE_PKGBASE}")
    cd "${PATH_WORK}"
}
ubur_package_build(){
    local PACKAGE_PKGBASE=$1
    if [[ -d ${CACHE_UPAC}/${PACKAGE_PKGBASE} ]]; then
	cd "${CACHE_UPAC}/${PACKAGE_PKGBASE}"
	makepkg ${UBUR_INSTALL_NOCONFIRM} -cCfrd || return 1
	cd "${PATH_WORK}"
    else
	prompt -w "Package source '${PACKAGE_PKGBASE}' not found for build."
    fi
}
ubur_package_install(){
    local PACKAGE_PKGNAME=$1
    local PACKAGE_PKGBASE=$2
    #ls -lv "${CACHE_UPAC}/${PACKAGE_PKGNAME}"/*.pkg.* 2>/dev/null || prompt -w "Package ${PACKAGE_PKGNAME} not installed."
    # Все собранные пакеты представить в виде строки, пример: vipnetclient4-gui|/home/superadmin/.cache/upac/vipnetclient4-gui/vipnetclient4-gui-4.15.0.26717-1-x86_64.pkg.tar.zst
    #INSTALL_PKGS=$(ls -1vr ${CACHE_UPAC}/${PACKAGE_PKGNAME}/*.${EXT_MASK}.*[!sig] 2>/dev/null | sed -En "s/.*\/((.*)-([^-]+)-([^-]+)-[^-]+\.${EXT_MASK}\.[[:alnum:]]+)/\2|\0/p" | awk -F '|' '!prefixes[$1]++ {print $2}') #"

    cd "${CACHE_UPAC}/${PACKAGE_PKGBASE}"
    makepkg --printsrcinfo > .SRCINFO
    local CAT_PACKAGE=$(cat "${CACHE_UPAC}/${PACKAGE_PKGBASE}/.SRCINFO")
    local PACKAGE_PKGVER=$(grep -E "pkgver =" <<< ${CAT_PACKAGE} | sed "s/.*pkgver = //g")
    local PACKAGE_PKGREL=$(grep -E "pkgrel =" <<< ${CAT_PACKAGE} | sed "s/.*pkgrel = //g")

    local INSTALL_PKGS=
    # Выбираем все зависимости блока pkgbase
    #local DEPENDS_PKGBASE=$(sed -En "/pkgbase = ${PACKAGE_PKGBASE}/,/pkgname = .*/{s/[[:blank:]]*depends = ([0-9A-Za-z@%&+?{|}:_-]+).*/\1/p}" <<< ${CAT_PACKAGE}) #"
    while IFS= read -u4 SELECT_DEPEND; do
	INSTALL_PKGS+="$(find ${CACHE_UPAC}/${PACKAGE_PKGBASE} -type f -name "${SELECT_DEPEND}-${PACKAGE_PKGVER}-${PACKAGE_PKGREL}-*.${EXT_MASK}.*" -not -regex ".*\.sig$" 2>/dev/null) "
    done 4< <(sed -En "/pkgbase = ${PACKAGE_PKGBASE}/,/pkgname = .*/{s/[[:blank:]]*depends = ([0-9A-Za-z@%&+?{|}:_-]+).*/\1/p}" <<< ${CAT_PACKAGE})
    # Выбираем все зависимости блока pkgname
    #local DEPENDS_PKGNAME=$(sed -En "/pkgname = ${PACKAGE_PKGNAME}/,/pkgname = .*/{s/[[:blank:]]*depends = ([0-9A-Za-z@%&+?{|}:_-]+).*/\1/p}" <<< ${CAT_PACKAGE}) #"
    while IFS= read -u4 SELECT_DEPEND; do
	INSTALL_PKGS+="$(find ${CACHE_UPAC}/${PACKAGE_PKGBASE} -type f -name "${SELECT_DEPEND}-${PACKAGE_PKGVER}-${PACKAGE_PKGREL}-*.${EXT_MASK}.*" -not -regex ".*\.sig$" 2>/dev/null) "
    done 4< <(sed -En "/pkgname = ${PACKAGE_PKGNAME}/,/pkgname = .*/{s/[[:blank:]]*depends = ([0-9A-Za-z@%&+?{|}:_-]+).*/\1/p}" <<< ${CAT_PACKAGE})
    # Выбираем непосредственно сам пакет устанавливаемый
    INSTALL_PKGS+="$(find ${CACHE_UPAC}/${PACKAGE_PKGBASE} -type f -name "${PACKAGE_PKGNAME}-${PACKAGE_PKGVER}-${PACKAGE_PKGREL}-*.${EXT_MASK}.*" -not -regex ".*\.sig$" 2>/dev/null) "
    if [[ -n ${INSTALL_PKGS} ]]; then
        sudo -E ${BIN_PACMAN} -Sy
	sudo -E ${BIN_PACMAN} -U ${UBUR_INSTALL_NOCONFIRM} ${INSTALL_PKGS} || return 1
    else
	prompt -w "Package '${PACKAGE_PKGNAME}' not found for install."
    fi
}

###############################
###   :::   M A I N   :::   ###
###############################

    BINNAME=${0##*/}
    PATH_WORK=${PWD}

    [[ -n ${NOCOLOR} ]] || set_color
    _init_

    REQUEST_ARGS=()
    arguments "$@"
    set -- "${REQUEST_ARGS[@]}"

    if [[ ${BACKEND} == 'ubur' ]]; then
	check_access_ubur
	[[ -n ${UBUR_CLEAN} && -z ${PACKAGES} ]] && rm -rdf ${CACHE_UPAC} && prompt -sq "Cache cleaned."
	[[ -z ${UBUR_NOSYNC} ]] && { ubur_repos_update || prompt -eq "Repository UBUR not sync." ; }
	while read -u3 PACKAGE_PKGNAME; do
	    PACKAGE_PKGBASE_FILE=$(grep "pkgname = ${PACKAGE_PKGNAME}" "${PATH_UBUR_REPO_SRCINFO_LOCAL}"/* | cut -f1 -d: | sort -u)
	    [[ -n ${PACKAGE_PKGBASE_FILE} ]] && PACKAGE_PKGBASE=$(grep "pkgbase = " ${PACKAGE_PKGBASE_FILE} | cut -f2 -d= | xargs) || PACKAGE_PKGBASE=
	    if [[ -n ${UBUR_CLEAN} || -n ${UBUR_INSTALL} ]] && [[ -d ${CACHE_UPAC}/${PACKAGE_PKGBASE} ]]; then
		rm -rdf "${CACHE_UPAC}/${PACKAGE_PKGBASE}" && prompt -s "Source '${PACKAGE_PKGNAME}' package cleaned."
	    fi
	    if [[ -n ${UBUR_SEARCH} ]]; then
		ubur_package_search ${PACKAGE_PKGBASE} || { prompt -w "Package '${PACKAGE_PKGNAME}' not found."; continue; }
		ubur_package_search_infocompact ${PACKAGE_PKGNAME} ${PACKAGE_PKGBASE}
	    elif [[ -n ${UBUR_LIST} ]]; then
		ubur_package_list
	    elif [[ -n ${UBUR_INFO} ]]; then
		ubur_package_search ${PACKAGE_PKGBASE} || { prompt -w "Package '${PACKAGE_PKGNAME}' not found."; continue; }
		ubur_package_info ${PACKAGE_PKGNAME} ${PACKAGE_PKGBASE}
	    elif [[ -n ${UBUR_INSTALL} || -n ${UBUR_REINSTALL} ]]; then
		ubur_package_search ${PACKAGE_PKGBASE} || { prompt -w "Package '${PACKAGE_PKGNAME}' not found."; continue; }
		[[ -n ${UBUR_NOSYNC} && -z ${UBUR_INSTALL} ]] || ubur_package_download ${PACKAGE_PKGBASE}
		[[ -z ${UBUR_INSTALL_DOWNLOAD_ONLY} ]] || { prompt -i "Package '${PACKAGE_PKGNAME}' download to '${CACHE_UPAC}/${PACKAGE_PKGBASE}'"; continue; }
		[[ -n ${UBUR_REINSTALL} ]] || ubur_package_prebuild ${PACKAGE_PKGBASE}
		[[ -n ${UBUR_REINSTALL} ]] || ubur_package_build ${PACKAGE_PKGBASE} || { prompt -e "Package '${PACKAGE_PKGNAME}' not build"; continue; }
		[[ -z ${UBUR_BUILD} ]] || { prompt -i "Package '${PACKAGE_PKGNAME}' build to '${CACHE_UPAC}/${PACKAGE_PKGBASE}/'"; continue; }
		ubur_package_install ${PACKAGE_PKGNAME} ${PACKAGE_PKGBASE} || { prompt -e "Package '${PACKAGE_PKGNAME}' not installed."; continue; }
	    elif [[ -n ${UBUR_BUILD} ]]; then
		ubur_package_search ${PACKAGE_PKGBASE} || { prompt -w "Package '${PACKAGE_PKGNAME}' not found."; continue; }
		[[ -z ${UBUR_NOSYNC} ]] && ubur_package_download ${PACKAGE_PKGBASE}
		[[ -z ${UBUR_INSTALL_DOWNLOAD_ONLY} ]] || { prompt -i "Package '${PACKAGE_PKGNAME}' download to '${CACHE_UPAC}/${PACKAGE_PKGBASE}'"; continue; }
		ubur_package_prebuild ${PACKAGE_PKGBASE} || { prompt -e "Package '${PACKAGE_PKGNAME}' did not find files to build"; continue; }
		ubur_package_build ${PACKAGE_PKGBASE} || { prompt -e "Package '${PACKAGE_PKGNAME}' not build"; continue; }
		prompt -i "Package '${PACKAGE_PKGNAME}' build to '${CACHE_UPAC}/${PACKAGE_PKGBASE}/'"
	    elif [[ -n ${UBUR_REMOVE} ]]; then
		if [[ -z ${UBUR_NODEPS} ]]; then
		    sudo -E ${BIN_PACMAN} -Rc ${UBUR_INSTALL_NOCONFIRM} ${PACKAGE_PKGNAME}
		else
		    sudo -E ${BIN_PACMAN} -Rdd ${UBUR_INSTALL_NOCONFIRM} ${PACKAGE_PKGNAME}
		fi
	    fi
	done 3< <(tr ' ' '\n' <<< ${PACKAGES})
    elif [[ ${BACKEND} == 'pacman' ]]; then
	[[ -z $1 ]] && usage_pacman || ${BIN_PACMAN} "$@"
    elif [[ ${BACKEND} == 'yay' ]]; then
	[[ -z $1 ]] && usage_yay || ${BIN_YAY} "$@"
    elif [[ ${BACKEND} == 'pamac' ]]; then
	[[ -z $1 ]] && usage_pamac || ${BIN_PAMAC} "$@"
    fi
