#!/bin/sh
#
# Copyright (C) 2012-2014, 2016, 2017, 2019-2021  Etersoft
# Copyright (C) 2012-2014, 2016, 2017, 2019-2021  Vitaly Lipatov <lav@etersoft.ru>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#

load_helper epm-sh-altlinux
load_helper epm-query
load_helper epm-print
load_helper epm-sh-warmup
load_helper epm-sh-install

RPMISNOTINSTALLED=202

__check_rpm_e_result()
{
    grep -q "is not installed" $1 && return $RPMISNOTINSTALLED
    return $2
}


# Try remove with low level removing
epm_remove_low()
{
	[ -z "$1" ] && return

	warmup_lowbase

	case $PMTYPE in
		*-rpm)
			cd /tmp || fatal
			__epm_check_vendor $@
			store_output sudocmd rpm -ev $noscripts $nodeps $@
			# rpm returns number of packages if failed on removing
			__check_rpm_e_result $RC_STDOUT $?
			RES=$?
			clean_store_output
			cd - >/dev/null
			return $RES ;;
		*-dpkg|-dpkg)
			# shellcheck disable=SC2046
			sudocmd dpkg -P $(subst_option nodeps --force-all) $(print_name "$@")
			return ;;
		pkgsrc)
			sudocmd pkg_delete -r $@
			return ;;
		pkgng)
			sudocmd pkg delete -R $@
			return ;;
		emerge)
			sudocmd emerge --unmerge $@
			return ;;
		pacman)
			sudocmd pacman -R $@
			return ;;
		appget|winget)
			sudocmd $PMTYPE uninstall $@
			return ;;
		slackpkg)
			sudocmd /sbin/removepkg $@
			return ;;
	esac
	return 1
}

epm_remove_names()
{
	[ -z "$1" ] && return

	warmup_bases

	local APTOPTIONS="$(subst_option non_interactive -y)"

	case $PMTYPE in
		apt-dpkg)
			sudocmd apt-get remove --purge $APTOPTIONS $@
			return ;;
		aptitude-dpkg)
			sudocmd aptitude purge $@
			return ;;
		apt-rpm)
			sudocmd apt-get remove $APTOPTIONS $@
			return ;;
		packagekit)
			docmd pkcon remove $@
			return ;;
		deepsolver-rpm)
			sudocmd ds-remove $@
			return ;;
		urpm-rpm)
			sudocmd urpme $@
			return ;;
		pkgsrc) # without dependencies
			sudocmd pkg_delete $@
			return ;;
		pkgng)
			sudocmd pkg delete -R $@
			return ;;
		emerge)
			#sudocmd emerge --unmerge $@
			sudocmd emerge -aC $@
			return ;;
		pacman)
			sudocmd pacman -Rc $@
			return ;;
		yum-rpm)
			sudocmd yum remove $@
			return ;;
		dnf-rpm)
			sudocmd dnf remove $@
			return ;;
		snappy)
			sudocmd snappy uninstall $@
			return ;;
		zypper-rpm)
			sudocmd zypper remove --clean-deps $@
			return ;;
		mpkg)
			sudocmd mpkg remove $@
			return ;;
		conary)
			sudocmd conary erase $@
			return ;;
		npackd)
			sudocmd npackdcl remove --package=$1
			return ;;
		nix)
			sudocmd nix-env --uninstall $@
			return ;;
		apk)
			sudocmd apk del $@
			return ;;
		guix)
			sudocmd guix package -r $@
			return ;;
		android)
			sudocmd pm uninstall $@
			return ;;
		chocolatey)
			sudocmd chocolatey uninstall $@
			return ;;
		slackpkg)
			sudocmd /usr/sbin/slackpkg remove $@
			return ;;
		homebrew)
			docmd brew remove $@
			return ;;
		aptcyg)
			sudocmd apt-cyg remove $@
			return ;;
		xbps)
			sudocmd xbps remove -R $@
			return ;;
		appget|winget)
			sudocmd $PMTYPE uninstall $@
			return ;;
		opkg)
			# shellcheck disable=SC2046
			sudocmd opkg $(subst_option force -force-depends) remove $@
			return ;;
		*)
			fatal "Have no suitable command for $PMTYPE"
			;;
	esac
}

