#!/bin/sh
#
# Copyright (C) 2023  Etersoft
# Copyright (C) 2023  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-repack

[ -n "$EPM_PACK_SCRIPTS_DIR" ] || EPM_PACK_SCRIPTS_DIR="$CONFIGDIR/pack.d"


# args: packname/packscript
get_pack_script()
{
    local packscript="$1"
    is_abs_path "$packscript" || packscript="$EPM_PACK_SCRIPTS_DIR/$1.sh"
    echo "$packscript"
}

has_pack_script()
{
    local packscript="$(get_pack_script "$1")"
    [ -f "$packscript.rpmnew" ] && warning 'There is .rpmnew file ${packscript}.rpmnew. The pack script can be outdated.'
    [ -s "$packscript" ]
}


# <packname> <abstarname> [packversion]
# fills returntarname with returned tar name or empty
__epm_pack_run_handler()
{
    local packname="$1"
    local tarname="$2"
    local packversion="$3"
    local url="$4"
    local checksum="$5"
    shift 5
    returntarname=''

    if [ -n "$checksum" ] ; then
        print_sha256sum --checksum "$checksum" $tarname
    else
        print_sha256sum "$checksum" $tarname
    fi

    local packscript="$(get_pack_script "$packname")"
    has_pack_script "$packscript" || return

    # a file to keep filename of generated tarball
    filefortarname="$(pwd)/filefortarname"

    [ "$PROGDIR" = "/usr/bin" ] && SCPATH="$PATH" || SCPATH="$PROGDIR:$PATH"
    local bashopt=''
    [ -n "$debug" ] && bashopt='-x'
    #info "Running $($script --description 2>/dev/null) ..."
    # TODO: add url info here
    ( unset BASH_ENV ; unset EPMCURDIR ; export PATH=$SCPATH ; export HOME=$(pwd) ; docmd $CMDSHELL $bashopt $packscript "$tarname" "$filefortarname" "$packversion" "$url" "$@") || fatal
    returntarname="$(cat "$filefortarname")" || fatal 'pack script $packscript didn'\''t set tarname'

    local i
    for i in $returntarname ; do
        [ -s "$i" ] || fatal 'pack script for $packname returned a non-existent file $i'
    done

    return 0
}

# we run this function in a tmpdir
__epm_pack()
{
    local packname="$1"
    local packversion="$3"
    local URL="$4"
    local checksum="$5"

    # fills returntarname with packed tar
    __epm_pack_run_handler "$@" || fatal 'Can'\''t find pack script for packname $packname'

    if [ -n "$download_only" ] ; then
        mv $returntarname "$EPMCURDIR"
        return
    fi

    # TODO: merge eepm.yaml here (common with $returntarname.eepm.yaml)
    # add upstream_url: $URL too

    # note: this repack related code here for follow reasons:
    #  * repack by default if we have repack rule
    #  * get repacked files
    #  * install (repacked) files
    # the most replacement is epm repack [--install] or epm install [--repack]

    # FIXME: check for every package would be more reliable
    # by default
    dorepack='--repack'
    # don't repack by default there is our pkg format
    __epm_split_by_pkg_type $PKGFORMAT $returntarname && dorepack=''
    # repack if we have a repack rule for it
    [ -z "$norepack" ] && __epm_check_repack_rule $returntarname && dorepack='--repack'
    # repack if forced
    [ -n "$repack" ] && dorepack='--repack'

    local pkgnames
    if [ -n "$dorepack" ]  ; then
        # TODO: where .eepm.yaml?
        [ -n "$EPM_REPACK_VERSION" ] || EPM_REPACK_VERSION="$packversion"
        __epm_repack $returntarname
        [ -n "$repacked_pkgs" ] || fatal "Can't repack $returntarname"
        # remove packed file if we have repacked one
        rm -f $returntarname
        pkgnames="$repacked_pkgs"
    else
        pkgnames="$returntarname"
    fi

    if [ -n "$install" ] ; then
        docmd epm install $pkgnames
        return
    fi

    # we need put result in the cur dir
    mv -v $pkgnames "$EPMCURDIR" || fatal

    local i
    for i in $returntarname ; do
        [ -r "$i.eepm.yaml" ] && mv -v "$i.eepm.yaml" "$EPMCURDIR"
    done

    return 0
}

__list_all_pack_rules()
{
    cd $EPM_PACK_SCRIPTS_DIR || fatal
    for i in *.sh ; do
       local name=$(basename $i .sh)
       startwith "$name" "common" && continue
       echo "$name"
    done
    cd - >/dev/null
}

epm_pack_help()
{
    message '
epm pack - create rpm package from files
Usage: epm pack [options] <packname> <tar|url|dir> [version]
Options:
    <packname>            - receipt
    <dir>                 - create tarball from the dir before
    <url>                 - download tar from url
    [version]             - force version for unversioned sources
    --install             - install after pack result
    --repack              - force repack ever if returned package can be installed without repack
    --download-only       - save pack result and exit
    --save-only           - save repacked packages and exit (this is default behaviour)
    --list                - list all available receipts
'
}


epm_pack()
{

case "$1" in
    -h|--help)                     # HELPCMD: help
        epm_pack_help
        return
        ;;
    --list)                        # HELPCMD: list all available receipts
        __list_all_pack_rules
        return
        ;;
    "")
        fatal "Missed pack rule. run with --help to get help."
        ;;
esac

    local tmpdir
    tmpdir="$(mktemp -d --tmpdir=$BIGTMPDIR)" || fatal
    remove_on_exit "$tmpdir"

    local packname="$1"
    local tarname="$2"
    local packversion="$3"
    local checksum="$4"
    local url=''
    shift 4

    if is_url "$tarname"; then
        url="$tarname"
        pkg_urls="$tarname"
        load_helper epm-download
        cd $tmpdir || fatal

        __download_pkg_urls
        pkg_urls=

        [ -n "$pkg_files" ] || fatal 'Can'\''t download $tarname'
        tarname="$(realpath "$pkg_files")"
    elif [ -d "$tarname" ] ; then
        tarname="$(realpath "$tarname")"
    elif [ -s "$tarname" ] ; then
        # get full path for real name
        tarname="$(realpath "$tarname")"
    else
        # just pass name
        true
    fi

    cd $tmpdir || fatal
    __epm_pack "$packname" "$tarname" "$packversion" "$url" "$checksum" "$@"

}
