#!/bin/sh

#----------------------------------------------------------------------
# Generated files from the upstream tarball (before repacking) are
# excluded from the repacked .orig tarball, so we need to generate them
# back at build time.  This script can be used to list missing files
# after building the debs.
# Dependencies: curl, jq
# Copyright © 2020 Guilhem Moulin <guilhem@debian.org>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU 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 General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
#----------------------------------------------------------------------

set -ue
PATH="/usr/bin:/bin"
export PATH

VERBOSE=
if [ "${1-}" = "-v" ] || [ "${1-}" = "--verbose" ]; then
    VERBOSE="y"
    shift
fi

if [ $# -ne 0 ]; then
    printf "Usage: %s [--verbose]\\n" "$0" >&2
    exit 1
fi

for bin in wget jq; do
    if ! command -v "$bin" >/dev/null; then
        printf "ERROR: \`%s\` is not in PATH\\n" "$bin" >&2
        exit 1
    fi
done

SOURCE_NAME="$(dpkg-parsechangelog -S Source)"
VERSION="$(dpkg-parsechangelog -S Version)"
UPSTREAM_VERSION="${VERSION%-*}"
UPSTREAM_VERSION="${UPSTREAM_VERSION%+dfsg*}"
UPSTREAM_VERSION="$(printf "%s" "$UPSTREAM_VERSION" | sed -r 's/~(alpha|beta|rc)(\d*)$/-\1\2/')"
SEP="--8<---------------------------------------------------------------->8--"

TEMPDIR="$(mktemp --tmpdir --directory "$SOURCE_NAME-$UPSTREAM_VERSION.XXXXXXXX")"
trap 'rm -rf "$TEMPDIR"' EXIT INT TERM

for f in /etc/devscripts.conf ~/.devscripts; do
    [ ! -f "$f" ] || . "$f"
done

# Assume gbp's export-dir is uscan's $USCAN_DESTDIR
DESTDIR="${USCAN_DESTDIR:-".."}"

# Not ideal to hardcode the URL here but our debian/watch file uses git tags
SOURCE_URL="https://github.com/roundcube/roundcubemail/releases/download/$UPSTREAM_VERSION/roundcubemail-$UPSTREAM_VERSION.tar.gz"

# Download a tarball and extract to "$TEMPDIR/${2-"$SOURCE_NAME"}"
download() {
    local url="$1" ext="${1##*/}" component="${2-"$SOURCE_NAME"}" destfile
    case "$ext" in
        *.tar.bz2) ext="tar.bz2";;
        *.tar.gz) ext="tar.gz";;
        *.tar.xz) ext="tar.xz";;
        *) ext="${ext##*.}";;
    esac
    destfile="$component.$ext"

    printf "Downloading %s…\\n" "$url" >&2
    curl -fS -Lo "$TEMPDIR/$destfile" "$url"
    rm -rf -- "$TEMPDIR/$component"
    extract "$TEMPDIR/$destfile" "$TEMPDIR/$component"
}

extract() {
    local archive="$1" destdir="$2"
    mkdir "$destdir"
    case "$archive" in
        *.tar.bz2) tar -C "$destdir" -xjf "$archive";;
        *.tar.gz) tar -C "$destdir" -xzf "$archive";;
        *.tar.xz) tar -C "$destdir" -xJf "$archive";;
        *.zip) unzip -q -x "$archive" -d "$destdir";;
        *) printf "ERROR: Don't know how to extract %s!\\n" "$archive" >&2; exit 1;;
    esac
}

find_sort() {
    # `tr | sort | tr` to emulate a sorted FS-traversal
    find -- "$@" -printf "%P\\n" | tr "/" "\\0" | sort | tr "\\0" "/"
}

# Download and unpack orig tarball
download "$SOURCE_URL"

