#!/bin/bash
# -*- ENCODING: UTF-8 -*-

# app
#
# Install and uninstall packages.
#
# Copyright (c) 2013-2026: Alexis Puente Montiel   < pica (a) picalibre.org >
#
# Licensed according to GNU AGPL version 3.0.
#
# It is libre/free software; you can use, redistribute and/or modify it according to the terms of GNU AGPL as published by GNU, version 3.0, 19 November 2007.
#
# It is distributed in the hope that it will be useful, but without any warranty. Read GNU AGPL version 3.0 for additional details.
#
# A copy of GNU AGPL version 3.0 is available at /usr/share/doc/<software-package-name>/agpl-3.0.txt (additionally on Internet as text at https://www.gnu.org/licenses/agpl-3.0.txt and as HTML at https://www.gnu.org/licenses/agpl-3.0-standalone.html ).
#
# Note: Additionally to the official e-mails, picalibre.org is strictly the only official site for this software project, please consider using it to download, report bugs and contribute.
#
# Depends: apt, bash, coreutils, dpkg, gawk | mawk | original-awk, grep


### SCRIPT VARIABLES ########################################

CNAME="app"
VERSION="1.3.1"
TITLE="'app'"

# Translations
if [ "$LANG" = "" ] ; then export $(cat /etc/default/locale | grep -a 'LANG=') ; fi
TEXTDOMAIN=pica-apt
TEXTDOMAINDIR=/usr/share/locale/

# Write errors to log
ERRORLOG="$HOME/.${CNAME}.log"
if [ -e "$ERRORLOG" ] ; then
	mv -f $ERRORLOG ${ERRORLOG}.ant
fi
if [ -e "$ERRORLOG" ] ; then rm -rf "$ERRORLOG" ; fi

for i in /etc/pica-global.dist /etc/pica-global.orig /etc/pica-global /etc/pica-global.local ~/.pica-global ~/pica-global ; do
	if [ -f "$i" ] ; then
	cat "$i"
	source "$i"
	source <(cat $i | sed -e "s/=\(YES\|Yes\|yes\|y\|SÍ\|SI\|Sí\|Si\|sí\|si\|S\|s\)/=Y/g" -e "s/=\(No\|no\|n\)/=N/g" -e "s/=\"\(YES\|Yes\|yes\|y\|SÍ\|SI\|Sí\|Si\|sí\|si\|S\|s\)\"/=Y/g" -e "s/=\"\(No\|no\|n\)\"/=N/g")
	fi
done
if [ "$DEBUG" = "Y" ] ; then
	set -xv
	DEBUG="Y"
else
	ERRORLOG="/tmp/.${CNAME}_$(id -nu).log"
	if [ -e "$ERRORLOG" ] ; then mv -f $ERRORLOG ${ERRORLOG}.ant ; fi
	if [ -e "$ERRORLOG" ] ; then rm -rf "$ERRORLOG" ; fi
fi
#if [ "$DEBUG" = "" ] ; then DEBUG="N" ; fi
if [ "$DEBUG" != "N" ] ; then
exec > >(tee -a "$ERRORLOG") 2>&1
echo "$0" "$*" >> "$ERRORLOG"
echo "$CNAME" "$VERSION" >> "$ERRORLOG"
echo $(date +%Y-%m-%d_%H:%M:%S) $"Start" >> "$ERRORLOG"
echo "env:" >> "$ERRORLOG"
env >> "$ERRORLOG"
echo "set:" >> "$ERRORLOG"
set >> "$ERRORLOG"
#else
#exec 2>>"$ERRORLOG"
fi

# Description:
BDESCRIP=$"Install and uninstall packages."
LDESCRIP=$"$TITLE is a tool to install and uninstall packages."

# Documentation:
docu_info () {
echo "$CNAME ($VERSION) - $BDESCRIP"
echo 
echo $"Usage:" $CNAME [$"OPTIONS"] $"ACTION" [ { $"PACKAGES" \| $"NAME" \| $"FILES" } ]
echo 
echo $"Options:"
echo -e "$ODESCRIP"
echo 
echo $"Actions (choose one):"
echo -e "$ADESCRIP"
echo 
echo $"'man $CNAME' for more information."
echo 
}

