#!/bin/sh

########## ####      ####
########## ####      ####
##      ## ##  ##  ##  ##
##      ## ##  ##  ##  ##
########## ##    ##    ## - PACKAGE MANAGER FOR SIMPLE LINUX
########## ##    ##    ## - AUTHOR -- TOLA MIRONCENKO
##         ##          ##
##         ##          ##
##         ##          ##
##         ##          ##

set -e

#---------------- variables --------------------------
version="1.0.0"
rootdir=/
repofile=$rootdir/etc/pm/repo
packagesqueryfile=$rootdir/usr/share/pm/query
reposquerydir=$rootdir/usr/share/pm/repos
cachedpkgdir=$rootdir/var/cache/pm/pkg
installedpackagesdir=$rootdir/usr/share/pm/packages
command=""
packages=""
archives=""
destdir=""
colors=y
#-----------------------------------------------------

#----- colors -------
RESET=""
GREEN=""
RED=""
BRED=""
YELLOW=""
BWHITE=""
BBLUE=""
BGREEN=""
if [ "$colors" = "y" ]; then
    RESET="\033[0m"
    GREEN="\033[0;32m"
    RED="\033[0;31m"
    BRED="\033[1;31m"
    YELLOW="\033[1;33m"
    BWHITE="\033[1;37m"
    BBLUE="\033[1;34m"
    BGREEN="\033[1;32m"
fi
#--------------------

#------------ check status function ------------
check() {
    if [ $1 -ne 0 ]; then
        printf "${BBLUE}**${BWHITE} $2 [${BRED} ERROR ${BWHITE}]\n${RESET}"
        exit $1
    fi
    printf "${BBLUE}**${BWHITE} $2 [${BGREEN} SUCCESS ${BWHITE}]\n${RESET}"
}
#-----------------------------------------------

#---------------- check root priveleges function ------------------------
checkroot() {
    if [ $(id -u) -ne 0 ]; then
        printf "${BBLUE}**${BWHITE} You must be root [${BRED} ERROR ${BWHITE}]\n${RESET}"
        exit 1
    fi
}
#------------------------------------------------------------------------

# check non root priveleges function
checknonroot() {
    if [ $(id -u) = 0 ]; then
        printf "${BBLUE}**${BWHITE} You must be non root [${BRED} ERROR ${BWHITE}]\n${RESET}"
        exit 1
    fi
}
# ----------------------------------

#----------------- add(install) package function ------------------------
add() {
    checkroot
    [[ "$packages" == "" ]] \
        && help \
        && exit 0
    down
    for i in $packages; do
        archives="$archives $(echo $cachedpkgdir/$i*.pkg.gz)"
    done
    unpack
}
a() {
    add
}
#------------------------------------------------------------------------

#-------------------- download package without install function ---------
down() {
    checkroot
    [[ "$packages" == "" ]] \
        && help \
        && exit 0
    for k in $packages; do
        downloaded=n
        servers=$(/usr/bin/cat $repofile)
        check $? "Read repositories"
        for i in $servers; do
            serverdir=$(echo $i | sed -e "/http:\/\//s///")
            serverdir=$(echo $serverdir | sed -e "/ftp:\/\//s///")
            repoquery=$(/usr/bin/cat $reposquerydir/$serverdir/query | sed -e '/.pkg.gz/s///')
            for j in $repoquery; do
                if [ "$(get_pkgname $j)" = "$(get_pkgname $k)" ] || [ "$(get_pkgname $j)" = "$k" ]; then
                    if [ ! -f $cachedpkgdir/$j.pkg.gz ]; then
                        printf "${YELLOW}**${RESET} Downloading ${YELLOW}$serverdir: ${BWHITE}$j\n${RESET}"
                        echo $i/$j.pkg.gz
                        wget $i/$j.pkg.gz -P $cachedpkgdir
                        check $? "Download package"
                    else
                        printf "${YELLOW}**${GREEN} successful downloaded $k\n${RESET}"
                        export downloaded=y
                    fi
                    export downloaded=y
                fi
            done
        done
        if [ "$downloaded" = "n" ]; then
            printf "${BBLUE}**${BWHITE} Can't find package $k [${BRED} ERROR ${BWHITE}]\n${RESET}"
            exit 1
        fi
        continue
    done
}
download() {
    down
}
#------------------------------------------------------------------------