# Download and unpack extra components
for p in "$TEMPDIR/$SOURCE_NAME/"*/jsdeps.json; do JSDEPS="$p"; break; done
TINYMCE_VERSION="$(jq -r ".dependencies | map(select (.lib == \"tinymce\")) [0].version" <"$JSDEPS")"
TINYMCE_URL="$(jq -r ".dependencies | map(select (.lib == \"tinymce\")) [0].url" <"$JSDEPS")"
TINYMCE_URL="$(printf "%s" "$TINYMCE_URL" | sed -r "s/\\b\\\$v\\b/$TINYMCE_VERSION/g")"
download "$TINYMCE_URL" "tinymce"

TINYMCELANGS_URL="$(jq -r ".dependencies | map(select (.lib == \"tinymce-langs\")) [0].url" <"$JSDEPS")"
TINYMCELANGS_URL="$(printf "%s" "$TINYMCELANGS_URL" | sed -r "s/\\b\\\$v\\b/$TINYMCE_VERSION/g")"
download "$TINYMCELANGS_URL" "tinymce-langs"


# Extract packages
mkdir "$TEMPDIR/pkg"
for pkg in $(sed -n "s/Package:\\s*//p" debian/control); do
    for deb in "$DESTDIR/${pkg}_${VERSION}" "$DESTDIR/${pkg}_${VERSION}"_*.deb; do
        if [ -e "$deb" ]; then
            dpkg -x "$deb" "$TEMPDIR/pkg"
            break
        fi
    done
done

compare() {
    local installdir="$1" url="$2" name="${3-"$SOURCE_NAME"}" orig_tarball p
    for p in "$DESTDIR/${SOURCE_NAME}_${VERSION%-*}".orig${3+"-$3"}.*; do orig_tarball="$p"; break; done
    extract "$orig_tarball" "$TEMPDIR/$name.repacked"
    find_sort "$TEMPDIR/$name"/* >"$TEMPDIR/alist"
    find_sort "$TEMPDIR/$name.repacked"/* >"$TEMPDIR/blist"

    diff -- "$TEMPDIR/alist" "$TEMPDIR/blist" >"$TEMPDIR/list-diff" && return || true

    printf "INFO upstream archive %s contains %d files\\n" "${url##*/}" "$(wc -l <"$TEMPDIR/alist")"
    printf "INFO repacked archive %s contains %d files (-%d, +%d)\\n" "${orig_tarball##*/}" "$(wc -l <"$TEMPDIR/blist")" \
        "$(grep -c "^< " <"$TEMPDIR/list-diff")" "$(grep -c "^> " <"$TEMPDIR/list-diff")"

    if [ "$VERBOSE" = "y" ]; then
        printf "%s\\n" "$SEP"
        ! diff -u --color="auto" --label="a/${url##*/}" --label="b${orig_tarball##*/}" \
            -- "$TEMPDIR/alist" "$TEMPDIR/blist"
        printf "%s\\n" "$SEP"
    fi

    sed -n -i "s/^< //p" "$TEMPDIR/list-diff"

    if [ -z "${3+x}" ]; then
        # Cf. debian/patches/use-system-JQueryUI.patch.  We remove these from
        # the diff as missing "js/i18n/$package-$lang_l.min.js" files is an
        # issue for libjs-jquery-ui not us.
        sed -ri "\,^plugins/jqueryui/js/i18n/datepicker-[[:alnum:]_-]+\.js$,d" "$TEMPDIR/list-diff"
    elif [ "$3" = "tinymce" ]; then
        # Cf. jsdeps.json
        sed -ni "s,^js/tinymce/,,p" "$TEMPDIR/list-diff"
        sed -i "\,^jquery\.tinymce\.min\.js$,d" "$TEMPDIR/list-diff"
        sed -i "\,^themes/mobile/,d" "$TEMPDIR/list-diff"
    fi

    while IFS= read -r p; do
        p2="$TEMPDIR/pkg/${installdir#/}/${p%/}"
        if [ ! -h "$p2" ] && [ ! -e "$p2" ]; then
            printf "%s\\n" "$p" >>"$TEMPDIR/missing"
        fi
    done <"$TEMPDIR/list-diff"

    local rv=0
    if [ -s "$TEMPDIR/missing" ]; then
        printf "ERROR %d files found in the orig tarball but not in any .deb:\\n" "$(wc -l <"$TEMPDIR/missing")"
        cat <"$TEMPDIR/missing"
        rv=1
    else
        printf "OK All %d files excluded during repacking are rebuilt anew and shipped by one of our .deb\\n" \
           "$(wc -l <"$TEMPDIR/list-diff")"
    fi
    return $rv
}

RV=0
compare "/usr/share/roundcube" "$SOURCE_URL" || RV=1
compare "/usr/share/roundcube/program/js/tinymce" "$TINYMCE_URL" "tinymce" || RV=1
compare "/usr/share/roundcube/program/js/tinymce/langs" "$TINYMCELANGS_URL" "tinymce-langs" || RV=1
exit $RV
