#!/bin/sh
#
# Copyright (C) 2017-2018  Etersoft
# Copyright (C) 2017-2018  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-assure

# arg: rpm or deb
# fills split_replaced_pkgs with packages of that type
__epm_split_by_pkg_type()
{
	local type="$1"
	shift

	split_replaced_pkgs=''

	for pkg in "$@" ; do
		[ "$(get_package_type "$pkg")" = "$type" ] || return 1
		[ -e "$pkg" ] || fatal "Can't read $pkg"
		split_replaced_pkgs="$split_target_pkgs $(realpath "$pkg")"
	done

	[ -n "$split_replaced_pkgs" ]
}

# fills repacked_rpms
__epm_repack_deb_to_rpm()
{
	local pkg

	assure_exists alien
	assure_exists dpkg
	# TODO: Для установки требует: /usr/share/debconf/confmodule но пакет не может быть установлен
	# assure_exists debconf

	repacked_rpms=''

	local TDIR=$(mktemp -d)
	cd $TDIR || fatal
	for pkg in "$@" ; do
		# TODO: fakeroot for non ALT?
		showcmd_store_output alien -r -k $scripts "$pkg" || fatal
		local RPMCONVERTED=$(grep "rpm generated" $RC_STDOUT | sed -e "s| generated||g")
		repacked_rpms="$repacked_rpms $(realpath $RPMCONVERTED)"
		to_remove_pkg_files="$to_remove_pkg_files $(realpath $RPMCONVERTED)"
		clean_store_output
	done

	cd - >/dev/null
	return 0
}

__epm_check_if_try_install_deb()
{
	__epm_split_by_pkg_type deb "$@" || return 1
	__epm_repack_deb_to_rpm "$@"

	# TODO: move to install
	docmd epm install $force $nodeps $repacked_rpms

	return 0
}

# fills repacked_debs
__epm_repack_rpm_to_deb()
{
	local pkg

	assure_exists alien
	assure_exists fakeroot
	assure_exists rpm

	repacked_debs=''

	local TDIR=$(mktemp -d)
	cd $TDIR || fatal

	for pkg in $rpmpkgs ; do
		showcmd_store_output fakeroot alien -d -k $scripts "$pkg"
		local DEBCONVERTED=$(grep "deb generated" $RC_STDOUT | sed -e "s| generated||g")
		repacked_debs="$repacked_rpms $(realpath $DEBCONVERTED)"
		to_remove_pkg_files="$to_remove_pkg_files $(realpath $DEBCONVERTED)"
		clean_store_output
	done

	cd - >/dev/null
	return 0
}


# TODO: rewrite to convert (get some code from Korinf?)
__epm_check_if_try_install_rpm()
{
	__epm_split_by_pkg_type rpm "$@" || return 1
	__epm_repack_rpm_to_deb "$@"

	# TODO: move to install
	docmd epm install $force $nodeps $repacked_debs

	return 0
}


# args: buildroot spec
__fix_spec()
{
    local buildroot="$1"
    local spec="$2"
    local i
    for i in $(grep '^"/' $spec | sed -e 's|^"\(.*\)"$|\1|') ; do
        #' hack for highlight
        # add %dir to dir in list
        if [ -d "$buildroot$i" ] ; then
            subst 's|^\("'$i'"\)$|%dir \1|' $spec
        fi
    done
    subst "s|^Release: |Release: alt1.repacked.with.epm.|" $spec
    subst "s|^\((Converted from a rpm package.*\)|(Repacked from binary rpm with epm $EPMVERSION)\n\1|" $spec
    #" hack for highlight
}

__apply_fix_code()
{
    local repackcode="$CONFIGDIR/repack.d/$1.sh"
    [ -x "$repackcode" ] || return
    shift
    docmd $repackcode "$1" "$2" || warning "There was errors with $repackcode script"
}

__create_rpmmacros()
{
    cat <<EOF >$HOME/.rpmmacros
%_topdir	$HOME/RPM
%_tmppath	$TMPDIR

%packager	EPM <support@etersoft.ru>
%_gpg_name	support@etersoft.ru
EOF
}

