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

alt_base_dist_url="http://ftp.basealt.ru/pub/distributions"

__use_url_install()
{
    # force download if wildcard is used
    echo "$pkg_urls" | grep -q "[?*]" && return 1

    # force download if repack is asked
    [ -n "$repack" ] && return 1

    # install of remote files has a side affect
    # (more fresh package from a repo can be installed instead of the file)
    #case $DISTRNAME in
    #    "ALTLinux")
    #        # do not support https yet
    #        echo "$pkg_urls" | grep -q "https://" && return 1
    #        pkg_names="$pkg_names $pkg_urls"
    #        return 0
    #        ;;
    #esac

    case $PMTYPE in
        #apt-rpm)
        #    pkg_names="$pkg_names $pkg_urls"
        #    ;;
        #deepsolver-rpm)
        #    pkg_names="$pkg_names $pkg_urls"
        #    ;;
        #urpm-rpm)
        #    pkg_names="$pkg_names $pkg_urls"
        #    ;;
        pacman)
            true
            ;;
        yum-rpm|dnf-rpm)
            true
            ;;
        #zypper-rpm)
        #    pkg_names="$pkg_names $pkg_urls"
        #    ;;
        *)
            return 1
            ;;
    esac
    [ -n "$pkg_names" ] && pkg_names="$pkg_names $pkg_urls" || pkg_names="$pkg_urls"
    return 0
}

# some heuristic to detect if we need download only latest package
__check_if_wildcard_downloading()
{
    mask="$(basename "$1")"
    is_wildcard "$mask" || return 1

    local fn
    fn="$(docmd eget --list "$url" | xargs -n1 basename 2>/dev/null)"
    # just return if there is no answer
    [ -n "$fn" ] || return 0

    local wf="$(epm print shortname from filename $fn | wc -l)"
    local ws="$(epm print shortname from filename $fn | sort -u | wc -l)"
    # not the same package of various versions
    [ "$wf" = "$ws" ]
}

# for download before install / checking
__download_pkg_urls()
{
    local url
    [ -z "$pkg_urls" ] && return
    for url in $pkg_urls ; do
        local tmppkg
        tmppkg="$(mktemp -d --tmpdir=$BIGTMPDIR)" || fatal
        remove_on_exit $tmppkg
        chmod $verbose a+rX $tmppkg
        cd $tmppkg || fatal

        local latest='--latest'
        __check_if_wildcard_downloading "$url" && latest=''

        # download packages
        if docmd eget $latest "$url" ; then
            local i
            for i in * ; do
                [ "$i" = "*" ] && warning 'Incorrect true status from eget. No saved files from download $url, ignoring' && continue
                [ -s "$tmppkg/$i" ] || continue
                chmod $verbose a+r "$tmppkg/$i"
                local si="$(echo "$i" | sed -e 's| |-|g')"
                if [ "$si" != "$i" ] ; then
                    info "Space detected in the downloaded file '$i', removing spaces ..."
                    mv -v "$tmppkg/$i" "$tmppkg/$si"
                    i="$si"
                fi
                si="$(echo "$i" | sed -e 's|\?.*||g')"
                if [ "$si" != "$i" ] ; then
                    info "Arg sign ? detected in the downloaded file '$i', removing args from filename ..."
                    mv -v "$tmppkg/$i" "$tmppkg/$si"
                    i="$si"
                fi
                [ -n "$pkg_files" ] && pkg_files="$pkg_files $tmppkg/$i" || pkg_files="$tmppkg/$i"
                [ -n "$pkg_urls_downloaded" ] && pkg_urls_downloaded="$pkg_urls_downloaded $url" || pkg_urls_downloaded="$url"
            done
        else
            warning "Failed to download $url, ignoring"
        fi
        cd - >/dev/null
    done
    # reconstruct
    pkg_filenames=$(strip_spaces "$pkg_files $pkg_names")
}

# NOTE: call __clean_downloaded_pkg_files after
__handle_pkg_urls_to_install()
{
    #[ -n "$pkg_urls" ] || return

    # FIXME: check type of pkg_urls separately?
    if [ "$(get_package_type "$pkg_urls")" != $PKGFORMAT ] || ! __use_url_install ; then
        # use workaround with eget: download and put in pkg_files
        __download_pkg_urls
    fi

    pkg_urls=
}

__handle_pkg_urls_to_checking()
{
    #[ -n "$pkg_urls" ] || return

    # use workaround with eget: download and put in pkg_files
    __download_pkg_urls

    pkg_urls=
}


# obsoleted
__epm_get_altpkg_url()
{
    info "TODO: https://packages.altlinux.org/api/branches"
    load_helper epm-site
    local arch=$(paoapi packages/$1 | get_pao_var arch)
    # FIXME: arch can be list
    [ "$arch" = "noarch" ] || arch=$(arch)
    # HACK: filename can be list
    local filename=$(paoapi packages/$1 | get_pao_var filename | grep $arch)
    [ -n "$filename" ] || fatal "Can't get filename"
    # fixme: get from /branches
    local dv=$DISTRNAME/$DISTRVERSION/branch
    [ "$DISTRVERSION" = "Sisyphus" ] && dv=$DISTRNAME/$DISTRVERSION
    echo "$alt_base_dist_url/$dv/$arch/RPMS.classic/$filename"
}