ADESCRIP=" a""\t\t""(a = u) "$"Install (security) updates (from package sources). Do before other actions if it was not done in the last hours.""\n"" u""\t\t""(a = u) "$"Install (security) updates (from package sources). Do before other actions if it was not done in the last hours.""\n"" i"$" [packages]""\t"$"Install the indicated packages (from package sources).""\n"" r"$" [packages]""\t"$"Reinstall the indicated packages (from package sources).""\n"" e"$" [packages]""\t"$"Delete the indicated installed packages.""\n"" t\t""\t"$"Delete all installed packages that seem unnecessary.""\n"" k""\t\t""(k = p) "$"Delete downloaded files that remain stored after installation.""\n"" p""\t\t""(k = p) "$"Delete downloaded files that remain stored after installation.""\n"" b"$" [name]""\t""(b = s) "$"Search packages by name.""\n"" s"$" [name]""\t""(b = s) "$"Search packages by name.""\n"" d"$" [packages]""\t"$"Details of the indicated packages.""\n"" v"$" [packages]""\t"$"Available versions of the indicated packages.""\n"" n"$" [packages]""\t"$"Install the indicated packages downloaded from outside the package sources (non-PicaLibre packages, generally not recommended).""\n"" f"$" [packages]""\t"$"Install the indicated packages downloaded from outside the package sources (installing dependencies from package sources) (non-PicaLibre packages, generally not recommended).""\n"" l""\t\t"$"List installed packages.""\n"" m""\t\t"$"List installed packages by size.""\n"" c"$" [packages]""\t"$"Content of the indicated installed packages.""\n"" o"$" [files]""\t"$"Source package of the indicated files.""\n"" q""\t\t"$"Fix problems installing packages (if it is a problem due to failing to install a package, first try if uninstalling 'e' that package fixes the problem).""\n"" z""\t\t"$"Checks after installing packages (generally unnecessary if installing from package sources).""\n"" x""\t\t"$"Show help documentation.""\n\n"$"[packages] and [files] can be a list separated by spaces (not commas or other signs), while [name] can be a regular expression and will be searched in both the names and descriptions of the packages.""\n\n"$"If you don't get a result, ensure you spelled the package name correctly."

ODESCRIP=" -g""\t""(-g = -y) "$"Do not ask for confirmation (only with 'i', 'r' or 'e' actions).""\n"" -y""\t""(-g = -y) "$"Do not ask for confirmation (only with 'i', 'r' or 'e' actions).""\n"" -s""\t"$"Simulate.""\n"" -x""\t"$"Show help documentation."


while getopts gysx OPTION ; do
	case $OPTION in
		g )   CONF="$CONF -y" ; shift 1 ;;
		y )   CONF="$CONF -y" ; shift 1 ;;
		s )   CONF="$CONF -s" ; SIM="Y" ; shift 1 ;;
		x )   docu_info ; exit 0 ;;
	esac
done

if [ "$*" = "" ] ; then
	docu_info ; exit 0
fi


### ROOT CHECK ########################################

root_check () {
if [ "$SIM" != "Y" ] ; then
#if [ "$(cat /etc/passwd | grep -aE ^$(whoami): | cut -d ':' -f 3 )" -ne 0 ] ; then
if [ "$(id -u)" -ne 0 ] ; then
	echo $"This action must be done as SuperUser. Cannot continue."
	exit 1
fi
fi
}
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/opt/trinity/bin


### SCRIPT ########################################