# TODO
epm_remove_nonint()
{
	warmup_bases

	case $PMTYPE in
		apt-dpkg)
			sudocmd apt-get -y --force-yes remove --purge $@
			return ;;
		aptitude-dpkg)
			sudocmd aptitude -y purge $@
			return ;;
		apt-rpm)
			sudocmd apt-get -y --force-yes remove $@
			return ;;
		packagekit)
			docmd pkcon remove --noninteractive $@
			return ;;
		urpm-rpm)
			sudocmd urpme --auto $@
			return ;;
		pacman)
			sudocmd pacman -Rc --noconfirm $@
			return ;;
		yum-rpm)
			sudocmd yum -y remove $@
			return ;;
		dnf-rpm)
			sudocmd dnf remove --assumeyes $@
			return ;;
		zypper-rpm)
			sudocmd zypper --non-interactive remove --clean-deps $@
			return ;;
		slackpkg)
			sudocmd /usr/sbin/slackpkg -batch=on -default_answer=yes remove $@
			return ;;
		pkgng)
			sudocmd pkg delete -y -R $@
			return ;;
		opkg)
			sudocmd opkg -force-defaults remove $@
			return ;;
		appget|winget)
			sudocmd $PMTYPE uninstall -s $@
			return ;;
		xbps)
			sudocmd xbps remove -y $@
			return ;;
	esac
	return 5
}

epm_print_remove_command()
{
	case $PMTYPE in
		*-rpm)
			echo "rpm -ev $nodeps $*"
			;;
		*-dpkg)
			echo "dpkg -P $*"
			;;
		packagekit-*)
			echo "pkcon remove --noninteractive $*"
			;;
		pkgsrc)
			echo "pkg_delete -r $*"
			;;
		pkgng)
			echo "pkg delete -R $*"
			;;
		pacman)
			echo "pacman -R $*"
			;;
		emerge)
			echo "emerge --unmerge $*"
			;;
		slackpkg)
			echo "/sbin/removepkg $*"
			;;
		opkg)
			echo "opkg remove $*"
			;;
		aptcyg)
			echo "apt-cyg remove $*"
			;;
		xbps)
			echo "xbps remove -y $*"
			;;
		appget|winget)
			echo "$PMTYPE uninstall -s $*"
			;;
		*)
			fatal "Have no suitable appropriate remove command for $PMTYPE"
			;;
	esac
}


epm_remove()
{
	if [ -n "$show_command_only" ] ; then
		epm_print_remove_command $pkg_filenames
		return
	fi

	if [ "$DISTRNAME" = "ALTLinux" ] || [ "$DISTRNAME" = "ALTServer" ] ; then
		load_helper epm-sh-altlinux
		if tasknumber "$pkg_names" >/dev/null ; then
			assure_exists apt-repo
			pkg_names="$(get_task_packages $pkg_names)"
		fi
	fi

	# TODO: fix pkg_names override
	# get full package name(s) from the package file(s)
	[ -n "$pkg_files" ] && pkg_names="$pkg_names $(epm query $pkg_files)"
	pkg_files=''

	if [ -z "$pkg_names" ] ; then
		warning "no package(s) to remove."
		return
	fi
	# remove according current arch (if x86_64) by default
	pkg_names="$(echo $pkg_names | exp_with_arch_suffix)"

	if [ -n "$dryrun" ] ; then
		info "Packages for removing:"
		echo "$pkg_names"
		case $PMTYPE in
			apt-rpm)
				nodeps="--test"
				APTOPTIONS="--simulate"
				;;
			apt-deb)
				nodeps="--simulate"
				APTOPTIONS="--simulate"
				;;
			*)
				return
				;;
		esac
	fi

	if [ -n "$skip_missed" ] ; then
		pkg_names="$(get_only_installed_packages $pkg_names)"
	fi

	epm_remove_low $pkg_names && return
	local STATUS=$?

	if [ -n "$direct" ] || [ -n "$nodeps" ] || [ "$STATUS" = "$RPMISNOTINSTALLED" ]; then
		[ -n "$force" ] || return $STATUS
	fi

	# get package name for hi level package management command (with version if supported and if possible)
	pkg_names=$(__epm_get_hilevel_name $pkg_names)

	if [ -n "$non_interactive" ] ; then
		epm_remove_nonint $pkg_names
		local RET=$?
		# if not separate command, use usual command
		[ "$RET" = "5" ] || return $RET
	fi

	epm_remove_names $pkg_names
}