# obsoleted
__epm_print_url_alt()
{
    local url="$1"
    echo "$url"
    echo "$url" | sed -e "s|$alt_base_dist_url/$DISTRNAME|http://mirror.yandex.ru/altlinux|g"
    echo "$url" | sed -e "s|$alt_base_dist_url/$DISTRNAME|http://download.etersoft.ru/pub/ALTLinux|g"
}

__epm_print_url_alt_check()
{
    local pkg=$1
    shift
    local tm
    tm="$(mktemp)" || fatal
    remove_on_exit $tm
    assure_exists curl
    load_helper epm-site
    quiet=1
    local buildtime=$(paoapi packages/$pkg | get_pao_var buildtime)
    echo
    message 'Latest release:' $(paoapi packages/$pkg | get_pao_var sourcepackage) $buildtime
    __epm_print_url_alt "$1" | while read url ; do
        eget --get-response $url >$tm || { echo "$url: missed" ; continue ; }
        local http=$(cat $tm | grep "^HTTP" | sed -e "s|\r||g")
        local lastdate=$(cat $tm | grep "^Last-Modified:" | sed -e "s|\r||g")
        local size=$(cat $tm | grep "^Content-Length:" | sed -e "s|^Content-Length: ||g"  | sed -e "s|\r||g")
        echo "$url ($http $lastdate) $(message "Size:") $size"
    done
    rm -f $tm
}

__epm_download_alt()
{
    local pkg
    if [ "$1" = "--check" ] ; then
        local checkflag="$1"
        shift
    fi

    load_helper epm-sh-altlinux

    # TODO: enable if install --download-only will works
    if tasknumber "$@" >/dev/null ; then
        load_helper epm-addrepo
        load_helper epm-reposave
        load_helper epm-removerepo
        load_helper epm-Install

        local installlist="$(get_task_packages $*)"
        # hack: drop -devel packages to avoid package provided by multiple packages
        installlist="$(estrlist reg_exclude ".*-devel .*-devel-static .*-checkinstall .*-debuginfo" "$installlist")"
        [ -n "$verbose" ] && info 'Packages from task(s): $installlist'

        try_change_alt_repo
        epm_addrepo "$@"
        epm update
        [ -n "$verbose" ] && epm repo list
        docmd epm download $print_url $installlist
        epm_removerepo "$@"
        end_change_alt_repo

        return
    fi

    info "Cleaning apt cache for correct result ..."
    epm --quiet clean

    # old systems ignore reinstall ?
    for pkg in "$@" ; do
        for i in $(sudocmd apt-get install -y --print-uris --reinstall "$pkg" | cut -f1 -d " " | grep ".rpm'$" | sed -e "s|^'||" -e "s|'$||") ; do
            echo "$(basename "$i")" | grep -q "^$pkg" || continue
            [ -n "$print_url" ] && echo "$i" && continue
            eget "$i"
        done
    done
    return

    # old code:
    for pkg in "$@" ; do
        local url=$(__epm_get_altpkg_url $pkg)
        [ -n "$url" ] || warning "Can't get URL for $pkg"
        if [ -n "$checkflag" ] ; then
            __epm_print_url_alt_check "$pkg" "$url"
        else
            docmd eget $url || return
        fi
    done
}

epm_download()
{
    local CMD

    case "$BASEDISTRNAME" in
        "alt")
            __epm_download_alt $*
            return
            ;;
    esac

    case $PMTYPE in
    apt-dpkg)
        if [ -n "$print_url" ] ; then
            docmd apt-get download --print-uris $* | cut -f1 -d " " | grep ".deb'$" | sed -e "s|^'||" -e "s|'$||"
            return
        fi
        docmd apt-get download $*
        ;;
    dnf-rpm|dnf5-rpm)
        sudocmd dnf download $print_url $*
        ;;
    aptcyg)
        sudocmd apt-cyg download $*
        ;;
    packagekit)
        docmd pkcon download $*
        ;;
    yum-rpm)
        # TODO: check yum install --downloadonly --downloaddir=/tmp <package-name>
        assure_exists yumdownloader yum-utils
        sudocmd yumdownloader $*
        ;;
    dnf-rpm)
        sudocmd dnf download $*
        ;;
    urpm-rpm)
        sudocmd urpmi --no-install $URPMOPTIONS $@
        ;;
    tce)
        sudocmd tce-load -w $*
        ;;
    opkg)
        docmd opkg $*
        ;;
    eopkg)
        docmd eopkg fetch $*
        ;;
    homebrew)
        docmd brew fetch $*
        ;;
    *)
        fatal 'Have no suitable command for $PMTYPE'
        ;;
    esac
}