#!/bin/bash
#
# Set autogit directory
DIR=$HOME/autogit
#
# Set cache directory and create it
CACHEDIR=/tmp/autogit
if [ -e "$DIR" ]; then
    mkdir -p "$CACHEDIR"
fi
#
# Additional Files
# Checked packages:
CHECKEDPKGS=$CACHEDIR/.pkgs.txt
# Failed to build packages:
FAILEDPKGS=$CACHEDIR/.failed.txt
# Compiled packages
COMPILEDPKGS=$CACHEDIR/.compiled.txt
#
# Configuration file update check
function conf_ver_upd() {
    # Check if the local ".conf" needs to be merged with the new package ".conf"
    # because code changes require it.
    # Define a hard coded variable, which will be checked inside the ".conf file"
    if [ "$CONFVER" == "2.0.0" ]; then
        echo "Up to date configuration" &>/dev/null
    else
        clear
        echo ""
        echo -e " \e[1mPackage Update - manual intervention required!\e[0m"
        echo -e " \e[1mPlease merge the changes of \e[7m/etc/autogit/autogit.conf\e[0m \e[1mfor usage!\e[0m"
        echo ""
        exit 1
    fi
}
#
# Check if a local configuration exists
if [ -e "$DIR" ]; then                  # If local autogit folder exists
    if [ -e "$DIR/autogit.conf" ]; then # If local autogit.conf file exists in "$DIR"

        # Load User configuration
        # This is the default behavior to quickly change all settings without the need of root access,
        # but can be changed by deleting the ".conf" in "$DIR" and "$HOME/.config/autogit", to use the root file instead.
        configdir=$DIR
        . "$configdir"/autogit.conf

        # Configuration file update check
        conf_ver_upd
    else
        if [ -e "$HOME/.config/autogit/autogit.conf" ]; then # If local autogit.conf file exists in "$HOME/.config/autogit"

            # Load User configuration
            # This is the default behavior to quickly change all settings without the need of root access,
            # but can be changed by deleting the ".conf" in "$DIR" and "$HOME/.config/autogit", to use the root file instead.
            configdir=$HOME/.config/autogit
            . "$configdir"/autogit.conf

            # Configuration file update check
            conf_ver_upd
        else
            # If a local "autogit.conf" file does not exist, but the autogit folder is present in "$DIR",
            # we need to assume the user wants to use the root configuration file instead.
            # This means a new configuration file can be detected via a ".pacnew" file and
            # should not require a message on changes, as this is user preference.
            # Load root configuration
            configdir=/etc/autogit
            . $configdir/autogit.conf
        fi
    fi
else
    # Create a local configuration on first run or if "$DIR" is not found
    if [ -e "/etc/autogit" ]; then
        if mkdir -p "$DIR" && cp -r /etc/autogit/reponames "$DIR" && cp -r /etc/autogit "$HOME/.config" && ln -s "$HOME/.config/autogit/autogit.conf" "$DIR"; then
            newconfig=1
        fi
    fi
