#!/bin/sh
#
# Copyright (C) 2012-13  Etersoft
# Copyright (C) 2012-13  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-query

# TODO: use when run install with epm --skip-installed install
filter_out_installed_packages()
{
	[ -z "$skip_installed" ] && cat && return

	case $PKGFORMAT in
		"rpm")
			LANG=C LC_ALL=C xargs -n1 rpm -q 2>&1 | grep 'is not installed' |
				sed -e 's|^.*package \(.*\) is not installed.*|\1|g'
			;;
		"deb")
			LANG=C LC_ALL=C xargs -n1 dpkg -l 2>&1 | grep -i 'no packages found matching' |
				sed -e 's|\.\+$||g' -e 's|^.*[Nn]o packages found matching \(.*\)|\1|g'
			;;
		*)
			for i in $(cat) ; do
				is_installed $i || echo $i
			done
			;;
	esac | sed -e "s|rpm-build-altlinux-compat[^ ]*||g" | filter_strip_spaces
}

# http://ru.gentoo-wiki.com/wiki/Portage_Overlay
# http://kb.etersoft.ru/Gentoo:_Установка_продуктов_Etersoft
# http://linuxreviews.org/gentoo/ebuilds/
# 
# install one ebuild
__emerge_install_ebuild()
{
	local EBUILD="$1"
	[ -s "$EBUILD" ] || fatal ".ebuild file '$EBUILD' is missing"

	# load ebuild and get vars
	. $EBUILD
	[ -n "$SRC_URI" ] || fatal "Can't load SRC_URI from $EBUILD"

	# try to detect tarballs
	local TARBALLS=
	local BASEDIR=$(dirname $EBUILD)
	for i in $SRC_URI ; do
		[ -s "$BASEDIR/$(basename $i)" ] || continue
		TARBALLS="$TARBALLS $BASEDIR/$(basename $i)"
	done

	local PORTAGENAME=epm
	local LP=/usr/local/portage/$PORTAGENAME
	sudocmd mkdir -p $LP/
	if ! grep -v "^#" /etc/make.conf | grep -q $LP ; then
		sudocmd echo 'PORTDIR_OVERLAY="$LP \${PORTDIR_OVERLAY}"' >>/etc/make.conf
		# Overlay name
		sudocmd mkdir -p $LP/profiles/
		sudocmd echo "$PORTAGENAME" > $LP/profiles/repo_name
	fi

	# copy tarballs
	local DDIR=/usr/portage/distfiles
	[ -d /var/calculate/remote/distfiles ] && DDIR=/var/calculate/remote/distfiles
	sudocmd cp -f $TARBALLS $DDIR/ || return

	# copy ebuild
	sudocmd cp -f $EBUILD $LP/ || return
	cd $LP
	sudocmd ebuild $(basename $EBUILD) digest
	cd -
	# FIXME: more correcty get name
	local PKGNAME=$(echo $EBUILD | sed -e "s|-[0-9].*||g")
	sudocmd emerge -av $PKGNAME || return
}

# install ebuild list
__emerge_install()
{
	local EBUILD=
	#local TARBALLS=
	local i

	# search ebuild in the args
	for i in $* ; do
		if echo $i | grep -q ebuild ; then
	[ -s "$EBUILD" ] || fatal "Can't find .ebuild file in $*"
			__emerge_install_ebuild $i
			continue
	#	else
	#		TARBALLS="$TARBALLS $i"
		fi
	done

}

# copied from etersoft-build-utils/share/eterbuild/functions/rpmpkg
epm_install_names()
{
	if [ -n "$non_interactive" ] ; then
		epm_ni_install_names "$@"
		return
	fi

	[ -z "$1" ] && return
	case $PMTYPE in
		apt-rpm|apt-dpkg)
			sudocmd apt-get $APTOPTIONS install $@
			return ;;
		deepsolver-rpm)
			sudocmd ds-install $@
			return ;;
		urpm-rpm)
			sudocmd urpmi $URPMOPTIONS $@
			return ;;
		pkgsrc)
			sudocmd pkg_add -r $@
			return ;;
		emerge)
			sudocmd emerge -uD $@
			return ;;
		pacman)
			sudocmd pacman -S $force $nodeps $@
			return ;;
		aura)
			sudocmd aura -A $force $nodeps $@
			return ;;
		yum-rpm)
			sudocmd yum $YUMOPTIONS install $@
			return ;;
		dnf-rpm)
			sudocmd dnf install $@
			return ;;
		zypper-rpm)
			sudocmd zypper install $ZYPPEROPTIONS $@
			return ;;
		mpkg)
			sudocmd mpkg install $@
			return ;;
		npackd)
			separate_installed $@
			# FIXME: fix return status
			# TODO: use upgrade if package is already installed
			[ -n "$pkg_noninstalled" ] && sudocmd npackdcl add --package=$@ $pkg_noninstalled
			[ -n "$pkg_installed" ] && sudocmd npackdcl update --package=$@ $pkg_installed
			return ;;
		slackpkg)
			separate_installed $@
			# TODO: use upgrade if package is already installed
			[ -n "$pkg_noninstalled" ] && sudocmd /usr/sbin/slackpkg install $pkg_noninstalled
			[ -n "$pkg_installed" ] && sudocmd /usr/sbin/slackpkg upgrade $pkg_installed
			return ;;
		homebrew)
			separate_installed $@
			[ -n "$pkg_noninstalled" ] && sudocmd brew install $pkg_noninstalled
			[ -n "$pkg_installed" ] && sudocmd brew upgrade $pkg_installed
			return ;;
		ipkg)
			[ -n "$force" ] && force=-force-depends
			sudocmd ipkg $force install $@
			return ;;
		nix)
			separate_installed $@
			[ -n "$pkg_noninstalled" ] && sudocmd nix-env --install $pkg_noninstalled
			[ -n "$pkg_installed" ] && sudocmd nix-env --upgrade $pkg_installed
			return ;;
		*)
			fatal "Do not known install command for $PMTYPE"
			;;
	esac
}

