#!/bin/sh
#
# Copyright (C) 2017-2018, 2020  Etersoft
# Copyright (C) 2017-2018, 2020  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
load_helper epm-status

[ -n "$EPM_REPACK_SCRIPTS_DIR" ] || EPM_REPACK_SCRIPTS_DIR="$CONFIGDIR/repack.d"

__epm_have_repack_rule()
{
    # FIXME: use real way (for any archive)
    local pkgname="$(epm print name for package "$1" 2>/dev/null)"
    local repackcode="$EPM_REPACK_SCRIPTS_DIR/$pkgname.sh"
    [ -s "$repackcode" ]
}

__epm_check_repack_rule()
{
    # skip repacking on non ALT systems
    [ "$BASEDISTRNAME" = "alt" ] || return 1

    local i
    for i in $* ; do
        # skip for packages built with repack
        epm_status_repacked "$i" && return 1

        __epm_have_repack_rule "$i" || return 1
    done
    return 0
}

__epm_check_if_needed_repack()
{
    __epm_check_repack_rule "$@" || return
    local pkgname="$(epm print name for package "$1")"
    warning "There is repack rule for '$pkgname' package. It is better install this package via 'epm install --repack' or 'epm play'."
}

# 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_replaced_pkgs $pkg"
    done

    [ -n "$split_replaced_pkgs" ]
}


__check_stoplist()
{
    local pkg="$1"
    local alf="$CONFIGDIR/repackstoplist.list"
    [ -s "$alf" ] || return 1
    [ -n "$pkg" ] || return 1
    grep -E -q "^$1$" $alf
}


# arg: <package file>
# sets:
#   alpkg      - resulted package file name in the current dir
#   SUBGENERIC - name of generic file's extension
__prepare_source_package()
{
    local pkg="$1"

    alpkg=$(basename $pkg)

    # TODO: use func for get name from deb pkg
    # TODO: epm print name from deb package
    local pkgname="$(echo $alpkg | sed -e "s|_.*||")"

    # TODO: use stoplist only for deb?
    [ -z "$force" ] && __check_stoplist $pkgname && fatal "Please use official package instead of $alpkg repacking (It is not recommended to use --force to skip this checking."

    SUBGENERIC=''

    if rhas "$alpkg" "\.(rpm|deb)$" ; then
        # skip packing for supported directly: rpm and deb
        return
    fi

    # convert tarballs to tar (for alien)
    load_helper epm-pack

    # they will fill $returntarname
    if rihas "$alpkg" "\.AppImage$" ; then
        # big hack with $pkg_urls_downloaded (it can be a list, not a single url)
        __epm_pack_run_handler generic-appimage "$pkg" "" "$pkg_urls_downloaded"
        SUBGENERIC='appimage'
    elif rhas "$alpkg" "\.snap$" ; then
        __epm_pack_run_handler generic-snap "$pkg"
        SUBGENERIC='snap'
    else
        __epm_pack_run_handler generic-tar "$pkg"
        SUBGENERIC='tar'
    fi

    # it is possible there are a few files, we don't support it
    [ -s "$returntarname" ] || fatal "Can't read result from pack: '$returntarname' is not a readable file."

    alpkg=$(basename $returntarname)
    # FIXME: looks like a hack with current dir
    if [ "$(pwd)" != "$(dirname "$returntarname")" ] ; then
        cp $verbose $returntarname $alpkg
        [ -r "$returntarname.eepm.yaml" ] && cp $verbose $returntarname.eepm.yaml $alpkg.eepm.yaml
    fi
}



# used in epm install
__epm_repack_single()
{
    local pkg="$1"
    case $PKGFORMAT in
        rpm)
            load_helper epm-repack-rpm
            __epm_repack_to_rpm "$pkg" || return
            ;;
        deb)
            if __epm_have_repack_rule "$pkg" ; then
                # we have repack rules only for rpm, so use rpm step in any case
                load_helper epm-repack-rpm
                load_helper epm-repack-deb
                __epm_repack_to_rpm "$pkg" || return
                [ -n "$repacked_pkg" ] || return
                __epm_repack_to_deb $repacked_pkg || return
            else
                load_helper epm-repack-deb
                __epm_repack_to_deb "$pkg" || return
            fi
            ;;
        *)
            fatal "$PKGFORMAT is not supported for repack yet"
            ;;
    esac

    return 0
}

# fill repacked_pkgs
__epm_repack()
{
    local pkg
    repacked_pkgs=''
    for pkg in $* ; do
        __epm_repack_single "$pkg" || fatal "Error with $pkg repacking."
        [ -n "$repacked_pkgs" ] && repacked_pkgs="$repacked_pkgs $repacked_pkg" || repacked_pkgs="$repacked_pkg"
    done
}


__epm_repack_if_needed()
{
    # return 1 if there is a package in host package format
    __epm_split_by_pkg_type $PKGFORMAT "$@" && return 1

    __epm_repack "$@"
    return 0
}

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
        __download_pkg_urls
        pkg_urls=
    fi

    [ -n "$pkg_names" ] && warning "Can't find $pkg_names files"
    [ -z "$pkg_files" ] && info "Skip empty repack list" && return 22

    if __epm_repack $pkg_files && [ -n "$repacked_pkgs" ] ; then
        if [ -n "$install" ] ; then
            epm install $repacked_pkgs
            return
        fi

        cp $repacked_pkgs "$EPMCURDIR"
        if [ -z "$quiet" ] ; then
            echo
            echo "Adapted packages:"
            for i in $repacked_pkgs ; do
                echo "    $EPMCURDIR/$(basename "$i")"
            done
        fi
    fi

}