fi
#
# Traps (ctrl-c)
function killproc() {
    echo -e "\n**** Received SIGINT, aborting! ****\n"
    kill -- -$$ && exit 2
}
#
# Messages
GITHUBMSG="\e[1mGithub repo updated - \e[7m$GITHUBBINARY\e[0m\e[0m"
GITHUBMSGCUST="\e[1mGithub repo updated - \e[7m$GITHUBBINARYCUSTOM\e[0m\e[0m"
GITHUBMSGCUST2="\e[1mGithub repo updated - \e[7m$GITHUBBINARYCUSTOM2\e[0m\e[0m"
GITHUBMSGCUST3="\e[1mGithub repo updated - \e[7m$GITHUBBINARYCUSTOM3\e[0m\e[0m"
GITHUBMSGCUST4="\e[1mGithub repo updated - \e[7m$GITHUBBINARYCUSTOM4\e[0m\e[0m"
GITHUBMSGCUST5="\e[1mGithub repo updated - \e[7m$GITHUBBINARYCUSTOM5\e[0m\e[0m"
GITLABMSG="\e[1mGitlab repo updated - \e[7m$GITLABBINARY\e[0m\e[0m"
GITLABMSGCUST="\e[1mGitlab repo updated - \e[7m$GITLABBINARYCUSTOM\e[0m\e[0m"
GITLABMSGCUST2="\e[1mGitlab repo updated - \e[7m$GITLABBINARYCUSTOM2\e[0m\e[0m"
GITLABMSGCUST3="\e[1mGitlab repo updated - \e[7m$GITLABBINARYCUSTOM3\e[0m\e[0m"
GITLABMSGCUST4="\e[1mGitlab repo updated - \e[7m$GITLABBINARYCUSTOM4\e[0m\e[0m"
GITLABMSGCUST5="\e[1mGitlab repo updated - \e[7m$GITLABBINARYCUSTOM5\e[0m\e[0m"
AURMSG="\e[1mAUR repo updated - \e[7m$AURBINARY\e[0m\e[0m"
FAILEDBUILDMSG="\e[31mPackage build failed, removing ...\e[0m"
#
# Source package directory mapping for efficient lookup
declare -A SOURCE_MAP=(
    ["GITHUBSOURCE"]="Github1:$GITHUBBINARY"
    ["GITHUBSOURCECUSTOM"]="Github2:$GITHUBBINARYCUSTOM"
    ["GITHUBSOURCECUSTOM2"]="Github3:$GITHUBBINARYCUSTOM2"
    ["GITHUBSOURCECUSTOM3"]="Github4:$GITHUBBINARYCUSTOM3"
    ["GITHUBSOURCECUSTOM4"]="Github5:$GITHUBBINARYCUSTOM4"
    ["GITHUBSOURCECUSTOM5"]="Github6:$GITHUBBINARYCUSTOM5"
    ["GITLABSOURCE"]="Gitlab1:$GITLABBINARY"
    ["GITLABSOURCECUSTOM"]="Gitlab2:$GITLABBINARYCUSTOM"
    ["GITLABSOURCECUSTOM2"]="Gitlab3:$GITLABBINARYCUSTOM2"
    ["GITLABSOURCECUSTOM3"]="Gitlab4:$GITLABBINARYCUSTOM3"
    ["GITLABSOURCECUSTOM4"]="Gitlab5:$GITLABBINARYCUSTOM4"
    ["GITLABSOURCECUSTOM5"]="Gitlab6:$GITLABBINARYCUSTOM5"
    ["AURSOURCE"]="AUR:$AURBINARY"
)
#
# Online connection check
function onlinecheck() {
    # Check for a internet connection with retry logic
    local retries=3
    local attempt=1
    
    while [ $attempt -le $retries ]; do
        if curl -f -s "$GITHUBURL" >/dev/null 2>&1; then
            return 0
        fi
        
        if [ $attempt -lt $retries ]; then
            echo "No online connection ..retrying"
            sleep 2
        fi
        ((attempt++))
    done
    
    echo "No online connection for $p ..exit!"
    exit 1
}
#
# Supported build options
function buildoptions() {
    failedbuild=0

    case "$var" in
        3)
            # Arch "devtools" - Convenience way option
            if $MBARG1 "$MBARG2" "$MBARG3" "$MBARG4"; then
                rm -rf ./*.*.log* ./*.log &>/dev/null                                # remove log files
                if mv ./*.*.pkg.* "$DIR/$GITHUBBINARY" &>/dev/null; then             # move built package
                    rm -rf ./*.*.tar.* ./*.zip ./*.deb &>/dev/null                   # remove left over source packages
                    find "$DIR/$GITHUBBINARY" -type d -exec paccache -v -r -k 1 -c {} \; # clean cache
                    setrepoadd=1
                else
                    echo -e "\e[1m\e[31mError: Failed to move package files to \"$DIR/$GITHUBBINARY\"\e[0m"
                fi
            else
                echo -e "$FAILEDBUILDMSG"
                rm -rf PKGBUILD &>/dev/null
                failedbuild=1
            fi
            ;;
        1)
            # Makepkg building
            if makepkg "$MARG1" "$MARG2" "$MARG3" "$MARG4" "$MARG5" "$MARG6"; then
                if mv ./*.*.pkg.* "$DIR/$GITHUBBINARY" &>/dev/null; then
                    rm -rf ./*.*.tar.* ./*.zip ./*.deb &>/dev/null
                    find "$DIR/$GITHUBBINARY" -type d -exec paccache -v -r -k 1 -c {} \; # clean cache
                    setrepoadd=1
                else
                    echo -e "\e[1m\e[31mError: Failed to move package files to \"$DIR/$GITHUBBINARY\"\e[0m"
                fi
            else
                echo -e "$FAILEDBUILDMSG"
                rm -rf PKGBUILD &>/dev/null
                failedbuild=1
            fi
            ;;
        0)
            # Makepkg installation
            if makepkg -srci --noconfirm; then
                echo "installed ..."
            else
                echo -e "$FAILEDBUILDMSG"
                rm -rf PKGBUILD &>/dev/null
                failedbuild=1
            fi
            ;;
        2)
            # Manjaro chrootbuild
            local -a chroot_args=()
            [[ -n "$MCARG1" ]] && chroot_args+=("$MCARG1")
            [[ -n "$MCARG2" ]] && chroot_args+=("$MCARG2")
            [[ -n "$MCARG3" ]] && chroot_args+=("$MCARG3")
            [[ -n "$MCARG4" ]] && chroot_args+=("$MCARG4")
            [[ -n "$MCARG5" ]] && chroot_args+=("$MCARG5")
            [[ -n "$MCARG6" ]] && chroot_args+=("$MCARG6")

            # Source folder
            local folder="$(printf '%q\n' "${PWD##*/}")"
            local original_dir="$PWD"

            # "chrootbuild" doesn't like to be inside the "git" directory, but instead wants to be pointed at it
            cd .. || return 1

            echo "Buildcommand = sudo chrootbuild ${chroot_args[*]} $folder"

            if sudo chrootbuild "${chroot_args[@]}" "$folder"; then
                if mv ./*.*.pkg.* "$DIR/$GITHUBBINARY" &>/dev/null; then
                    cd "$original_dir" || return 1
                    rm -rf ./*.*.log* ./*.log &>/dev/null
                    rm -rf ./*.*.tar.* ./*.zip ./*.deb &>/dev/null
                    find "$DIR/$GITHUBBINARY" -type d -exec paccache -v -r -k 1 -c {} \; # clean cache
                    setrepoadd=1
                else
                    cd "$original_dir" || return 1
                    echo -e "\e[1m\e[31mError: Failed to move package files to \"$DIR/$GITHUBBINARY\"\e[0m"
                fi
            else
                echo -e "$FAILEDBUILDMSG"
                rm -rf "$folder"/PKGBUILD &>/dev/null
                cd "$original_dir" || return 1
                failedbuild=1
            fi
            ;;
    esac
}
#
# Find "-git" package source
# shellcheck disable=SC2120
function gitpkg_src_check() {
    local PKGBUILD=${1:-PKGBUILD}
    shopt -s expand_aliases 2>/dev/null || true

    # Define a helper to safely expand variable names
    safe_eval() {
        local expr="$1"
        eval "echo \"\$${expr}\"" 2>/dev/null || echo "$expr"
    }

    # Source PKGBUILD
    # shellcheck disable=SC1090
    if ! source "$PKGBUILD"; then
        echo "Error: Failed to source $PKGBUILD" >&2
        return 1
    fi

    # Handle source array safely
    local srcdir=${srcdir:-$PWD}
    local entry dir_part url_part dir_name

    # Check if source array is defined and non-empty
    if [[ -z "${source[*]}" ]]; then
        echo "No sources defined in PKGBUILD" >&2
        return 1
    fi

    # Loop through source array entries
    # shellcheck disable=SC2154
    for entry in "${source[@]}"; do
        [[ "$entry" != *"git+"* ]] && continue

        # Handle name::git+url syntax
        if [[ "$entry" == *::git+* ]]; then
            dir_part="${entry%%::git+*}"
            url_part="${entry#*::git+}"
        else
            dir_part=""
            url_part="$entry"
        fi

        # If directory name not specified explicitly, extract from URL
        if [[ -z "$dir_part" ]]; then
            url_part="${url_part%%#*}" # strip fragment
            dir_part="$(basename "${url_part}" .git)"
        fi

        # Expand any variables in dir_part
        if [[ "$dir_part" =~ \$ ]]; then
            dir_part="$(safe_eval "${dir_part#\${}")"
        fi

        dir_name="$dir_part"

        # Check if directory exists and "cd" into it
        if [[ -d "$srcdir/$dir_name" ]]; then
            cd "$srcdir/$dir_name" || return 1
            return 0
        else
            echo "Git source directory '$dir_name' not found in $srcdir" >&2
            return 1
        fi
    done

    echo "No git source found in PKGBUILD" >&2
    return 1
}
#
# Main functionality
function maincheck() {
    if [ -e "$DIR/packages/$GITDIR/$p" ]; then # If file exists
        cd "$DIR/packages/$GITDIR/$p" || exit  # go to current package directory to compare it

        ONLINEPKGBUILD=".onlinepkgbuild"
        CURL=$(curl -f -s "$GITHUBURL" | tee "$ONLINEPKGBUILD")
        onlinecheck

        # Update check method 1: compare "pkgver" + "pkgrel" & "sha512sum of PKGBUILD's via curl"
        if [ "$UPDCHECK" == "1" ]; then
            if [ -e "PKGBUILD" ]; then # If file exists "PKGBUILD"
                LOCALPKGVER=$(grep -m1 '^pkgver=' PKGBUILD | cut -c 8-)
                LOCALPKGREL=$(grep -m1 '^pkgrel=' PKGBUILD | cut -c 8-)
                GETPKGVER=$(echo "$CURL" | grep -m1 '^pkgver=' | cut -c 8-)
                GETPKGREL=$(echo "$CURL" | grep -m1 '^pkgrel=' | cut -c 8-)
                SHA512LOCAL=$(sha512sum PKGBUILD | cut -f 1 -d " ")
                SHA512ONLINE=$(sha512sum "$ONLINEPKGBUILD" | cut -f 1 -d " ")

                echo -e "\e[1m⚿ local  version: $LOCALPKGVER-$LOCALPKGREL\e[0m"
                echo -e "\e[1m⚿ online version: $GETPKGVER-$GETPKGREL\e[0m"
            fi
        fi

        # Update check method 2: compare "pkgver" + "pkgrel" of ".SRCINFO's" & "sha512sum" of PKGBUILD's via "git" & "makepkg"
        if [ "$UPDCHECK" == "2" ]; then
            ONLINESRCDIR="onlinesrcinfo"
            # Local PKGBUILD ".SRCINFO"
            if [ -e "PKGBUILD" ]; then # If file exists "PKGBUILD"

                if [ -e ".SRCINFO" ]; then # If file exists ".SRCINFO"
                    echo ".SRCINFO exists" &>/dev/null
                else
                    makepkg --printsrcinfo >.SRCINFO # print .SRCINFO file for a reliable local pkg update reference
                fi

                # Online PKGBUILD ".SRCINFO"
                if [ -e "$ONLINESRCDIR" ]; then # If file exists
                    cd "$ONLINESRCDIR/original" || exit
                    git fetch origin &>/dev/null
                    git checkout origin/"$BRANCH" &>/dev/null
                    git reset --hard origin/"$BRANCH" &>/dev/null                               # reset files to how they were before
                    git clean -f -d &>/dev/null                                                 # clear any other changes you've done
                    makepkg --printsrcinfo >"$DIR/packages/$GITDIR/$p"/"$ONLINESRCDIR"/.SRCINFO # print .SRCINFO file for a reliable online pkg update reference
                    cd "$DIR/packages/$GITDIR/$p" || exit                                       # go to current package directory
                else
                    if mkdir -p "$ONLINESRCDIR" && cd "$ONLINESRCDIR"; then
                        git clone --single-branch --branch "$BRANCH" "$GITHUBCLONEURL""$p".git &>/dev/null
                        folder="$(ls)"
                        mv "$folder" original &>/dev/null
                        cd original || exit
                        makepkg --printsrcinfo >"$DIR/packages/$GITDIR/$p"/"$ONLINESRCDIR"/.SRCINFO # print .SRCINFO file for a reliable online pkg update reference
                        cd "$DIR/packages/$GITDIR/$p" || exit                                       # go to current package directory
                    fi
                fi

                LOCALPKGVER=$(cat .SRCINFO | grep 'pkgver =' | cut -c 11-)
                LOCALPKGREL=$(cat .SRCINFO | grep 'pkgrel =' | cut -c 11-)
                GETPKGVER=$(cat "$ONLINESRCDIR"/.SRCINFO | grep 'pkgver =' | cut -c 11-)
                GETPKGREL=$(cat "$ONLINESRCDIR"/.SRCINFO | grep 'pkgrel =' | cut -c 11-)
                SHA512LOCAL=$(sha512sum PKGBUILD | cut -f 1 -d " ")
                SHA512ONLINE=$(sha512sum "$ONLINESRCDIR/original/PKGBUILD" | cut -f 1 -d " ")

                echo -e "\e[1m⚿ local  version: $LOCALPKGVER-$LOCALPKGREL\e[0m"
                echo -e "\e[1m⚿ online version: $GETPKGVER-$GETPKGREL\e[0m"
            fi
        fi

        # Check if it's a Git Package before updating
        gitfile=.gitcheck
        if [ -e "PKGBUILD" ]; then # If file exists
            if [ -e "$gitfile" ]; then
                if grep -qE -- '-git$' "$gitfile" 2>/dev/null; then # If result matches (Name has a -git string)
                    # Find "-git" package source
                    gitpkg_src_check
                    # Check if a gitlog has been created
                    if [ -f ".gitversioncheck" ]; then # If file exists
                        git fetch origin &>/dev/null
                        gitversionfile1=.gitversioncheck1
                        gitversioncheck1="$(git show | head -1 | tee "$gitversionfile1")"
                        if [[ -n "$gitversioncheck1" ]]; then
                            if [[ "$(cat "$gitversionfile1")" == "$(cat ".gitversioncheck")" ]]; then
                                cd "$DIR/packages/$GITDIR/$p" || exit
                                echo -e "\e[2m🗹 Up-to-Date\e[0m"
                                rm -rf .onlinepkgbuild &>/dev/null
                                return 1
                            fi
                        fi
                    else
                        # Create a gitlog to check for updates
                        gitversionfile=.gitversioncheck
                        gitversioncheck="$(git show | head -1 | tee "$gitversionfile")"
                        # Generate a gitcheck file for a update reference
                        if [[ -n "$gitversioncheck" ]]; then
                            cd "$DIR/packages/$GITDIR/$p" || exit
                            echo -e "\e[2m🗹 Up-to-Date\e[0m"
                            rm -rf .onlinepkgbuild &>/dev/null
                            return 1
                        fi
                    fi
                fi
            fi
        fi

        # Check which update method is selected
        if [ "$UPDCHECK" == "2" ] && [ -e "PKGBUILD" ] && [ "$GETPKGVER" == "$LOCALPKGVER" ] && [ "$GETPKGREL" == "$LOCALPKGREL" ] && [ "$SHA512LOCAL" == "$SHA512ONLINE" ]; then # If PKGBUILD exists, "pkgver" + "pkgrel" and SHA-512 sums match
            echo -e "\e[2m🗹 Up-to-Date\e[0m"
            rm -rf "$ONLINEPKGBUILD" &>/dev/null
        elif [ "$UPDCHECK" == "1" ] && [ -e "PKGBUILD" ] && [ "$GETPKGVER" == "$LOCALPKGVER" ] && [ "$GETPKGREL" == "$LOCALPKGREL" ] && [ "$SHA512LOCAL" == "$SHA512ONLINE" ]; then # If PKGBUILD exists, "pkgver" + "pkgrel" and SHA-512 sums match
            echo -e "\e[2m🗹 Up-to-Date\e[0m"
            rm -rf "$ONLINEPKGBUILD" &>/dev/null
        else

            echo -e "\e[7mOut-of-Date! Updating ...\e[0m"
            cd "$DIR/packages/$GITDIR/$p" || exit

            onlinecheck
            git fetch origin &>/dev/null
            git checkout origin/"$BRANCH" &>/dev/null
            git reset --hard origin/"$BRANCH" # reset files to how they were before
            git clean -f -d                   # clear any other changes you've done
            buildoptions
            # Check if it's a Git Package to create a log for updating
            cd "$DIR/packages/$GITDIR/$p" || exit
            gitfile=.gitcheck
            gitcheck="$(echo "$p" | tee "$gitfile")"
            if [ -n "$gitcheck" ]; then
            if grep -qE -- '-git$' "$gitfile" 2>/dev/null; then # If result matches (Name has a -git string)
                makepkg --nobuild
                makepkg --verifysource
                makepkg --printsrcinfo >.SRCINFO
                # Find "-git" package source
                gitpkg_src_check
                # Create a gitlog to check for updates
                gitversionfile=.gitversioncheck
                gitversioncheck="$(git show | head -1 | tee "$gitversionfile")"
                # Generate a gitcheck file for a update reference
                if [[ -n "$gitversioncheck" ]]; then
                    cd "$DIR/packages/$GITDIR/$p" || exit
                    rm -rf .onlinepkgbuild &>/dev/null
                    return 1
                fi
            fi
            rm -rf "$gitfile" &>/dev/null
        fi
        fi
    else

        echo "Package does not exist local, downloading ..."

        onlinecheck
        mkdir -p "$DIR/packages/$GITDIR/$p" && cd "$DIR/packages/$GITDIR/$p" || exit
        git clone --single-branch --branch "$BRANCH" "$GITHUBCLONEURL""$p".git
        folder="$(ls)"
        echo "$folder"
        mv "$folder" original &>/dev/null
        cd original || exit
        ls
        mv -- * .* "$DIR/packages/$GITDIR/$p" 2>/dev/null || true
        cd "$DIR/packages/$GITDIR/$p" || exit
        rm -rf original &>/dev/null
        mkdir -p "$DIR/$GITHUBBINARY"
        buildoptions
        # Check if it's a Git Package to create a log for updating
        cd "$DIR/packages/$GITDIR/$p" || exit
        gitfile=.gitcheck
        gitcheck="$(echo "$p" | tee "$gitfile")"
        if [ -n "$gitcheck" ]; then
            if grep -qE -- '-git$' "$gitfile" 2>/dev/null; then # If result matches (Name has a -git string)
                makepkg --nobuild
                makepkg --verifysource
                makepkg --printsrcinfo >.SRCINFO
                # Find "-git" package source
                gitpkg_src_check
                # Create a gitlog to check for updates
                gitversionfile=.gitversioncheck
                gitversioncheck="$(git show | head -1 | tee "$gitversionfile")"
                # Generate a gitcheck file for a update reference
                if [[ -n "$gitversioncheck" ]]; then
                    cd "$DIR/packages/$GITDIR/$p" || exit
                    rm -rf .onlinepkgbuild &>/dev/null
                    return 1
                fi
            fi
            rm -rf "$gitfile" &>/dev/null
        fi
    fi
}
#

# Function for checked and failed to build packages
function checked_and_failed_pkgs() {
    printf '%s\n' "$p" | tee -a "$CHECKEDPKGS" &>/dev/null # Checked Packages
    if [ "$failedbuild" == "1" ]; then
        printf '%s\n' "$p"-["$GITHUBBINARY"] | tee -a "$FAILEDPKGS" &>/dev/null # Failed to build packages
        failedbuild=0
    fi
}
# Update, install, build packages from Github repos with available PKGBUILD
function githubversion() {
    while IFS="" read -r p || [ -n "$p" ]; do
        case "$p" in "" | \#*) continue ;; esac # Skip empty lines and lines that start with "#"
        echo ""
        cd "$DIR" || exit
        printf '\e[1;36m%s\e[m\n' "𝌤 $p" # Print package list entry
        GITHUBCLONEURL="$GITHUBCLONEURLC"
        GITHUBURL="${GITHUBURLC}${p}/${BRANCH}/PKGBUILD"
        GITDIR=Github1
        maincheck
        if [ "$setrepoadd" == "1" ]; then
            setrepoaddgithub1=1
            setrepoadd=0
            printf '%s\n' "$p"-["$GITHUBBINARY"] | tee -a "$COMPILEDPKGS" &>/dev/null # Compiled packages
        fi
        # Function for checked and failed to build packages
        checked_and_failed_pkgs
    done <"$GITHUBSOURCE" #< $GITHUBSOURCE1
}
#
# Additional Custom Github repo
# Update, install, build packages from Github repos with available PKGBUILD
function githubversioncustom() {
    while IFS="" read -r p || [ -n "$p" ]; do
        case "$p" in "" | \#*) continue ;; esac
        echo ""
        cd "$DIR" || exit
        printf '\e[1;36m%s\e[m\n' "𝌤 $p" # Print package list entry
        GITHUBBINARY=$GITHUBBINARYCUSTOM
        local BRANCH=$BRANCHCUSTOM
        GITHUBCLONEURL=$GITHUBCLONEURLCCUSTOM
        GITHUBURL="${GITHUBURLCCUSTOM}${p}/${BRANCHCUSTOM}/PKGBUILD"
        GITDIR=Github2
        maincheck
        if [ "$setrepoadd" == "1" ]; then
            setrepoaddgithub2=1
            setrepoadd=0
            printf '%s\n' "$p"-["$GITHUBBINARY"] | tee -a "$COMPILEDPKGS" &>/dev/null
        fi
        # Function for checked and failed to build packages
        checked_and_failed_pkgs
    done <"$GITHUBSOURCECUSTOM" #< $GITHUBSOURCE1
}
#
# Additional Custom Github repo
# Update, install, build packages from Github repos with available PKGBUILD
function githubversioncustom2() {
    while IFS="" read -r p || [ -n "$p" ]; do
        case "$p" in "" | \#*) continue ;; esac
        echo ""
        cd "$DIR" || exit
        printf '\e[1;36m%s\e[m\n' "𝌤 $p" # Print package list entry
        GITHUBBINARY=$GITHUBBINARYCUSTOM2
        local BRANCH=$BRANCHCUSTOM2
        GITHUBCLONEURL=$GITHUBCLONEURLCCUSTOM2
        GITHUBURL="${GITHUBURLCCUSTOM2}${p}/${BRANCHCUSTOM2}/PKGBUILD"
        GITDIR=Github3
        maincheck
        if [ "$setrepoadd" == "1" ]; then
            setrepoaddgithub3=1
            setrepoadd=0
            printf '%s\n' "$p"-["$GITHUBBINARY"] | tee -a "$COMPILEDPKGS" &>/dev/null
        fi
        # Function for checked and failed to build packages
        checked_and_failed_pkgs
    done <"$GITHUBSOURCECUSTOM2" #< $GITHUBSOURCE1
}
#
# Additional Custom Github repo
# Update, install, build packages from Github repos with available PKGBUILD
function githubversioncustom3() {
    while IFS="" read -r p || [ -n "$p" ]; do
        case "$p" in "" | \#*) continue ;; esac
        echo ""
        cd "$DIR" || exit
        printf '\e[1;36m%s\e[m\n' "𝌤 $p" # Print package list entry
        GITHUBBINARY=$GITHUBBINARYCUSTOM3
        local BRANCH=$BRANCHCUSTOM3
        GITHUBCLONEURL=$GITHUBCLONEURLCCUSTOM3
        GITHUBURL="${GITHUBURLCCUSTOM3}${p}/${BRANCHCUSTOM3}/PKGBUILD"
        GITDIR=Github4
        maincheck
        if [ "$setrepoadd" == "1" ]; then
            setrepoaddgithub4=1
            setrepoadd=0
            printf '%s\n' "$p"-["$GITHUBBINARY"] | tee -a "$COMPILEDPKGS" &>/dev/null
        fi
        # Function for checked and failed to build packages
        checked_and_failed_pkgs
    done <"$GITHUBSOURCECUSTOM3" #< $GITHUBSOURCE1
}
#
# Additional Custom Github repo
# Update, install, build packages from Github repos with available PKGBUILD
function githubversioncustom4() {
    while IFS="" read -r p || [ -n "$p" ]; do
        case "$p" in "" | \#*) continue ;; esac
        echo ""
        cd "$DIR" || exit
        printf '\e[1;36m%s\e[m\n' "𝌤 $p" # Print package list entry
        GITHUBBINARY=$GITHUBBINARYCUSTOM4
        local BRANCH=$BRANCHCUSTOM4
        GITHUBCLONEURL=$GITHUBCLONEURLCCUSTOM4
        GITHUBURL="${GITHUBURLCCUSTOM4}${p}/${BRANCHCUSTOM4}/PKGBUILD"
        GITDIR=Github5
        maincheck
        if [ "$setrepoadd" == "1" ]; then
            setrepoaddgithub5=1
            setrepoadd=0
            printf '%s\n' "$p"-["$GITHUBBINARY"] | tee -a "$COMPILEDPKGS" &>/dev/null
        fi
        # Function for checked and failed to build packages
        checked_and_failed_pkgs
    done <"$GITHUBSOURCECUSTOM4" #< $GITHUBSOURCE1
}
#
# Additional Custom Github repo
# Update, install, build packages from Github repos with available PKGBUILD
function githubversioncustom5() {
    while IFS="" read -r p || [ -n "$p" ]; do
        case "$p" in "" | \#*) continue ;; esac
        echo ""
        cd "$DIR" || exit
        printf '\e[1;36m%s\e[m\n' "𝌤 $p" # Print package list entry
        GITHUBBINARY=$GITHUBBINARYCUSTOM5
        local BRANCH=$BRANCHCUSTOM5
        GITHUBCLONEURL=$GITHUBCLONEURLCCUSTOM5
        GITHUBURL="${GITHUBURLCCUSTOM5}${p}/${BRANCHCUSTOM5}/PKGBUILD"
        GITDIR=Github6
        maincheck
        if [ "$setrepoadd" == "1" ]; then
            setrepoaddgithub6=1
            setrepoadd=0
            printf '%s\n' "$p"-["$GITHUBBINARY"] | tee -a "$COMPILEDPKGS" &>/dev/null
        fi
        # Function for checked and failed to build packages
        checked_and_failed_pkgs
    done <"$GITHUBSOURCECUSTOM5" #< $GITHUBSOURCE1
}
#
# Additional Gitlab repo
# Update, install, build packages from Gitlab repos with available PKGBUILD
function gitlabversion() {
    while IFS="" read -r p || [ -n "$p" ]; do
        case "$p" in "" | \#*) continue ;; esac
        echo ""
        cd "$DIR" || exit
        printf '\e[1;36m%s\e[m\n' "𝌤 $p" # Print package list entry
        GITHUBBINARY=$GITLABBINARY
        local BRANCH=$BRANCHGITLAB
        GITHUBCLONEURL=$GITLABCLONEURL
        GITHUBURL="${GITLABURLC}${p}/-/raw/${BRANCHGITLAB}/PKGBUILD"
        GITDIR=Gitlab1
        maincheck
        if [ "$setrepoadd" == "1" ]; then
            setrepoaddgitlab1=1
            setrepoadd=0
            printf '%s\n' "$p"-["$GITHUBBINARY"] | tee -a "$COMPILEDPKGS" &>/dev/null
        fi
        # Function for checked and failed to build packages
        checked_and_failed_pkgs
    done <"$GITLABSOURCE" #< $GITHUBSOURCE1
}
#
# Additional Custom Gitlab repo
# Update, install, build packages from Gitlab repos with available PKGBUILD
function gitlabversioncustom() {
    while IFS="" read -r p || [ -n "$p" ]; do
        case "$p" in "" | \#*) continue ;; esac
        echo ""
        cd "$DIR" || exit
        printf '\e[1;36m%s\e[m\n' "𝌤 $p" # Print package list entry
        GITHUBBINARY=$GITLABBINARYCUSTOM
        local BRANCH=$BRANCHGITLABCUSTOM
        GITHUBCLONEURL=$GITLABCLONEURLCUSTOM
        GITHUBURL="${GITLABURLCCUSTOM}${p}/-/raw/${BRANCHGITLABCUSTOM}/PKGBUILD"
        GITDIR=Gitlab2
        maincheck
        if [ "$setrepoadd" == "1" ]; then
            setrepoaddgitlab2=1
            setrepoadd=0
            printf '%s\n' "$p"-["$GITHUBBINARY"] | tee -a "$COMPILEDPKGS" &>/dev/null
        fi
        # Function for checked and failed to build packages
        checked_and_failed_pkgs
    done <"$GITLABSOURCECUSTOM" #< $GITHUBSOURCE1
}
#
# Additional Custom Gitlab repo extra 2
# Update, install, build packages from Gitlab repos with available PKGBUILD
function gitlabversioncustom2() {
    while IFS="" read -r p || [ -n "$p" ]; do
        case "$p" in "" | \#*) continue ;; esac
        echo ""
        cd "$DIR" || exit
        printf '\e[1;36m%s\e[m\n' "𝌤 $p" # Print package list entry
        GITHUBBINARY=$GITLABBINARYCUSTOM2
        local BRANCH=$BRANCHGITLABCUSTOM2
        GITHUBCLONEURL=$GITLABCLONEURLCUSTOM2
        GITHUBURL="${GITLABURLCCUSTOM2}${p}/-/raw/${BRANCHGITLABCUSTOM2}/PKGBUILD"
        GITDIR=Gitlab3
        maincheck
        if [ "$setrepoadd" == "1" ]; then
            setrepoaddgitlab3=1
            setrepoadd=0
            printf '%s\n' "$p"-["$GITHUBBINARY"] | tee -a "$COMPILEDPKGS" &>/dev/null
        fi
        # Function for checked and failed to build packages
        checked_and_failed_pkgs
    done <"$GITLABSOURCECUSTOM2" #< $GITHUBSOURCE1
}
#
# Additional Custom Gitlab repo extra 3
# Update, install, build packages from Gitlab repos with available PKGBUILD
function gitlabversioncustom3() {
    while IFS="" read -r p || [ -n "$p" ]; do
        case "$p" in "" | \#*) continue ;; esac
        echo ""
        cd "$DIR" || exit
        printf '\e[1;36m%s\e[m\n' "𝌤 $p" # Print package list entry
        GITHUBBINARY=$GITLABBINARYCUSTOM3
        local BRANCH=$BRANCHGITLABCUSTOM3
        GITHUBCLONEURL=$GITLABCLONEURLCUSTOM3
        GITHUBURL="${GITLABURLCCUSTOM3}${p}/-/raw/${BRANCHGITLABCUSTOM3}/PKGBUILD"
        GITDIR=Gitlab4
        maincheck
        if [ "$setrepoadd" == "1" ]; then
            setrepoaddgitlab4=1
            setrepoadd=0
            printf '%s\n' "$p"-["$GITHUBBINARY"] | tee -a "$COMPILEDPKGS" &>/dev/null
        fi
        # Function for checked and failed to build packages
        checked_and_failed_pkgs
    done <"$GITLABSOURCECUSTOM3" #< $GITHUBSOURCE1
}
#
#
# Additional Custom Gitlab repo extra 3
# Update, install, build packages from Gitlab repos with available PKGBUILD
function gitlabversioncustom4() {
    while IFS="" read -r p || [ -n "$p" ]; do
        case "$p" in "" | \#*) continue ;; esac
        echo ""
        cd "$DIR" || exit
        printf '\e[1;36m%s\e[m\n' "𝌤 $p" # Print package list entry
        GITHUBBINARY=$GITLABBINARYCUSTOM4
        local BRANCH=$BRANCHGITLABCUSTOM4
        GITHUBCLONEURL=$GITLABCLONEURLCUSTOM4
        GITHUBURL="${GITLABURLCCUSTOM4}${p}/-/raw/${BRANCHGITLABCUSTOM4}/PKGBUILD"
        GITDIR=Gitlab5
        maincheck
        if [ "$setrepoadd" == "1" ]; then
            setrepoaddgitlab5=1
            setrepoadd=0
            printf '%s\n' "$p"-["$GITHUBBINARY"] | tee -a "$COMPILEDPKGS" &>/dev/null
        fi
        # Function for checked and failed to build packages
        checked_and_failed_pkgs
    done <"$GITLABSOURCECUSTOM4" #< $GITHUBSOURCE1
}
#
#
# Additional Custom Gitlab repo extra 3
# Update, install, build packages from Gitlab repos with available PKGBUILD
function gitlabversioncustom5() {
    while IFS="" read -r p || [ -n "$p" ]; do
        case "$p" in "" | \#*) continue ;; esac
        echo ""
        cd "$DIR" || exit
        printf '\e[1;36m%s\e[m\n' "𝌤 $p" # Print package list entry
        GITHUBBINARY=$GITLABBINARYCUSTOM5
        local BRANCH=$BRANCHGITLABCUSTOM5
        GITHUBCLONEURL=$GITLABCLONEURLCUSTOM5
        GITHUBURL="${GITLABURLCCUSTOM5}${p}/-/raw/${BRANCHGITLABCUSTOM5}/PKGBUILD"
        GITDIR=Gitlab6
        maincheck
        if [ "$setrepoadd" == "1" ]; then
            setrepoaddgitlab6=1
            setrepoadd=0
            printf '%s\n' "$p"-["$GITHUBBINARY"] | tee -a "$COMPILEDPKGS" &>/dev/null
        fi
        # Function for checked and failed to build packages
        checked_and_failed_pkgs
    done <"$GITLABSOURCECUSTOM5" #< $GITHUBSOURCE1
}
#
# Additional AUR repo
# Update, install, build packages from AUR
function aur() {
    while IFS="" read -r p || [ -n "$p" ]; do
        case "$p" in "" | \#*) continue ;; esac
        echo ""
        cd "$DIR" || exit
        printf '\e[1;36m%s\e[m\n' "𝌤 $p" # Print package list entry
        GITHUBBINARY=$AURBINARY
        local BRANCH=master
        GITHUBURL="${AURCLONEURL}${p}"
        GITHUBCLONEURL="$AURURL"
        GITDIR=AUR
        maincheck
        if [ "$setrepoadd" == "1" ]; then
            setrepoaddaur=1
            setrepoadd=0
            printf '%s\n' "$p"-["$GITHUBBINARY"] | tee -a "$COMPILEDPKGS" &>/dev/null
        fi
        # Function for checked and failed to build packages
        checked_and_failed_pkgs
    done <"$AURSOURCE" #< $GITHUBSOURCE1
}
#
# Run the script once
function manualsync() {

    clear

    local out

    setreposync=0

    # Clear per-pass counters left behind by an interrupted previous run
    rm -rf "$CHECKEDPKGS" "$COMPILEDPKGS" "$FAILEDPKGS" &>/dev/null

    time {
        if [ "$SETGITHUBREPO" == "1" ]; then
            githubversion
            if [ "$setrepoaddgithub1" == "1" ]; then
                echo ""
                echo -e "$GITHUBMSG"
            fi
            # Local pacman repository update - rename repo to your preference
            if [ "$REPOADD" == "1" ] && [ "$setrepoaddgithub1" == "1" ]; then
                echo -e "\e[1mUpdating Database ...\e[0m"
                if out=$($REPOADDCMD "$DIR"/"$GITHUBBINARY"/"$GITHUBBINARY".db.tar.gz "$DIR"/"$GITHUBBINARY"/*.pkg.* 2>&1); then
                    setrepoaddgithub1=0
                    setreposync=1
                else
                    echo -e "\e[1m\e[31mError: repo-add failed for \"$GITHUBBINARY\":\e[0m"
                    echo "$out"
                fi
            fi
        fi
        if [ "$SETCUSTGITHUBREPO" == "1" ]; then
            githubversioncustom
            if [ "$setrepoaddgithub2" == "1" ]; then
                echo ""
                echo -e "$GITHUBMSGCUST"
            fi
            # Local pacman repository update - rename repo to your preference
            if [ "$REPOADD" == "1" ] && [ "$setrepoaddgithub2" == "1" ]; then
                echo -e "\e[1mUpdating Database ...\e[0m"
                if out=$($REPOADDCMD "$DIR"/"$GITHUBBINARYCUSTOM"/"$GITHUBBINARYCUSTOM".db.tar.gz "$DIR"/"$GITHUBBINARYCUSTOM"/*.pkg.* 2>&1); then
                    setrepoaddgithub2=0
                    setreposync=1
                else
                    echo -e "\e[1m\e[31mError: repo-add failed for \"$GITHUBBINARYCUSTOM\":\e[0m"
                    echo "$out"
                fi
            fi
        fi
        if [ "$SETCUSTGITHUBREPO2" == "1" ]; then
            githubversioncustom2
            if [ "$setrepoaddgithub3" == "1" ]; then
                echo ""
                echo -e "$GITHUBMSGCUST2"
            fi
            # Local pacman repository update - rename repo to your preference
            if [ "$REPOADD" == "1" ] && [ "$setrepoaddgithub3" == "1" ]; then
                echo -e "\e[1mUpdating Database ...\e[0m"
                if out=$($REPOADDCMD "$DIR"/"$GITHUBBINARYCUSTOM2"/"$GITHUBBINARYCUSTOM2".db.tar.gz "$DIR"/"$GITHUBBINARYCUSTOM2"/*.pkg.* 2>&1); then
                    setrepoaddgithub3=0
                    setreposync=1
                else
                    echo -e "\e[1m\e[31mError: repo-add failed for \"$GITHUBBINARYCUSTOM2\":\e[0m"
                    echo "$out"
                fi
            fi
        fi
        if [ "$SETCUSTGITHUBREPO3" == "1" ]; then
            githubversioncustom3
            if [ "$setrepoaddgithub4" == "1" ]; then
                echo ""
                echo -e "$GITHUBMSGCUST3"
            fi
            # Local pacman repository update - rename repo to your preference
            if [ "$REPOADD" == "1" ] && [ "$setrepoaddgithub4" == "1" ]; then
                echo -e "\e[1mUpdating Database ...\e[0m"
                if out=$($REPOADDCMD "$DIR"/"$GITHUBBINARYCUSTOM3"/"$GITHUBBINARYCUSTOM3".db.tar.gz "$DIR"/"$GITHUBBINARYCUSTOM3"/*.pkg.* 2>&1); then
                    setrepoaddgithub4=0
                    setreposync=1
                else
                    echo -e "\e[1m\e[31mError: repo-add failed for \"$GITHUBBINARYCUSTOM3\":\e[0m"
                    echo "$out"
                fi
            fi
        fi
        if [ "$SETCUSTGITHUBREPO4" == "1" ]; then
            githubversioncustom4
            if [ "$setrepoaddgithub5" == "1" ]; then
                echo ""
                echo -e "$GITHUBMSGCUST4"
            fi
            # Local pacman repository update - rename repo to your preference
            if [ "$REPOADD" == "1" ] && [ "$setrepoaddgithub5" == "1" ]; then
                echo -e "\e[1mUpdating Database ...\e[0m"
                if out=$($REPOADDCMD "$DIR"/"$GITHUBBINARYCUSTOM4"/"$GITHUBBINARYCUSTOM4".db.tar.gz "$DIR"/"$GITHUBBINARYCUSTOM4"/*.pkg.* 2>&1); then
                    setrepoaddgithub5=0
                    setreposync=1
                else
                    echo -e "\e[1m\e[31mError: repo-add failed for \"$GITHUBBINARYCUSTOM4\":\e[0m"
                    echo "$out"
                fi
            fi
        fi
        if [ "$SETCUSTGITHUBREPO5" == "1" ]; then
            githubversioncustom5
            if [ "$setrepoaddgithub6" == "1" ]; then
                echo ""
                echo -e "$GITHUBMSGCUST5"
            fi
            # Local pacman repository update - rename repo to your preference
            if [ "$REPOADD" == "1" ] && [ "$setrepoaddgithub6" == "1" ]; then
                echo -e "\e[1mUpdating Database ...\e[0m"
                if out=$($REPOADDCMD "$DIR"/"$GITHUBBINARYCUSTOM5"/"$GITHUBBINARYCUSTOM5".db.tar.gz "$DIR"/"$GITHUBBINARYCUSTOM5"/*.pkg.* 2>&1); then
                    setrepoaddgithub6=0
                    setreposync=1
                else
                    echo -e "\e[1m\e[31mError: repo-add failed for \"$GITHUBBINARYCUSTOM5\":\e[0m"
                    echo "$out"
                fi
            fi
        fi
        if [ "$SETGITLABREPO" == "1" ]; then
            gitlabversion
            if [ "$setrepoaddgitlab1" == "1" ]; then
                echo ""
                echo -e "$GITLABMSG"
            fi
            # Local pacman repository update - rename repo to your preference
            if [ "$REPOADD" == "1" ] && [ "$setrepoaddgitlab1" == "1" ]; then
                echo -e "\e[1mUpdating Database ...\e[0m"
                if out=$($REPOADDCMD "$DIR"/"$GITLABBINARY"/"$GITLABBINARY".db.tar.gz "$DIR"/"$GITLABBINARY"/*.pkg.* 2>&1); then
                    setrepoaddgitlab1=0
                    setreposync=1
                else
                    echo -e "\e[1m\e[31mError: repo-add failed for \"$GITLABBINARY\":\e[0m"
                    echo "$out"
                fi
            fi
        fi
        if [ "$SETGITLABREPOCUSTOM" == "1" ]; then
            gitlabversioncustom
            if [ "$setrepoaddgitlab2" == "1" ]; then
                echo ""
                echo -e "$GITLABMSGCUST"
            fi
            # Local pacman repository update - rename repo to your preference
            if [ "$REPOADD" == "1" ] && [ "$setrepoaddgitlab2" == "1" ]; then
                echo -e "\e[1mUpdating Database ...\e[0m"
                if out=$($REPOADDCMD "$DIR"/"$GITLABBINARYCUSTOM"/"$GITLABBINARYCUSTOM".db.tar.gz "$DIR"/"$GITLABBINARYCUSTOM"/*.pkg.* 2>&1); then
                    setrepoaddgitlab2=0
                    setreposync=1
                else
                    echo -e "\e[1m\e[31mError: repo-add failed for \"$GITLABBINARYCUSTOM\":\e[0m"
                    echo "$out"
                fi
            fi
        fi
        if [ "$SETGITLABREPOCUSTOM2" == "1" ]; then
            gitlabversioncustom2
            if [ "$setrepoaddgitlab3" == "1" ]; then
                echo ""
                echo -e "$GITLABMSGCUST2"
            fi
            # Local pacman repository update - rename repo to your preference
            if [ "$REPOADD" == "1" ] && [ "$setrepoaddgitlab3" == "1" ]; then
                echo -e "\e[1mUpdating Database ...\e[0m"
                if out=$($REPOADDCMD "$DIR"/"$GITLABBINARYCUSTOM2"/"$GITLABBINARYCUSTOM2".db.tar.gz "$DIR"/"$GITLABBINARYCUSTOM2"/*.pkg.* 2>&1); then
                    setrepoaddgitlab3=0
                    setreposync=1
                else
                    echo -e "\e[1m\e[31mError: repo-add failed for \"$GITLABBINARYCUSTOM2\":\e[0m"
                    echo "$out"
                fi
            fi
        fi
        if [ "$SETGITLABREPOCUSTOM3" == "1" ]; then
            gitlabversioncustom3
            if [ "$setrepoaddgitlab4" == "1" ]; then
                echo ""
                echo -e "$GITLABMSGCUST3"
            fi
            # Local pacman repository update - rename repo to your preference
            if [ "$REPOADD" == "1" ] && [ "$setrepoaddgitlab4" == "1" ]; then
                echo -e "\e[1mUpdating Database ...\e[0m"
                if out=$($REPOADDCMD "$DIR"/"$GITLABBINARYCUSTOM3"/"$GITLABBINARYCUSTOM3".db.tar.gz "$DIR"/"$GITLABBINARYCUSTOM3"/*.pkg.* 2>&1); then
                    setrepoaddgitlab4=0
                    setreposync=1
                else
                    echo -e "\e[1m\e[31mError: repo-add failed for \"$GITLABBINARYCUSTOM3\":\e[0m"
                    echo "$out"
                fi
            fi
        fi
        if [ "$SETGITLABREPOCUSTOM4" == "1" ]; then
            gitlabversioncustom4
            if [ "$setrepoaddgitlab5" == "1" ]; then
                echo ""
                echo -e "$GITLABMSGCUST4"
            fi
            # Local pacman repository update - rename repo to your preference
            if [ "$REPOADD" == "1" ] && [ "$setrepoaddgitlab5" == "1" ]; then
                echo -e "\e[1mUpdating Database ...\e[0m"
                if out=$($REPOADDCMD "$DIR"/"$GITLABBINARYCUSTOM4"/"$GITLABBINARYCUSTOM4".db.tar.gz "$DIR"/"$GITLABBINARYCUSTOM4"/*.pkg.* 2>&1); then
                    setrepoaddgitlab5=0
                    setreposync=1
                else
                    echo -e "\e[1m\e[31mError: repo-add failed for \"$GITLABBINARYCUSTOM4\":\e[0m"
                    echo "$out"
                fi
            fi
        fi
        if [ "$SETGITLABREPOCUSTOM5" == "1" ]; then
            gitlabversioncustom5
            if [ "$setrepoaddgitlab6" == "1" ]; then
                echo ""
                echo -e "$GITLABMSGCUST5"
            fi
            # Local pacman repository update - rename repo to your preference
            if [ "$REPOADD" == "1" ] && [ "$setrepoaddgitlab6" == "1" ]; then
                echo -e "\e[1mUpdating Database ...\e[0m"
                if out=$($REPOADDCMD "$DIR"/"$GITLABBINARYCUSTOM5"/"$GITLABBINARYCUSTOM5".db.tar.gz "$DIR"/"$GITLABBINARYCUSTOM5"/*.pkg.* 2>&1); then
                    setrepoaddgitlab6=0
                    setreposync=1
                else
                    echo -e "\e[1m\e[31mError: repo-add failed for \"$GITLABBINARYCUSTOM5\":\e[0m"
                    echo "$out"
                fi
            fi
        fi
        if [ "$AURREPO" == "1" ]; then
            aur
            if [ "$setrepoaddaur" == "1" ]; then
                echo ""
                echo -e "$AURMSG"
            fi
            # Local pacman repository update - rename repo to your preference
            if [ "$REPOADD" == "1" ] && [ "$setrepoaddaur" == "1" ]; then
                echo -e "\e[1mUpdating Database ...\e[0m"
                if out=$($REPOADDCMD "$DIR"/"$AURBINARY"/"$AURBINARY".db.tar.gz "$DIR"/"$AURBINARY"/*.pkg.* 2>&1); then
                    setrepoaddaur=0
                    setreposync=1
                else
                    echo -e "\e[1m\e[31mError: repo-add failed for \"$AURBINARY\":\e[0m"
                    echo "$out"
                fi
            fi
        fi
        # Print output summary
        if [ -e "$CHECKEDPKGS" ]; then
            echo ""
            checked=$(cat "$CHECKEDPKGS" | wc -l)
            echo -e "     \e[3m🗱  Checked Package(s): $checked\e[0m"
            rm -rf "$CHECKEDPKGS" &>/dev/null
        fi
        if [ -e "$COMPILEDPKGS" ]; then
            checked=$(cat "$COMPILEDPKGS" | wc -l)
            echo -e "     \e[3m🗱  Compiled Package(s): $checked\e[0m"
            cat -b "$COMPILEDPKGS"
            rm -rf "$COMPILEDPKGS" &>/dev/null
        fi
        if [ -e "$FAILEDPKGS" ]; then
            checked=$(cat "$FAILEDPKGS" | wc -l)
            echo -e "     \e[3m🗱  Failed to Build: $checked\e[0m"
            cat -b "$FAILEDPKGS"
            rm -rf "$FAILEDPKGS" &>/dev/null
        fi
        # Run repo-sync if enabled
        repo_rsync
        echo ""
        echo -e "\e[1m Elapsed Time: \e[0m"
    }
}
#
# Run the script in a loop
function main() {
    while true; do
        manualsync
        echo ""
        echo -e "\e[1mPress \e[7m[Ctrl]\e[0m+\e[1m\e[7m[C]\e[0m \e[1mto stop \e[3mautogit\e[0m"
        countdown() {
            secs=$timer
            shift
            while [ "$secs" -gt 0 ]; do
                printf "\r\033[KWaiting %.d seconds for next sync ..." $((secs--))
                sleep 1
            done
            echo
        }
        countdown
        sleep 1
    done
    # close while-loop
}
#
# Select the source to edit for the fzf menu
function pkgchooser() {
    # Check if -e (edit) is run for a different text
    if [ "$edit" == "1" ]; then
        # shellcheck disable=SC2120
        editfzf() {
            cd "$DIR"/reponames || exit
            files=()
            while IFS= read -r -d '' file; do
                files+=("$file")
            done < <(ls "$DIR"/reponames | fzf -i --reverse --info=inline --prompt="Enter string > " --header="    ENTER to edit package(s)
    from selected source file(s). 
    ESC to quit." --preview "cat $DIR/reponames/{}" --no-unicode "$(if (($(tput cols) >= 80)); then echo "--preview-window=right:55%:wrap"; else echo "--preview-window=bottom:60%:wrap"; fi)" --multi --print0)

            ((${#files})) || return
            "${VISUAL:-${EDITOR:-vi}}" "$@" "${files[@]}"
        }
        editfzf
    else
        # Check if -d (DRY RUN) is run for a different text
        if [ "$dryrun" == "1" ]; then
            # Select the source to edit
            ls "$DIR"/reponames | fzf -i --reverse --info=inline --prompt="Enter string > " --header="    ENTER to remove package(s)
    from selected source file.
    ESC to quit. [DRY RUN] " --preview "cat $DIR/reponames/{}" --no-unicode "$(if (($(tput cols) >= 80)); then echo "--preview-window=right:55%:wrap"; else echo "--preview-window=bottom:60%:wrap"; fi)" | xargs -ro >"$DIR"/reponames/.selected.txt
        else
            # Check if -b (REBUILD) is run for a different text
            if [ "$rebuild" == "1" ]; then
                # Select the source to edit
                ls "$DIR"/reponames | fzf -i --reverse --info=inline --prompt="Enter string > " --header="    ENTER to rebuild package(s)
    from selected source file.
    ESC to quit. " --preview "cat $DIR/reponames/{}" --no-unicode "$(if (($(tput cols) >= 80)); then echo "--preview-window=right:55%:wrap"; else echo "--preview-window=bottom:60%:wrap"; fi)" | xargs -ro >"$DIR"/reponames/.selected.txt
            else
                # Select the source to edit
                ls "$DIR"/reponames | fzf -i --reverse --info=inline --prompt="Enter string > " --header="    ENTER to remove package(s)
    from selected source file.
    ESC to quit. " --preview "cat $DIR/reponames/{}" --no-unicode "$(if (($(tput cols) >= 80)); then echo "--preview-window=right:55%:wrap"; else echo "--preview-window=bottom:60%:wrap"; fi)" | xargs -ro >"$DIR"/reponames/.selected.txt
            fi
        fi
    fi

    # Open file content to manipulate it
    # Check if -d (DRY RUN) is run for a different text
    if [ "$dryrun" == "1" ]; then
        if [ -s "$DIR"/reponames/.selected.txt ]; then
            GETSELECTED=$(cat "$DIR"/reponames/.selected.txt)
            cat "$DIR"/reponames/"$GETSELECTED" | fzf -i --multi --reverse --info=inline --prompt="Enter string > " --header="    TAB key to (un)select.
    ENTER to remove selected source(s), binary(s)
    and package list entry(s). ESC to quit. [DRY RUN] " | xargs -ro >"$DIR"/reponames/.output.txt
            awk -v ORS='\n' '{ for (i = 1; i <= NF; i++) print $i }' "$DIR"/reponames/.output.txt >"$DIR"/reponames/.toremove.txt

            # Set a start flag for the "removepkgs" function when the second fzf menu has been run
            startflag=1
        fi
    else
        # Open file content to manipulate it
        # Check if -b (REBUILD) is run for a different text
        if [ "$rebuild" == "1" ]; then
            if [ -s "$DIR"/reponames/.selected.txt ]; then
                GETSELECTED=$(cat "$DIR"/reponames/.selected.txt)
                cat "$DIR"/reponames/"$GETSELECTED" | fzf -i --multi --reverse --info=inline --prompt="Enter string > " --header="    TAB key to (un)select.
    ENTER to rebuild selected package(s)
    ESC to quit. " | xargs -ro >"$DIR"/reponames/.output.txt
                awk -v ORS='\n' '{ for (i = 1; i <= NF; i++) print $i }' "$DIR"/reponames/.output.txt >"$DIR"/reponames/.toremove.txt

                # Set a start flag for the "removepkgs" function when the second fzf menu has been run
                startflag=1
            fi
        else
            # Open file content to manipulate it
            if [ -s "$DIR"/reponames/.selected.txt ]; then
                GETSELECTED=$(cat "$DIR"/reponames/.selected.txt)
                cat "$DIR"/reponames/"$GETSELECTED" | fzf -i --multi --reverse --info=inline --prompt="Enter string > " --header="    TAB key to (un)select.
    ENTER to remove selected source(s), binary(s)
    and package list entry(s). ESC to quit. " | xargs -ro >"$DIR"/reponames/.output.txt
                awk -v ORS='\n' '{ for (i = 1; i <= NF; i++) print $i }' "$DIR"/reponames/.output.txt >"$DIR"/reponames/.toremove.txt

                # Set a start flag for the "removepkgs" function when the second fzf menu has been run
                startflag=1
            fi
        fi
    fi
}

# Remove selected package(s)
function removepkgs() {
    local out

    clear
    while IFS="" read -r p || [ -n "$p" ]; do
        echo ""
        cd "$DIR" || exit
        printf '\e[1;36m%s %s\e[m\n' "𝌤" "$p" # Print package list entry
        # Safely extract source package directory without using eval
        if [[ ! "$GETSELECTED" =~ ^[a-zA-Z0-9_-]+$ ]]; then
            echo >&2 "Error: Invalid package name format"
            exit 1
        fi
        SOURCEPKGDIR=$(awk -v pattern="$GETSELECTED" '$0 ~ pattern && /SOURCE/ {print}' "$DIR/autogit.conf" | grep -E -o ".{0,20}=" | rev | cut -c 2- | rev) # Find Reponame for source folder
        
        # Use array lookup instead of nested if-else
        if [[ -n "${SOURCE_MAP[$SOURCEPKGDIR]}" ]]; then
            IFS=: read -r PKGDIR PKGBIN <<< "${SOURCE_MAP[$SOURCEPKGDIR]}"
        else
            echo >&2 "Error: Unknown source directory $SOURCEPKGDIR"
            exit 1
        fi
        echo """$DIR""/packages/$PKGDIR/""$p""" | tee "$DIR"/reponames/.rm.txt &>/dev/null
        location=$(cat "$DIR"/reponames/.rm.txt) #Source package folder to remove

        if [ "$dryrun" == "1" ]; then
            if [ -e "$location" ]; then # If file exists (source file folder)
                echo -e "\e[1m\e[32m==>\e[0m \e[1mFound Source:\e[0m \e[1m\"$location\"\e[0m"
                echo -e "\e[1m\e[34m  -> Removing Source Folder ...\e[0m"
                echo "Dry Run"
            else
                echo " ⇒ No Package Source Files Found"
                echo "Dry Run"
            fi
        else
            if [ -e "$location" ]; then # If file exists (source file folder)
                echo -e "\e[1m\e[32m==>\e[0m \e[1mFound Source:\e[0m \e[1m\"$location\"\e[0m"
                echo -e "\e[1m\e[34m  -> Removing Source Folder ...\e[0m"
                sourcelocation=1
            else
                echo " ⇒ No Package Source Files Found"
            fi
        fi

        # Find the Filename
        #cd "$DIR/packages/$PKGDIR/$p"
        if [ -e "$location" ]; then # If file exists (source file folder)
            cd "$location" || exit
            #ls
            filename1=$(cat PKGBUILD | grep 'pkgbase=' | cut -c 9-)
            filename2=$(cat PKGBUILD | grep 'pkgname=' | cut -c 9-)
            if [ -n "$filename1" ]; then
                filename=$filename1
                if ls "$DIR"/"$PKGBIN" | grep "$filename*.*" | tee "$DIR"/reponames/.rmbin.txt &>/dev/null; then
                    locationbin=$(cat "$DIR"/reponames/.rmbin.txt)
                    #echo "FILENAME=pkgbase"
                fi
            else
                filename=$filename2
                if ls "$DIR"/"$PKGBIN" | grep "$filename*.*" | tee "$DIR"/reponames/.rmbin.txt &>/dev/null; then
                    locationbin=$(cat "$DIR"/reponames/.rmbin.txt)
                    #echo "FILENAME=pkgname"
                fi
            fi
        fi

        # Delete Binary if exists
        if [ "$dryrun" == "1" ]; then
            if [ -n "$locationbin" ]; then # If file exists (binary folder)
                #echo
                echo -e "\e[1m\e[32m==>\e[0m \e[1mFound Binary:\e[0m"
                echo -e "\e[1m""$locationbin""\e[0m"
                echo -e "\e[1m\e[34m  -> Removing Binary ...\e[0m"
                echo "Dry Run"

                # Run repo-add
                if [ "$REPOADD" == "1" ]; then
                    #echo
                    echo -e "\e[1m\e[32m==>\e[0m \e[1mUpdating Database ...\e[0m"
                    echo -e "\e[1m\e[34m  -> ""$DIR""/""$PKGBIN"" ...\e[0m"
                    echo "Dry Run"
                fi
            fi
        else
            if [ -n "$locationbin" ]; then # If file exists (binary)
                #echo
                echo -e "\e[1m\e[32m==>\e[0m \e[1mFound Binary:\e[0m"
                echo -e "\e[1m""$locationbin""\e[0m"
                echo -e "\e[1m\e[34m  -> Removing Binary ...\e[0m"
                # Remove old database first as repo-add has no option to remove deleted binary's when updating it
                if [[ -n "$PKGBIN" && -d "${DIR}/${PKGBIN}" ]]; then
                    rm -rf "${DIR:?}/${PKGBIN}"/*"${PKGBIN}"* # remove database
                fi
                locationbinn="$locationbin"
                if [[ -n "$PKGBIN" && -n "$locationbinn" && -d "${DIR}/${PKGBIN}" ]]; then
                    rm -rf "${DIR:?}/${PKGBIN}/${locationbinn}" # remove binary
                fi

                # Run repo-add
                if [ "$rebuild" == "1" ]; then
                    echo "rebuild" &>/dev/null
                else
                    if [ "$REPOADD" == "1" ]; then
                        #echo
                        echo -e "\e[1m\e[32m==>\e[0m \e[1mUpdating Database ...\e[0m"
                        echo -e "\e[1m\e[34m  -> ""$DIR""/$PKGBIN ...\e[0m"
                        if ! out=$($REPOADDCMD "$DIR"/"$PKGBIN"/"$PKGBIN".db.tar.gz "$DIR"/"$PKGBIN"/*.pkg.* 2>&1); then
                            echo -e "\e[1m\e[31mError: repo-add failed for \"$PKGBIN\":\e[0m"
                            echo "$out"
                        fi
                    fi
                fi
            fi
        fi
        # remove the source folder here - not before!
        if [ "$sourcelocation" == "1" ] && [[ -n "$location" && -d "$location" ]]; then
            rm -rf "$location"
        fi
        if [ "$dryrun" == "1" ]; then
            echo -e "\e[1m\e[32m==>\e[0m \e[1mRemoving From List: \"$p\"\e[0m"
            echo -e "\e[1m\e[34m  -> \"$DIR/reponames/$GETSELECTED\" ...\e[0m"
            echo "Dry Run"
            echo -e "\e[7m\e[31m<DELETED>\e[0m\e[0m"
        else
            if [ "$rebuild" == "1" ]; then
                echo -e "\e[1mRebuilding ...\e[0m"
                autogitrun=1
                sleep 3
            else
                echo -e "\e[1m\e[32m==>\e[0m \e[1mRemoving From List: \"$p\"\e[0m"
                echo -e "\e[1m\e[34m  -> \"$DIR/reponames/$GETSELECTED\" ...\e[0m"
                grep -v -x -F "$p" "$DIR"/reponames/"$GETSELECTED" >"$DIR"/reponames/.pkglist
                mv "$DIR"/reponames/.pkglist "$DIR"/reponames/"$GETSELECTED"
                echo -e "\e[7m\e[31m<DELETED>\e[0m\e[0m"
            fi
        fi

    done \
        <"$DIR"/reponames/.toremove.txt
}
#
function cleanup() {
    # Clean Up
    rm -rf "$DIR"/reponames/.selected.txt &>/dev/null
    rm -rf "$DIR"/reponames/.output.txt &>/dev/null
    rm -rf "$DIR"/reponames/.toremove.txt &>/dev/null
    rm -rf "$DIR"/reponames/.rm.txt &>/dev/null
    rm -rf "$DIR"/reponames/.rmbin.txt &>/dev/null
}
# Run fzf options
# Flags
while test $# -gt 0; do
    case "$1" in
    -h | --help)
        echo
        echo -e " Welcome to Autogit's Help Page!"
        echo
        echo -e " Autogit runs by default without flags."
        echo -e " In order to run autogit, edit the options in"
        echo -e " \"""$DIR""/autogit.conf\""
        echo
        echo -e " The provided flags will run a fzf UI to manage packages."
        echo
        echo -e " autogit [options]:"
        echo -e ""
        echo -e " -e, --edit        - [EDIT]"
        echo -e "                     Edit Package List Entries (Commenting With '#' Is Supported)"
        echo -e "                     NOTE: Make Sure That The (EDITOR) Environment Variable Is Set On Your System!"
        echo -e ""
        echo -e " -d, --dryrun      - [DRY RUN]"
        echo -e "                     Dry Run To Remove Packages - (Nothing Will Be Touched)"
        echo -e ""
        echo -e " -b, --build       - [REBUILD PACKAGES]"
        echo -e "                     Remove Package Source(s), Binary(s) And Rebuild The Packge(s)"
        echo -e ""
        echo -e " -r, --remove      - [REMOVE PACKAGES]"
        echo -e "                     Remove Package Source(s), Binary(s), Package List Entry(s),"
        echo -e "                     Old Database Files And Run \"repo-add\" If Enabled"
        echo -e ""
        echo -e " -h, --help        - This Help Text"
        echo
        exit
        ;;
    -e | --edit)
        edit=1
        pkgchooser
        cleanup # needs to be run as last because we need to remove files when fzf has been quit with "ESC"
        exit    # this "exit" command is needed to prevent the UI from loading!
        ;;
    -d | --dryrun)
        echo "Dry Run"
        dryrun=1
        pkgchooser
        if [ "$startflag" == "1" ]; then
            removepkgs
        fi
        cleanup # needs to be run as last because we need to remove files when fzf has been quit with "ESC"
        exit    # this "exit" command is needed to prevent the UI from loading!
        ;;
    -b | --build)
        rebuild=1
        pkgchooser
        # pkgchooser runs the whole script
        if [ "$startflag" == "1" ]; then
            removepkgs
            if [ "$autogitrun" == "1" ]; then
                # run autogit
                cd || exit
                autogit
            fi
        fi
        cleanup # needs to be run as last because we need to remove files when fzf has been quit with "ESC"
        exit    # this "exit" command is needed to prevent the UI from loading!
        ;;
    -r | --remove)
        pkgchooser
        if [ "$startflag" == "1" ]; then
            removepkgs
        fi
        cleanup # needs to be run as last because we need to remove files when fzf has been quit with "ESC"
        exit    # this "exit" command is needed to prevent the UI from loading!
        ;;

    *)
        echo -e "Wrong Option, Please run \"autogit -h\""
        exit
        ;;
    esac
done
#
# Sync all enabled repositories to a custom location via "rsync"
function repo_rsync() {
    # Check if the option is enabled
    if [ "$REPOSYNC" == "1" ]; then
        # Define an array with variable names for local repos
        repositories=("$GITHUBBINARY" "$GITHUBBINARYCUSTOM" "$GITHUBBINARYCUSTOM2" "$GITHUBBINARYCUSTOM3" "$GITHUBBINARYCUSTOM4" "$GITHUBBINARYCUSTOM5" "$GITLABBINARY" "$GITLABBINARYCUSTOM" "$GITLABBINARYCUSTOM2" "$GITLABBINARYCUSTOM3" "$GITLABBINARYCUSTOM4" "$GITLABBINARYCUSTOM5" "$AURBINARY")
        declare -A unique_names
        # Loop through the original array
        for name in "${repositories[@]}"; do
            # Check if the name is already in the unique_names array
            if [[ ! "${unique_names[$name]}" ]]; then
                # If not, add it to the unique_names array
                unique_names[$name]=1
            fi
        done
        # Check if the unique names are repositories
        echo ""
        echo -e "Processing \e[1mREPOSYNC\e[0m..."
        for name in "${!unique_names[@]}"; do
            # Perform actions for each name
            cd "$DIR" || exit
            # If destination repo exists
            if [ -e "$DIR"/"$name" ] && [ -e "$REPOPATH"/"$name" ] && [ "$setreposync" == "1" ]; then
                echo ""
                echo -e "Found \"$name\" in \"$REPOPATH"\"
                echo -e "Syncing \e[7m[$name]\e[0m ..."
                if ! $RSYNCCMD "$DIR"/"$name" "$REPOPATH"/; then
                    echo "Failed with user permissions, trying root..."
                    if sudo $RSYNCCMD "$DIR"/"$name" "$REPOPATH"/; then
                        echo -e "Done!"
                    else
                        echo -e "Something went wrong, exit."
                        exit 1
                    fi
                fi
            else
                if [ -e "$DIR"/"$name" ] && [ -e "$REPOPATH"/"$name" ]; then
                    echo ""
                    echo "Found \"$name\" in \"$REPOPATH"\"
                    echo "Next repo-sync on database update!"
                fi
            fi
            # If destination repo does not exist
            if [ -e "$DIR"/"$name" ] && [ ! -d "$REPOPATH"/"$name" ]; then
                echo ""
                echo -e "\"$name\" repository does not exist in \"$REPOPATH"\"
                echo -e "Syncing \e[7m[$name]\e[0m ..."
                if ! $RSYNCCMD "$DIR"/"$name" "$REPOPATH"/; then
                    echo "Failed with user permissions, trying root..."
                    if sudo $RSYNCCMD "$DIR"/"$name" "$REPOPATH"/; then
                        echo -e "Done!"
                    else
                        echo -e "Something went wrong, exit."
                        exit 1
                    fi
                fi
            fi
        done
    fi
}

#
# Start script without flags
function modecheck() {
    # Trap (ctrl-c)
    trap killproc INT

    if [ "$mode" == "1" ]; then
        main
    else
        if [ "$mode" == "2" ]; then
            manualsync
        fi
    fi
    if [ "$newconfig" == "1" ]; then
        clear
        echo ""
        echo -e " \e[1mLocal configuration generated in \e[7m$DIR\e[0m"
        echo ""
        echo -e " \e[1mplease configure \e[7mautogit.conf\e[0m \e[1mfor usage!\e[0m"
        echo ""
    fi
}
modecheck