#-------------------- unpack local package archive ----------------------
unpack() {
    checkroot
    if [[ "$archives" == "" ]]; then
        printf "${BBLUE}**${BWHITE} Specify package name [${BRED} ERROR ${BWHITE}]\n${RESET}"
        exit 1
    fi

    # Сохраняем список архивов для итерации, чтобы он не перезатерся
    local_archives="$archives"

    for archive in $local_archives; do
        if [ ! -f $archive ]; then
            printf "${BBLUE}**${BWHITE} File $archive not found [${BRED} ERROR ${BWHITE}]\n${RESET}" \
            && exit 1
        fi
        packagename=$(echo $archive | sed -e "/.gz/s///")
        packagename=${packagename#*pkg/}
        printf "${YELLOW}**${GREEN} Installing ${packagename%.pkg*}\n${RESET}"
        if [ ! -f $packagesqueryfile ]; then
            printf "${BBLUE}**${BWHITE} Can't find $packagesqueryfile [${BRED} ERROR ${BWHITE}]\n${RESET}" \
            && exit 1
        fi
        installed=false
        # Используем уникальное имя переменной для цикла
        for installed_pkg in $(/usr/bin/cat $packagesqueryfile); do
            if [ "$installed_pkg" = "${packagename%.pkg*}" ]; then
                export installed=true
                break
            fi
        done
        if [[ "$installed" == "true" ]]; then
            printf "${YELLOW}**${RESET} Package already installed:${YELLOW} reinstalling\n${RESET}"
        fi
        tar -xf $cachedpkgdir/$packagename.gz -C $rootdir/tmp
        cd $rootdir/tmp/$packagename
        if [ -f pre_install ]; then
            /usr/bin/sh -c ./pre_install
            rm -v pre_install &> /dev/null
        fi
        if [ -f deps ]; then
            printf "${YELLOW}**${GREEN} Checking deps\n${RESET}"
            pkg_deps=$(/usr/bin/cat deps)

            missing_deps=""
            # Используем уникальное имя переменной
            for dep in $pkg_deps; do
                have=false
                for installed_pack in $(/usr/bin/cat $packagesqueryfile); do
                    if [ $installed_pack = $dep ]; then
                        have=yes
                        break
                    fi
                done
                if [ "$have" = "false" ]; then
                    missing_deps="$missing_deps $dep"
                fi
            done

            # Если есть недостающие зависимости, устанавливаем их
            if [ ! -z "$missing_deps" ]; then
                printf "${YELLOW}**${GREEN} Installing missing dependencies: $missing_deps\n${RESET}"
                # Сохраняем полное текущее состояние
                saved_packagename="$packagename"
                saved_archives="$archives"
                saved_packages="$packages"
                saved_dir=$(pwd)

                # Устанавливаем все недостающие зависимости
                for missing_dep in $missing_deps; do
                    printf "${YELLOW}**${GREEN} Installing dependency: $missing_dep\n${RESET}"

                    # Переходим в безопасную директорию перед вызовом add
                    cd $rootdir

                    # Устанавливаем переменные для add
                    packages="$missing_dep"
                    archives=""

                    # Вызываем add, который скачает и установит зависимость
                    # add изменит глобальные переменные packages и archives
                    add

                    # Возвращаемся в директорию текущего пакета
                    cd "$saved_dir"
                done

                # Полностью восстанавливаем сохраненные переменные
                packagename="$saved_packagename"
                archives="$saved_archives"
                packages="$saved_packages"

                printf "${YELLOW}**${GREEN} Continuing installation of ${packagename%.pkg*}\n${RESET}"
            fi

            mkdir -p $installedpackagesdir/$packagename &> /dev/null
            mv -v deps $installedpackagesdir/$packagename &> /dev/null
        fi
        mkdir -p $installedpackagesdir/$packagename &> /dev/null
        mv -v list $installedpackagesdir/$packagename &> /dev/null
        if [ -f pre_delete ]; then
            mv -v pre_delete $installedpackagesdir/$packagename &> /dev/null
        fi
        if [ -f post_delete ]; then
            mv -v post_delete $installedpackagesdir/$packagename &> /dev/null
        fi
        cp -r ./* $rootdir/
        if [ -f $rootdir/post_install ]; then
            mv -v $rootdir/post_install $installedpackagesdir/$packagename &> /dev/null
        fi
        if [ -f $rootdir/tmp/$packagename/post_install ]; then
            printf "${YELLOW}**${GREEN} post_install script ${packagename%.pkg*}\n${RESET}"
            /usr/bin/sh -c $rootdir/tmp/$packagename/post_install &> /dev/null
        fi
        if [[ "$installed" == "false" ]]; then
            echo ${packagename%.pkg*} >> $packagesqueryfile
        fi
        rm -rv $rootdir/tmp/$packagename &> /dev/null
        printf "${YELLOW}**${GREEN} Installed ${packagename%.pkg*} successful\n${RESET}"
        cd - &> /dev/null
    done
}
u() {
    unpack
}
#------------------------------------------------------------------------

#------------------ delete package function -----------------------------
del() {
    checkroot
    printf "${YELLOW}**${GREEN} deleting\n${RESET}"
    for i in $packages; do
        printf "${YELLOW}**${GREEN} deleting $i\n${RESET}"
        [ ! -f $installedpackagesdir/$i*.pkg/list ] \
            && printf "${BBLUE}**${BWHITE} package not installed ($i) [${BRED} ERROR ${BWHITE}]\n${RESET}" \
            && exit 1
        [ -f $installedpackagesdir/$i*.pkg/pre_delete ] \
            && /usr/bin/sh -c $installedpackagesdir/$i*.pkg/pre_delete
        for file in $(/usr/bin/cat $installedpackagesdir/$i*.pkg/list); do
            rm -v $rootdir/$file
        done
        rm -rv $installedpackagesdir/$i*.pkg &> /dev/null
        packs=$(cat $packagesqueryfile)
        rm $packagesqueryfile
        for pack in $packs; do
            if [ "$(get_pkgname $pack)" = "$i" ]; then
                continue
            fi
            echo $pack >> $packagesqueryfile
        done
        [ -f $installedpackagesdir/$i*.pkg/post_delete ] \
            && /usr/bin/sh -c $installedpackagesdir/$i*.pkg/post_delete
        printf "${YELLOW}**${GREEN} delete $i successful\n${RESET}"
    done
}
d() {
    del
}
#------------------------------------------------------------------------

#------------------- list files in package function ---------------------
list() {
    if [[ "$packages" == "" ]]; then
        for i in $(/usr/bin/cat $packagesqueryfile); do
            cd $installedpackagesdir
            pkgname=$(echo $(find . -name "$i*") | sed -e "/.\//s///" | sed -e "/.pkg/s///")
            cd - &>/dev/null
            if [[ "$(/usr/bin/cat $packagesqueryfile | grep $i)" == "" ]]; then
                printf "${BBLUE}**${BWHITE} Package "$i" is not installed [${BRED} ERROR ${BWHITE}]\n${RESET}"
                continue
            fi
            filelist=$(/usr/bin/cat $installedpackagesdir/$pkgname*.pkg/list)
            for j in $filelist; do
                printf "${YELLOW}$(get_pkgname $pkgname) ${BGREEN}$(get_pkgver $pkgname)-$(get_pkgrel $pkgname): ${BWHITE}$j${RESET}\n"
            done
            unset pkgname
        done
        exit 0
    fi
    for i in $packages; do
        cd $installedpackagesdir
        pkgname=$(echo $(find . -name "$i*") | sed -e "/.\//s///" | sed -e "/.pkg/s///")
        cd - &>/dev/null
        if [[ "$(/usr/bin/cat $packagesqueryfile | grep $i)" == "" ]]; then
            printf "${BBLUE}**${BWHITE} Package "$i" is not installed [${BRED} ERROR ${BWHITE}]\n${RESET}"
            continue
        fi
        filelist=$(/usr/bin/cat $installedpackagesdir/"${pkgname}".pkg/list)
        for j in $filelist; do
            printf "${YELLOW}$(get_pkgname $pkgname) ${BGREEN}$(get_pkgver $pkgname)-$(get_pkgrel $pkgname): ${BWHITE}$j${RESET}\n"
        done
        unset pkgname
    done
}
l() {
    list
}
#------------------------------------------------------------------------

# print pkgrel function
get_pkgrel() {
    echo $(echo $1 | awk -F'-' '{ print $NF }')
}
#------------------------

# print pkgver function
get_pkgver() {
    echo $(echo $1 | awk -F'-' '{ print $(NF-1) }')
}
#------------------------

# print pkgname function
get_pkgname() {
    echo $( echo $(echo $1 | awk -F'-' '{ for (i=NF-2; i>=1; i--) print $i }') | awk -F' ' '{ if (NF==1) { print $NF } else { for (i=NF; i >= 1; i--) { if (i-1 >= 1) { printf $i "-" } else { printf $i } } } }')
}
#------------------------

# print package information function
printpkg() {
    printf "${BWHITE}$(get_pkgname $1) ${BGREEN}$(get_pkgver $1)-$(get_pkgrel $1)\n${RESET}"
}
#-------------------------------------

#------------------- show installed packages function -------------------
query() {
    packagesquery=$(/usr/bin/cat $packagesqueryfile)
    [[ "$packagesquery" == "" ]] \
        && printf "${YELLOW}**${BWHITE} No installed packages\n${RESET}" \
        && exit 0
    for i in $packagesquery; do
        printpkg $i
    done
}
q() {
    query
}
#------------------------------------------------------------------------

#--------------------- show help function -------------------------------
help() {
    printf "
${YELLOW}**${GREEN} pm usage${RESET}:
    ${BWHITE}pm <options> <command> [<package name>]

${YELLOW}Commands:${BWHITE}
    ${BGREEN}add, a, -a, --add [package name]${BWHITE} - download and install from repository
    ${BGREEN}unpack, u, -u, --unpack [/path/to/package/archive]${BWHITE} - unpack(install) from local package archive
    ${BGREEN}down, download, --download [package name]${BWHITE} - download package from repository without install
    ${BGREEN}up, upgrade, -U, --upgrade${BWHITE} - upgrade packages
    ${BGREEN}del, d, -d, --delete, --del [package name]${BWHITE} - delete package
    ${BGREEN}list, l, -L, --list [package name]${BWHITE} - list files in package
    ${BGREEN}search, ss, -s, --search, --ss [package name]${BWHITE} - search package in repository
    ${BGREEN}query, q, -q, --query${BWHITE} - show installed packages
    ${BGREEN}help, -h, --help${BWHITE} - this help message
    ${BGREEN}clear, c, -c, --clear${BWHITE} - clear all package archives from cached packages directory
    ${BGREEN}sync, s, -S, --sync${BWHITE} - synchronize repository
    ${BGREEN}deps, -D, --deps [package name]${BWHITE} - show package dependencies
    ${BGREEN}build${BWHITE} - build package (./ must contain PMBUILD)
    ${BGREEN}index, i, -i, --index${BWHITE} - scan directory with packages and print packages in terminal (to create repository query use pm index > query)
    ${BGREEN}cache, cs, -C, --cache${BWHITE} - show cache size
    ${BGREEN}v, version, -v, --version${BWHITE} - show version

${YELLOW}Options:${BWHITE}
    ${BGREEN}-r, --rootdir${BWHITE} - set root directory for package manager
${RESET}"
}
#------------------------------------------------------------------------

#------------------- sync repo function ---------------------------------
sync() {
    checkroot
    servers=$(/usr/bin/cat $repofile)
    for i in $servers; do
        printf "${YELLOW}**${GREEN} Sync ${BWHITE}$i\n${RESET}"
        serverdir=$(echo $i | sed -e "/http:\//s///")
        serverdir=$(echo $serverdir | sed -e "/ftp:\//s///")
        mkdir -p $reposquerydir/$serverdir &> /dev/null
        wget $i/query -O $reposquerydir/$serverdir/query &> /dev/null
        check $? "Sync $i"
    done
}
s() {
    sync
}
#------------------------------------------------------------------------

#----------------- search package in repo function ----------------------
search() {
    servers=$(/usr/bin/cat $repofile)
    if [[ "$packages" == "" ]]; then
        for i in $servers; do
            serverdir=$(echo $i | sed -e "/http:\/\//s///")
            serverdir=$(echo $serverdir | sed -e "/ftp:\/\//s///")
            repoquery=$(/usr/bin/cat $reposquerydir/$serverdir/query | sed -e '/.pkg.gz/s///')
            for j in $repoquery; do
                installed=false
                for inst in $(/usr/bin/cat $packagesqueryfile); do
                    [ "$(get_pkgname $inst)" = "$(get_pkgname $j)" ] \
                    && [ "$(get_pkgver $inst)" = "$(get_pkgver $j)" ] \
                    && [ "$(get_pkgrel $inst)" = "$(get_pkgrel $j)" ] \
                        && export installed=true \
                        && break
                done
                printf "${YELLOW}$serverdir: ${BWHITE}$(get_pkgname $j) ${BGREEN}$(get_pkgver $j)-$(get_pkgrel $j) ${RESET}"
                [[ "$installed" == "true" ]] \
                    && printf "${BBLUE}[installed]\n${RESET}" \
                    || echo ""
            done
        done
        exit 0
    fi
    for k in $packages; do
        found=false
        for i in $servers; do
            serverdir=$(echo $i | sed -e "/http:\/\//s///")
            serverdir=$(echo $serverdir | sed -e "/ftp:\/\//s///")
            repoquery=$(/usr/bin/cat $reposquerydir/$serverdir/query | sed -e '/.pkg.gz/s///')
            for j in $repoquery; do
                if [[ $j =~ $k ]]; then
                    printf "${YELLOW}$serverdir: ${BWHITE}$j\n${RESET}"
                    found=true
                fi
            done
        done
        [ "$found" = "false" ] && printf "${YELLOW}**${RED} error:${RESET} can't find package ($k)\n"
    done
}
ss() {
    search
}
#------------------------------------------------------------------------

#------------------- clear cached packages directory --------------------
clear() {
    checkroot
    printf "${YELLOW}**${BWHITE} clearing cached packages directory "
    rm -rf $cachedpkgdir/*
    printf "[${GREEN} OK${BWHITE} ]\n${RESET}"
}
clean() {
    clear
}
c() {
    clear
}
#------------------------------------------------------------------------

#--- show package dependencies function ---
deps() {
    checkroot
    if [[ "$packages" == "" ]]; then
        for i in $(/usr/bin/cat $packagesqueryfile); do
            cd $installedpackagesdir
            pkgname=$(echo $(find . -name "$i*") | sed -e "/.\//s///" | sed -e "/.pkg/s///")
            cd - &>/dev/null
            printf "${YELLOW}$(get_pkgname $pkgname) ${BGREEN}$(get_pkgver $pkgname)-$(get_pkgrel $pkgname)${BWHITE} deps: \n${RESET}"
            [ ! -f $installedpackagesdir/${pkgname}.pkg/deps ] \
                && printf "\t${YELLOW}**${BWHITE} No deps\n${RESET}" \
                && continue
            for j in $(cat $installedpackagesdir/${pkgname}.pkg/deps); do
                printf "\t"
                printpkg $j
            done
            unset pkgname
        done
        exit 0
    fi
    for i in $packages; do
        cd $installedpackagesdir
        pkgname=$(echo $(find . -name "$i*") | sed -e "/.\//s///" | sed -e "/.pkg/s///")
        cd - &>/dev/null
        if [ "$pkgname" = "" ]; then
            printf "${BBLUE}**${BWHITE} Package $i not found [${BRED} ERROR ${BWHITE}]\n${RESET}"
            continue
        fi
        printf "${YELLOW}$(get_pkgname $pkgname) ${BGREEN}$(get_pkgver $pkgname)-$(get_pkgrel $pkgname)${BWHITE} deps: \n${RESET}"
        [ ! -f $installedpackagesdir/${pkgname}.pkg/deps ] \
            && printf "\t${YELLOW}**${BWHITE} No deps\n${RESET}" \
            && continue
        for j in $(cat $installedpackagesdir/${pkgname}.pkg/deps); do
            printf "\t"
            printpkg $j
        done
        unset pkgname
    done
}
#------------------------------------------

#--- build package uses PMBUILD file function ---
buildpkg() {
    checknonroot
    if [ ! -f ./PMBUILD ]; then
        if [ "$1" != "" ]; then
            source $1
        else
            printf "${BBLUE}**${BWHITE} Can't find PMBUILD [${BRED} ERROR ${BWHITE}]\n${RESET}"
            exit 1
        fi
    else
        source ./PMBUILD
    fi
     export buildroot=$(pwd)
    if [ -f $buildroot/$pkgname-$pkgver-$pkgrel.pkg.gz ]; then
        if [ "$1" != "-r" ]; then
            printf "${BBLUE}**${BWHITE} $pkgname-$pkgver-$pkgrel.pkg.gz already exists please use -r to rebuild [${YELLOW} WARNING ${BWHITE}]\n${RESET}"
            exit 0
        else
            [ -d pkg ] && rm -rf pkg
            [ -d src ] && rm -rf src
            [ -f $pkgname-$pkgver-$pkgrel.pkg.gz ] \
                && rm -rf $pkgname-$pkgver-$pkgrel.pkg.gz
        fi
    fi
    [ ! -d src ] && mkdir -p src
    [ ! -d pkg/$pkgname-$pkgver-$pkgrel.pkg ] \
        && mkdir -p pkg/$pkgname-$pkgver-$pkgrel.pkg
    export pkgdir=$buildroot/pkg/$pkgname-$pkgver-$pkgrel.pkg
    [ "$srcdir" = "" ] && export srcdir=$buildroot/src/$pkgname
    [ "$gitsource" != "" ] \
        && printf "${BBLUE}**${BWHITE} Downloading sources\n${RESET}" \
        && git clone $gitsource $srcdir \
        && check $? "Download sources"
    if [ "$source" != "" ]; then
        printf "${BBLUE}**${BWHITE} Downloading sources\n${RESET}"
        [ ! -d $srcdir ] && mkdir -p $srcdir
        cd $srcdir
        [ ! -f $pkgname-$pkgver.tar.* ] && wget $source
        cd -
    fi
    if [[ $(type -t configure) = function ]]; then
        printf "${BBLUE}**${BWHITE} Configuring package\n${RESET}"
        configure
        check $? "Configure"
    fi
    if [[ $(type -t build) = function ]]; then
        printf "${BBLUE}**${BWHITE} Building package\n${RESET}"
        build
        check $? "Build"
    else
        echo "no build"
    fi
    if [[ $(type -t package) == function ]]; then
        printf "${BBLUE}**${BWHITE} Packaging package\n${RESET}"
        package
        check $? "Package"
    else
        echo "no package"
    fi
    printf "${BBLUE}**${BWHITE} Stripping unneded symbols\n${RESET}"
    STRIP=$(which strip)
    if [ -n "$CROSS_COMPILE" ]; then
        STRIP=$CROSS_COMPILE-strip
    fi
    for execfile in $(find $pkgdir -executable -type f); do
        $STRIP $execfile
    done
    printf "${BBLUE}**${BWHITE} Strip unneded symbols [${BGREEN} SUCCESS ${BWHITE}]\n${RESET}"
    cd $pkgdir
    find -type f > $buildroot/list
    find -type l >> $buildroot/list
    sed -i "s/.\///" $buildroot/list
    sed -i 's/usr\/sbin//g' $buildroot/list
    sed -i 's/usr\/lib64//g' $buildroot/list
    sed -i 's/usr\/lib32//g' $buildroot/list
    cd $buildroot
    mv list $pkgdir/list
    if [ "$deps" != "" ]; then
        for i in $deps; do
            echo $i >> $pkgdir/deps
        done
    fi
    cd $pkgdir
    printf "${BBLUE}**${BWHITE} Archiving package\n${RESET}"
    tar -czf $buildroot/$pkgname-$pkgver-$pkgrel.pkg.gz .. &> /dev/null
    check $? "Archive package"
    cd $buildroot
    unset pkgdir srcdir buildroot
}
#-----------------------------------------------------

# upgrade system packages function
upgrade() {
    checkroot
    total_updates=0
    for i in $(cat $packagesqueryfile); do
        package=$(search $(get_pkgname $i) | awk -F' ' '{ for (i=2; i<=NF; i++) { print $i } }')
        repo=$(search $(get_pkgname $i) | awk -F' ' '{ print $1 }')
        for j in $package; do
            if [ $(get_pkgrel $j) -gt $(get_pkgrel $i) ]; then
                printf "${BRED}old: $(printpkg $i)"
                printf "${BGREEN}new: $(printpkg $j)"
                printf "${BGREEN}from: $(printf $repo | sed 's/://g')\n${RESET}"
                total_updates=$((total_updates+1))
                continue
            fi
            instver=$(echo $(get_pkgver $i) | awk -F'.' '{ for (i=1; i<=NF; i++) printf $i }')
            repover=$(echo $(get_pkgver $j) | awk -F'.' '{ for (i=1; i<=NF; i++) printf $i }')
            if [ $repover -gt $instver ]; then
                printf "${BRED}old: $(printpkg $i)"
                printf "${BGREEN}new: $(printpkg $j)"
                printf "${BGREEN}from: $(printf $repo | sed 's/://g')\n${RESET}"
                total_updates=$((total_updates+1))
                continue
            fi
        done
    done
    printf "${YELLOW}Total updates: ${BWHITE}$total_updates\n${RESET}"
    return
}
up() {
    upgrade
}
#-----------------------------

# index packages in directory and create query file for create pm repository
index() {
    for i in $(ls | grep .pkg.gz);do echo $i | sed 's/.pkg.gz//g';done
}
i() {
    index
}
#---------------------------------------------------------------------------

# calculate cache size function
cachesize() {
    printf "${YELLOW}Cache size: ${BWHITE}$(du -sh $cachedpkgdir | awk '{print $1}')\n${RESET}"
}
cs() {
    cachesize
}
#------------------------------

# print version function
version() {
    printf "
${BWHITE}########## ####      ####
${BWHITE}########## ####      ####
${BWHITE}##      ## ##  ##  ##  ##
${BWHITE}##      ## ##  ##  ##  ##
${BWHITE}########## ##    ##    ## - ${BGREEN}PACKAGE MANAGER FOR SIMPLE LINUX
${BWHITE}########## ##    ##    ## - ${BGREEN}AUTHOR ${BWHITE}-- TOLA MIRONCENKO
${BWHITE}##         ##          ## - ${BGREEN}VERSION ${BWHITE}-- ${version}
${BWHITE}##         ##          ##
${BWHITE}##         ##          ##
${BWHITE}##         ##          ##
${RESET}"
}
v() {
    version
}
#------------------------------

# install pm to some rootfs directory function
selfinstall() {
    checkroot
    [ -z "$destdir" ] && destdir="rootfs"
    printf "${BGREEN}Installing pm to ${BWHITE}$destdir ${BGREEN}directory\n${RESET}"
    printf "${YELLOW}Creating directories... ${RESET}"
    [ ! -d $destdir ] && mkdir -p $destdir
    [ ! -d $destdir/etc/pm ] && mkdir -p $destdir/etc/pm
    [ ! -d $destdir/tmp ] && mkdir -p $destdir/tmp
    [ ! -d $destdir/usr/bin ] && mkdir -p $destdir/usr/bin
    [ ! -d $destdir/usr/share/pm ] && mkdir -p $destdir/usr/share/pm
    [ ! -d $destdir/usr/share/pm/packages ] && mkdir -p $destdir/usr/share/pm/packages
    [ ! -d $destdir/usr/share/pm/repos ] && mkdir -p $destdir/usr/share/pm/repos
    [ ! -d $destdir/var/cache/pm/pkg ] && mkdir -p $destdir/var/cache/pm/pkg
    printf "${BWHITE}[ ${BGREEN}OK ${BWHITE}]${RESET}\n"
    printf "${YELLOW}Creating files... ${RESET}"
    [ ! -f $destdir/etc/pm/repo ] && touch $destdir/etc/pm/repo
    [ ! -f $destdir/usr/share/pm/query ] && touch $destdir/usr/share/pm/query
    [ ! -f $destdir/usr/bin/pm ] && cp $rootdir/usr/bin/pm $destdir/usr/bin/pm
    printf "${BWHITE}[ ${BGREEN}OK ${BWHITE}]${RESET}\n"
    printf "${BGREEN}Installation completed successfully.${RESET}\n"
}
si() {
    selfinstall
}
#--------------------------------------------

# parse command function
parse_command() {
    while [ $1 ]; do
        case "$1" in
            add|a|del|d)
                command=$1
                shift
                packages=$@
                break;
                ;;
            s|sync|clear|c|clean|down|download)
                command=$1
                shift
                packages=$@
                break;
                ;;
            unpack|u|up|upgrade|i|index|v|version)
                command=$1
                shift
                archives=$@
                break;
                ;;
            query|q|search|ss|list|l|deps|cachesize|cs)
                command=$1
                shift
                packages=$@
                break
                ;;
            selfinstall|si)
                command=$1
                shift
                ;;
            build)
                checknonroot
                buildpkg $@
                exit 0
                ;;
            *)
                shift
                ;;
        esac
    done
}
#---------------------------

# parse options function
parse_opts() {
    while [ $1 ]; do
        case "$1" in
            -h|--help)
                help
                exit 0
                ;;
            -r|--rootdir)
                rootdir=$2
                shift 2
                ;;
            -q|--query)
                command=query
                shift
                ;;
            -S|--sync)
                command=sync
                shift
                ;;
            -C|--cache)
                command=cachesize
                shift
                ;;
            -c|--clear)
                command=clear
                shift
                ;;
            -i|--index)
                command=index
                shift
                ;;
            -D|--deps)
                command=deps
                shift
                packages=$@
                ;;
            -L|--list)
                command=list
                shift
                packages=$@
                ;;
            -a|--add)
                command=add
                shift
                packages=$@
                ;;
            -u|--unpack)
                command=unpack
                shift
                archives=$@
                ;;
            --download)
                command=download
                shift
                packages=$@
                ;;
            -d|--delete|--del)
                command=del
                shift
                packages=$@
                ;;
            -U|--upgrade)
                command=upgrade
                shift
                ;;
            -s|--search|--ss)
                command=search
                shift
                packages=$@
                ;;
            -v|--version)
                command=version
                shift
                ;;
            --si|--selfinstall)
                command=selfinstall
                shift
                ;;
            --dest)
                destdir=$2
                shift 2
                ;;
            *)
                if [ "${1#--}" != "$1" ] || [ "${1#-}" != "$1" ]; then
                    echo "Invalid option: $1" >&2
                    help
                    exit 1
                fi
                shift
                ;;
        esac
    done
}
#---------------------------

#--- main ---
main() {
    parse_command "$@"
    parse_opts "$@"
    if [ -z "$command" ]; then
        help
        exit 1
    fi
    $command
}
#------------

main $@