# will fill repacked_rpms var
__epm_repack_rpm()
{
    assure_distr ALTLinux "install --repack"

    assure_exists fakeroot || fatal
    assure_exists alien || fatal
    assure_exists rpmbuild rpm-build || fatal

    local pkg
    export HOME=$(mktemp -d)
    local tmpbuilddir=$HOME/repack
    mkdir $tmpbuilddir
    __create_rpmmacros

    local abspkg
    repacked_rpms=''
    for pkg in $* ; do
        abspkg=$(realpath $pkg)
        info "Repacking $abspkg to local rpm format ..."
        cd $tmpbuilddir || fatal
        docmd fakeroot alien --generate --to-rpm $verbose $scripts $abspkg || fatal

        local subdir="$(echo *)"
        [ -d "$subdir" ] || fatal "can't find subdir"

        # detect spec and move to prev dir
        local spec="$(echo $tmpbuilddir/$subdir/*.spec)"
        [ -s "$spec" ] || fatal "can't find spec"
        mv $spec $tmpbuilddir || fatal
        spec="$tmpbuilddir/$(basename "$spec")"
        __fix_spec $tmpbuilddir/$subdir $spec
        local pkgname="$(grep "^Name: " $spec | sed -e "s|Name: ||g" | head -n1)"
        __apply_fix_code $pkgname $tmpbuilddir/$subdir $spec
        showcmd fakeroot rpmbuild --buildroot $tmpbuilddir/$subdir --define='_allow_root_build 1' -bb $spec
        if [ -n "$verbose" ] ; then
            a='' fakeroot rpmbuild --buildroot $tmpbuilddir/$subdir  --define='_allow_root_build 1' -bb $spec || fatal
        else
            a='' fakeroot rpmbuild --buildroot $tmpbuilddir/$subdir  --define='_allow_root_build 1' -bb $spec >/dev/null || fatal
        fi
        local repacked_rpm="$(realpath $tmpbuilddir/../*.rpm)"
        if [ -s "$repacked_rpm" ] ; then
            repacked_rpms="$repacked_rpms $repacked_rpm"
            to_remove_pkg_files="$to_remove_pkg_files $repacked_rpm"
        else
            warning "Can't find converted rpm for source binary $pkg package"
        fi
        cd - >/dev/null
        rm -rf $tmpbuilddir/$subdir/
        #rm -rf $tmpbuilddir/../*.rpm
        rm -rf $spec
    done
    rmdir $tmpbuilddir
    #rmdir $tmpbuilddir/..
    true
}

epm_repack()
{
    # if possible, it will put pkg_urls into pkg_files and reconstruct pkg_filenames
    if [ -n "$pkg_urls" ] ; then
        load_helper epm-download
        __handle_pkg_urls_to_install
    fi

    [ -z "$pkg_files" ] && info "Skip empty repack list" && return 22

    # TODO: если у нас rpm, а пакет - deb и наоборот
    case $PKGFORMAT in
        rpm)
            if __epm_split_by_pkg_type deb $pkg_files ; then
                __epm_repack_deb_to_rpm $split_replaced_pkgs
                cp -v $repacked_rpms .
                pkg_files="$(estrlist exclude $split_replaced_pkgs $pkg_files)"
            fi

            if [ -n "$pkg_files" ] ; then
                __epm_repack_rpm $pkg_files || fatal
                cp -v $repacked_rpms .
            fi
            ;;
        deb)
            if __epm_split_by_pkg_type rpm $pkg_files ; then
                __epm_repack_rpm_to_deb $split_replaced_pkgs
                cp -v $repacked_debs .
                pkg_files="$(estrlist exclude $split_replaced_pkgs $pkg_files)"
            fi
            ;;
        *)
            fatal "$PKGFORMAT is not supported for repack yet"
            ;;
    esac


    # TODO: move it to exit handler
    if [ -z "$DEBUG" ] ; then
    # TODO: reinvent
    [ -n "$to_remove_pkg_files" ] && rm -fv $to_remove_pkg_files
    [ -n "$to_remove_pkg_files" ] && rmdir -v $(dirname $to_remove_pkg_files | head -n1) 2>/dev/null
    fi

}