#!/bin/bash

#-----------------------------------------------------------------------------
# Name        : slackpkgext
# Description : slackpkg ncurses/gui wrapper
# Author      : Konstantinos Mantzaris <kmanjaris@gmail.com>
# Date        : 01/04/2014
# All rights reserved.
#-----------------------------------------------------------------------------
# Redistribution and use of this script, with or without modification, is
# permitted provided that the following conditions are met:
#
# 1. Redistributions of this script must retain the above copyright
#    notice, this list of conditions and the following disclaimer.
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ''AS IS'' AND ANY EXPRESS OR IMPLIED
# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
# EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#

# Automatically determine the architecture we're on:
if [ -z "$ARCH" ]; then
  case "$( uname -m )" in
    i?86) export ARCH=i486 ;;
    arm*) export ARCH=arm ;;
    # Unless $ARCH is already set, use uname -m for all other archs:
       *) export ARCH=$( uname -m ) ;;
  esac
fi

if [ "$ARCH" = "i486" ]; then
  LIBDIRSUFFIX=""
elif [ "$ARCH" = "i686" ]; then
  LIBDIRSUFFIX=""
elif [ "$ARCH" = "s390" ]; then
  LIBDIRSUFFIX=""
elif [ "$ARCH" = "x86_64" ]; then
  LIBDIRSUFFIX="64"
elif [ "$ARCH" = "arm" ]; then
  LIBDIRSUFFIX="arm"
fi

if [ -f /etc/slackware-version ] ; then
   SLKVER=$(cat /etc/slackware-version | cut -d' ' -f2)
else
   dialog --title "ERROR: slackpkgext" --msgbox "\nCould not find file /etc/slackware-version.\nAborting process..." 8 55
fi

slackpkg__mirror_status() {
    if [ $(cat /etc/slackpkg/mirrors | grep '#' | wc -l) -ge $(grep -v '^$' /etc/slackpkg/mirrors |wc -l) ] ; then
	dialog --title "Processing Error" --msgbox "\nPlease select a mirror using 'Set Repository Mirror'\nand retrieve the latest package records with\n'Get Repository Records Update' before proceeding." 9 58
	exit 1
    fi
    killall slackpkg 2>&1>/dev/null
    rm /var/lock/slackpkg.* 2>&1>/dev/null
    rm -rf /tmp/slackpkg.* 2>&1>/dev/null
}

slackpkg_update_dialog() {
    slackpkg__mirror_status
    TMPPAR=""
    echo "y" | slackpkg update 2>&1 | (while read line ; do
    if [ "$TMPPAR" = "" ] && [[ "$line" =~ "RETR" ]] ; then
	TMPPAR=`echo $line | awk -F' RETR ' '{print $2}' | awk -F' ' '{print $1}'`
	echo "XXX"
	echo " \t"
	echo "\nGetting update file $TMPPAR"
	echo "XXX"
    elif [ "$TMPPAR" = "" ] && [[ "$line" =~ "Saving to" ]] ; then
	TMPPAR=`echo $line | awk -F'/' '{ if($1 ~ /Saving to/) { gsub("\x27","",$4);print $4 } }'`
	echo "XXX"
	echo " \t"
	echo "\nGetting update file $TMPPAR"
	echo "XXX"
    fi
    
    echo $line | awk '/[0-9]K / {print $0}' | awk -F' ' '{ for(i=1;i<=NF;i++) if($i ~ /[0-9]+%/) print $i; }' | awk -F"%" '{print $1}'
    if [ "`echo $line | awk '/[0-9]K / {print $0}' | awk -F' ' '{ for(i=1;i<=NF;i++) if($i ~ /[0-9]+%/) print $i; }' | awk -F"%" '{print $1}'| tr -d '\n'`" = "100" ] ; then TMPPAR="" ; fi
    done) | dialog --title "Updating Records" --gauge "Getting update file:" 8 55 0 ;
}