pica-extras-fix () {
if [ "$(lsof /var/lib/apt/lists/lock 2>>$ERRORLOG | grep -a -c ^)" -eq 0 ] && [ "$(lsof /var/lib/apt/lists/lock-frontend 2>>$ERRORLOG | grep -a -c ^)" -eq 0 ] && [ "$(lsof /var/lib/apt/lists/lock-frontened 2>>$ERRORLOG | grep -a -c ^)" -eq 0 ] && [ "$(lsof /var/cache/apt/archives/lock 2>>$ERRORLOG | grep -a -c ^)" -eq 0 ] && [ "$(lsof /var/cache/apt/archives/lock-frontend 2>>$ERRORLOG | grep -a -c ^)" -eq 0 ] && [ "$(lsof /var/cache/apt/archives/lock-frontened 2>>$ERRORLOG | grep -a -c ^)" -eq 0 ] && [ "$(lsof /var/lib/dpkg/lock 2>>$ERRORLOG | grep -a -c ^)" -eq 0 ] && [ "$(lsof /var/lib/dpkg/lock-frontend 2>>$ERRORLOG | grep -a -c ^)" -eq 0 ] && [ "$(lsof /var/lib/dpkg/lock-frontened 2>>$ERRORLOG | grep -a -c ^)" -eq 0 ] ; then
# Translations
cd /
for i in guvcview pdfarranger synaptic thunar ; do
	if [ -e "/var/lib/dpkg/info/$i-extras.md5sums" ] ; then
		cat "/var/lib/dpkg/info/$i-extras.md5sums" | grep -aEi "\.mo$" | while read l ; do
			if [ "$(md5sum $(echo $l | awk '{print $2}'))" != "$l" ] ; then
				apt-get install --reinstall --no-install-recommends -y -o Dpkg::Options::="--force-confmiss" -o Dpkg::Options::="--force-confnew" $i-extras
				#echo -e "\e[1;31m"$"$i must be reinstalled.""\e[0m"
			fi
		done
	fi
done
cd - 1>/dev/null
fi
}

case $1 in

	a | u )
		root_check
		apt-actualiza
	;;

	i )
		root_check
		shift 1
#		apt install -o Dpkg::Options::="--force-confmiss" -o Dpkg::Options::="--force-confnew" $CONF "$@" 2>>$ERRORLOG
		apt-get install -o Dpkg::Options::="--force-confmiss" -o Dpkg::Options::="--force-confnew" $CONF "$@"
		pica-extras-fix
	;;

	r )
		root_check
		shift 1
#		apt reinstall -o Dpkg::Options::="--force-confmiss" -o Dpkg::Options::="--force-confnew" $CONF "$@" 2>>$ERRORLOG
		apt-get reinstall -o Dpkg::Options::="--force-confmiss" -o Dpkg::Options::="--force-confnew" $CONF "$@"
		pica-extras-fix
	;;

	e )
		root_check
		shift 1
#		apt purge $CONF "$@" 2>>$ERRORLOG
		apt-get purge $CONF "$@"
	;;

	t )
		root_check
		shift 1
#		apt autopurge "$@" 2>>$ERRORLOG
		apt-get autopurge "$@"
	;;

	k | p )
		root_check
		shift 1
#		apt clean "$@" 2>>$ERRORLOG
		apt-get clean "$@"
		find "$TFS"/var/lib/apt/lists -type f | grep -aEiv "lock$" | while read i ; do rm -f "$i" ; done
		if [ -e "$TFS/var/cache/apt-xapian-index/" ] ; then find "$TFS"/var/cache/apt-xapian-index/ -type f | while read i ; do rm -rf $i ; done ; fi
		find "$TFS"/var/cache/apt/  -maxdepth 1 -type f | grep -aEi 'pkgcache|srcpkgcache' | while read i ; do rm -rf $i ; done
	;;

	s | b )
		shift 1
		apt-cache search "$@" | sort -u -V
	;;

	d )
		shift 1
		apt-cache show "$@"
	;;

	v )
		shift 1
		#apt-cache madison "$@" | sort -u -V
		apt-cache policy "$@"
	;;

	n )
		root_check
		shift 1
		dpkg -i "$@"
		apt-post
	;;

	f )
		root_check
		shift 1
		if [ "$(dpkg -l | grep -aEi "^ii|^hi" | awk '{print $2}' | sed "s|:.*||g" | grep -aEi "^gdebi-core$" )" = "" ] ; then apt-get install --reinstall --no-install-recommends -y -o Dpkg::Options::="--force-confmiss" -o Dpkg::Options::="--force-confnew" gdebi-core ; fi
		gdebi "$@"
		apt-post
	;;

	l )
		shift 1
		dpkg -l "$@"
	;;

	m )
		dpkg-query -Wf '${Installed-Size}\t${Package}\t${Status}\n' | sort -n | awk '$3 !~ /deinstall/ {print $1"\t"$2}'
	;;

	c )
		shift 1
		dpkg -L "$@" | sort -u
	;;

	o )
		shift 1
		dpkg -S "$@"
	;;

	q )
		root_check
		apt-problem
	;;

	z )
		root_check
		apt-post
	;;

	x )
		docu_info
		exit 0
	;;

	* )
		docu_info
		exit 1
	;;

esac

exit 0