# Non interactive install
epm_ni_install_names()
{
	[ -z "$1" ] && return
	case $PMTYPE in
		apt-rpm|apt-dpkg)
			sudocmd apt-get -y --force-yes -o Dpkg::Options::="--force-confdef" -o Dpkg::Options::="--force-confold" $APTOPTIONS install $@
			return ;;
		yum-rpm)
			sudocmd yum -y $YUMOPTIONS install $@
			return ;;
		urpm-rpm)
			sudocmd urpmi --auto $URPMOPTIONS $@
			return ;;
		zypper-rpm)
			# FIXME: returns true ever no package found, need check for "no found", "Nothing to do."
			yes | sudocmd zypper --non-interactive $ZYPPEROPTIONS install $@
			return ;;
		pkgsrc)
			sudocmd pkg_add -r $@
			return ;;
		emerge)
			sudocmd emerge -uD $@
			return ;;
		pacman)
			sudocmd pacman -S --noconfirm $force $nodeps $@
			return ;;
		aura)
			sudocmd aura -A $force $nodeps $@
			return ;;
		npackd)
			#  npackdcl update --package=<package> (remove old and install new)
			sudocmd npackdcl add --package=$@
			return ;;
		chocolatey)
			docmd chocolatey install $@
			return ;;
		ipkg)
			sudocmd ipkg -force-defaults install $@
			return ;;
		nix)
			sudocmd nix-env --install $@
			return ;;
		slackpkg)
			separate_installed $@
			# FIXME: broken status when use batch and default answrt
			[ -n "$pkg_noninstalled" ] && sudocmd /usr/sbin/slackpkg -batch=on -default_answer=yes install $pkg_noninstalled
			[ -n "$pkg_installed" ] && sudocmd /usr/sbin/slackpkg -batch=on -default_answer=yes upgrade $pkg_installed
			return ;;
		*)
			fatal "Do not known appropriate install command for $PMTYPE"
			;;
	esac
}

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

    case $PMTYPE in
        apt-rpm)
            sudocmd rpm -Uvh $force $nodeps $@ && return
            # TODO: check for "is already installed"
            # if run with --nodeps, do not fallback on hi level
            [ -n "$nodeps" ] && return

            # use install_names
            ;;
        apt-dpkg)
            # the new version of the conf. file is installed with a .dpkg-dist suffix
            if [ -n "$non_interactive" ] ; then
                DPKGOPTIONS="--force-confdef --force-confold"
            fi
            sudocmd dpkg $DPKGOPTIONS -i $@
            # if run with --nodeps, do not fallback on hi level

            [ -n "$nodeps" ] && return
            # fall to apt-get -f install for fix deps
            # can't use APTOPTIONS with empty install args
            epm_install_names -f
            return
            ;;
        yum-rpm|dnf-rpm)
            sudocmd rpm -Uvh $force $nodeps $@ && return
            # if run with --nodeps, do not fallback on hi level

            [ -n "$nodeps" ] && return
            YUMOPTIONS=--nogpgcheck
            # use install_names
            ;;
        zypper-rpm)
            sudocmd rpm -Uvh $force $nodeps $@ && return
            # if run with --nodeps, do not fallback on hi level

            [ -n "$nodeps" ] && return
            ZYPPEROPTIONS=--no-gpg-checks
            # use install_names
            ;;
        urpm-rpm)
            sudocmd rpm -Uvh $force $nodeps $@ && return
            # if run with --nodeps, do not fallback on hi level
            [ -n "$nodeps" ] && return

            URPMOPTIONS=--no-verify-rpm
            # use install_names
            ;;
        pkgsrc)
            sudocmd pkg_add $@
            return ;;
        emerge)
            __emerge_install $@
            return ;;
        pacman)
            sudocmd pacman -U --noconfirm $force $nodeps $@ && return
            [ -n "$nodeps" ] && return
            sudocmd pacman -U $force $@
            return ;;
        slackpkg)
            sudocmd /sbin/installpkg $@
            return ;;
    esac

    # other systems can install file package via ordinary command
    epm_install_names "$@"
}

epm_print_install_command()
{
    case $PMTYPE in
        apt-rpm|yum-rpm|urpm-rpm|zypper-rpm|dnf-rpm)
            echo "rpm -Uvh --force $nodeps $@"
            ;;
        apt-dpkg)
            echo "dpkg -i $@"
            ;;
        pkgsrc)
            echo "pkg_add $@"
            ;;
        #emerge)
        #    # it is better to use epm
        #    echo "tar xvfj $@ -C /"
        #    ;;
        pacman)
            echo "pacman -U --noconfirm --force $nodeps $@"
            ;;
        slackpkg)
            echo "/sbin/installpkg $@"
            ;;
        npackd)
            echo "npackdcl add --package=$@"
            ;;
        ipkg)
            echo "ipkg install $@"
            ;;
        *)
            fatal "Do not known appropriate install command for $PMTYPE"
            ;;
    esac
}


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

    [ -n "$pkg_files$pkg_names" ] || { echo "Skip empty install list" ; return 22 ; }

    local names="$(echo $pkg_names | filter_out_installed_packages)"
    local files="$(echo $pkg_files | filter_out_installed_packages)"

    [ -z "$files$names" ] && echo "Skip empty install list" && return 22

    epm_install_names $names || return
    epm_install_files $files
}