slackpkg_check_dialog() {
    slackpkg__mirror_status
    TMPFILE=$(mktemp -t slackpkgext.XXXXXX)

    dialog --title "Check Package Availability" --clear \
           --inputbox "\nPlease type the name of a package to check..." 9 55 2> $TMPFILE

    case $? in
    0)
	slackpkg search $(cat $TMPFILE) 2>&1 > $TMPFILE
	if [ ! "$(cat $TMPFILE | grep 'No package name')" = "" ] ; then
	    dialog --title "Check Package Results" --msgbox "\nNo package name matches the search pattern" 7 55
	else
	    VAR=$(cat $TMPFILE |sed '1,4d'|head -n -4|sed 's/\x1b//g'|sed 's/\[?12l\[?25h//g')
	    LNS=$(cat $TMPFILE |sed '1,4d'|head -n -4|sed 's/\x1b//g'|sed 's/\[?12l\[?25h//g'|wc -l)
	    LNE=$(cat $TMPFILE |sed '1,4d'|head -n -4|sed 's/\x1b//g'|sed 's/\[?12l\[?25h//g'|wc -L)
	    if [ $(( $LNS + 5)) -gt 25 ] ; then LNS="20" ; fi
	    dialog --title "Check Package Results" --msgbox "$VAR" $(( $LNS + 5)) $(($LNE + 5 ))
	fi
	;;
    255)
	exit 1
	;;
    esac
    rm -r $TMPFILE
}

slackpkg_install_dialog() {
    slackpkg__mirror_status
    TMPFILE=$(mktemp -t slackpkgext.XXXXXX)

    dialog --title "Install Package" --clear \
           --inputbox "\nPlease type the name of a package to install..." 9 55 2> $TMPFILE

    case $? in
    0)
	slackpkg install $(cat $TMPFILE) 3>&2 2>&1 1>&3
	if [ ! "$(cat $TMPFILE | grep 'No packages match')" = "" ] ; then
	    dialog --title "Install Package" --msgbox "\nNo packages match the pattern for install or system\npackage is already installed." 8 55
	fi
	;;
    255)
	exit 1
	;;
    esac
    rm -r $TMPFILE
}

slackpkg_upgrade_dialog() {
    slackpkg__mirror_status
    TMPFILE=$(mktemp -t slackpkgext.XXXXXX)

    dialog --title "Upgrade Packages" --clear --yesno "\nWould you like to receive an updated copy of the\nrepository files?" 8 55
    case $? in
    0)
	slackpkg_update_dialog
	;;
    255)
	exit 1
	;;
    esac
    slackpkg upgrade patches 2> $TMPFILE
    if [ ! "$(cat $TMPFILE | grep 'No packages match')" = "" ] ; then
	dialog --title "Upgrade Packages" --msgbox "\nThe system is up to date." 7 55
    fi
    rm -r $TMPFILE
}

slackpkg_mirror_dialog() {
    TMPFILE=$(mktemp -t slackpkgext.XXXXXX)

    if [ -f /etc/slackpkg/mirrors ] ; then
	if [ "$LIBDIRSUFFIX" = "" ] ; then
	    cat /etc/slackpkg/mirrors | sed -e "1,/# Slackware-$SLKVER/d" | sed '/^# Slackware-current$/,$d' | sed '/#-------/d' | sed '/#$/d' > $TMPFILE
	elif [ "$LIBDIRSUFFIX" = "64" ] ; then
	    cat /etc/slackpkg/mirrors | sed -e "1,/# Slackware64-$SLKVER/d" | sed '/^# Slackware64-current$/,$d' | sed '/#-------/d' | sed '/#$/d' > $TMPFILE
	elif [ "$LIBDIRSUFFIX" = "arm" ] ; then
	    cat /etc/slackpkg/mirrors | sed -e "1,/# Slackware ARM $SLKVER/d" | sed '/^# Slackware ARM current$/,$d' | sed '/#-------/d' | sed '/#$/d' > $TMPFILE
	fi
	RLINES=""
	COUNTRY=""
	LOCATION=""
	ISON=""
	while read line
	do
	    if [[ ! "$line" =~ ":" ]] || ([[ ! "$line" =~ "ftp"  ]] && [[ ! "$line" =~ "http"  ]] && [[ ! "$line" =~ "rsync"  ]]) ; then
		COUNTRY=$(echo $line|cut -c2-|sed 's/://g')
	    else
		if [ "${line:0:1}" = "#" ] ; then
		    LOCATION=$(echo $line|awk -F"/" '{print $1"//"$3"/"}')
		    LOCATION="\"${LOCATION}\" off"
		else
		    LOCATION=$(echo $line|sed 's/^ //g'|awk -F"/" '{print $1"//"$3"/"}')
		    ISON="${LOCATION:0:-4}"
		    LOCATION="\"${LOCATION}\" on "
		fi
		RNEXT=$(echo "${LOCATION:0:-4}  \"${COUNTRY}\"  ${LOCATION: -3}")
		RLINES="${RLINES} \\+${RNEXT}"
	    fi
	done < <(cat $TMPFILE)
	echo $RLINES | sed 's/+/\n/g'| sed '1d' | sed 's/# //g'| sed 's/#//g'  > $TMPFILE
	CHOICE=$(dialog --title "Select Mirror Site" --clear \
	                --radiolist "\nPlease select the mirror site closer to you\n" 28 73 20 \
	                --file $TMPFILE 3>&2 2>&1 1>&3)
	case $? in
	    0)
		if [ "$LIBDIRSUFFIX" = "" ] ; then
		    HEAD=$(cat /etc/slackpkg/mirrors | grep -n '# Slackware-current' | cut -d ':' -f 1)
		elif [ "$LIBDIRSUFFIX" = "64" ] ; then
		    HEAD=$(cat /etc/slackpkg/mirrors | grep -n '# Slackware64-current' | cut -d ':' -f 1)
		elif [ "$LIBDIRSUFFIX" = "arm" ] ; then
		    HEAD=$(cat /etc/slackpkg/mirrors | grep -n '# Slackware ARM current' | cut -d ':' -f 1)
		fi
		BOT=$(( $(cat /etc/slackpkg/mirrors | wc -l) - $HEAD ))
		if [ "$LIBDIRSUFFIX" = "" ] ; then
		    TOP=$(cat /etc/slackpkg/mirrors | grep -n "# Slackware-$SLKVER" | cut -d ':' -f 1)
		elif [ "$LIBDIRSUFFIX" = "64" ] ; then
		    TOP=$(cat /etc/slackpkg/mirrors | grep -n "# Slackware64-$SLKVER" | cut -d ':' -f 1)
		elif [ "$LIBDIRSUFFIX" = "arm" ] ; then
		    TOP=$(cat /etc/slackpkg/mirrors | grep -n "# Slackware ARM $SLKVER" | cut -d ':' -f 1)
		fi
		TAIL=$(( $(cat /etc/slackpkg/mirrors | wc -l) - $TOP ))
		MIDNUM=$(( $HEAD - $TOP ))
		MID=$(cat /etc/slackpkg/mirrors | tail -n $TAIL | head -n $MIDNUM)
		if [ "$ISON" = "" ] ; then
		    if [[ "$MID" =~ "#$CHOICE" ]] ; then
			MID=$(cat /etc/slackpkg/mirrors | tail -n $TAIL | head -n $MIDNUM | sed 's!#'"$CHOICE"'!'"$CHOICE"'!g')
		    elif [[ "$MID" =~ "# $CHOICE" ]] ; then
			MID=$(cat /etc/slackpkg/mirrors | tail -n $TAIL | head -n $MIDNUM | sed 's!# '"$CHOICE"'! '"$CHOICE"'!g')
		    fi
		else
		    if [[ "$MID" =~ "#$CHOICE" ]] ; then
			MID=$(cat /etc/slackpkg/mirrors | tail -n $TAIL | head -n $MIDNUM | sed 's!'"$ISON"'!#'"$ISON"'!g' | sed 's!#'"$CHOICE"'!'"$CHOICE"'!g')
		    elif [[ "$MID" =~ "# $CHOICE" ]] ; then
			MID=$(cat /etc/slackpkg/mirrors | tail -n $TAIL | head -n $MIDNUM | sed 's! '"$ISON"'!# '"$ISON"'!g' | sed 's!# '"$CHOICE"'! '"$CHOICE"'!g')
		    fi
		fi
		TOP=$(cat /etc/slackpkg/mirrors | head -n $TOP)
		BOT=$(cat /etc/slackpkg/mirrors | tail -n $BOT)
		echo "$TOP" > /etc/slackpkg/mirrors
		echo "$MID" >> /etc/slackpkg/mirrors
		echo "$BOT" >> /etc/slackpkg/mirrors
		;;
	    1)
		rm -r $TMPFILE
		exit 0
		;;
	    255)
		rm -r $TMPFILE
		exit 1
		;;
	esac
    else
	dialog --title "Select Mirror Site" --msgbox "\nSlackpkg is not installed!" 7 55
    fi
    rm -r $TMPFILE
}

case $1 in
  update)
    slackpkg_update_dialog
    ;;
  check)
    slackpkg_check_dialog
    ;;
  install)
    slackpkg_install_dialog
    ;;
  upgrade)
    slackpkg_upgrade_dialog
    ;;
  mirror)
    slackpkg_mirror_dialog
    ;;
  *)
    echo "Usage: $(basename $0) {update|check|install|upgrade|mirror}"
    exit 1
    ;;
esac
exit 0
