#!/bin/bash
#
# Check that the github repo has the same package and db files as the given local folder.
#

echo2() { echo "$@" >&2 ; }

DIE() {
    echo2 "Error: $1"
    exit 1
}

NameCheck() {
    local xx yy
    for xx in "$@" ; do
        for yy in $remotefilelist ; do
            test "$xx" = "$yy" && break
        done
        if [ "$xx" = "$yy" ] ; then
            echo2 "    OK: $xx"
        else
            echo2 "file $xx missing from $MIRROR_NAME !"
            problemfiles+="$xx "
        fi
    done
}

ContentsCheck() {
    local xx remfiles=""
    local failcode=0

    sleep 1      # github has problems if fetching fast and repeatedly ???

    for xx in "$@" ; do
        remfiles+="$MIRROR_URL/$xx "
    done

    pushd $tmpdir >/dev/null
    if false ; then
        wget -q --timeout=20 --show-progress $remfiles || failcode=$?
    else
        curl --location --remote-time --max-time 20 --remote-name-all --progress-bar --fail $remfiles || failcode=$?
    fi
    popd >/dev/null

    if [ $failcode -ne 0 ] ; then
        echo2 "Error: fetching github files failed (code $failcode)."
        problemfiles+="$remfiles "
        return $failcode
    fi

    for xx in "$@" ; do
        cmp $xx $tmpdir/$xx >/dev/null
        if [ $? -eq 0 ] ; then
            echo2 "    OK: $xx"
        else
            echo2 "file $xx is different !"
            problemfiles+="$xx "
        fi
        rm -f $tmpdir/$xx
    done
}

Usage() {
    local progname="$(basename $0)"
    cat <<EOF >&2
$progname: Check the validity of $SIGNER packages in the $MIRROR_NAME mirror.

Usage: $progname [parameters]
parameters:
    --slow        Check contents of each file.
    --fast        Check just the name of all package files.
    --optimized   Check contents of some files, and names of other files.
    --no-filelist Don't generate list of latest files into the repo.
    folder-name   Name of the local folder that contains package files.
                  If not given, current folder is used.
EOF
}

Main()
{
    if [ 1 -eq 1 ] ; then
        if [ ! -r assets.conf ] ; then
            DIE "no assets.conf found!"
        fi
        source assets.conf
        local MIRROR_NAME=Github
        local MIRROR_URL=""
        local findpart=""
        if [ -z "$REPO_COMPRESSOR" ] ; then
            local REPO_COMPRESSOR=xz
        fi
        case "$SIGNER" in
            EndeavourOS)
                case "$REPONAME" in
                    endeavouros | endeavouros_calamares)
                        MIRROR_URL=https://github.com/endeavouros-team/mirrors/releases/tag/"${RELEASE_TAGS[0]}"
                        findpart=/endeavouros-team/mirrors/releases/download/"${RELEASE_TAGS[0]}"/
                        ;;
                    endeavouros-testing-dev)
                        MIRROR_URL=https://github.com/endeavouros-team/repo-testing/releases/tag/"${RELEASE_TAGS[0]}"
                        findpart=/endeavouros-team/repo-testing/releases/download/"${RELEASE_TAGS[0]}"/
                        ;;
                    *)
                        DIE "sorry, unsupported repo name '$REPONAME'."
                        ;;
                esac
                ;;
            *)
                MIRROR_URL=https://github.com/$REPO_OWNER/$REPONAME/releases/tag/"${RELEASE_TAGS[0]}"/
                findpart=/$REPO_OWNER/$REPONAME/releases/download/"${RELEASE_TAGS[0]}"/
                ;;
        esac
    else
        local conf=/etc/eos-mirrorcheck.conf
        test -r $conf || DIE "configuration file $conf is required but not found."
        source $conf
        test -n "$MIRROR_URL"  || DIE "variable MIRROR_URL has no value, check file $conf."
        test -n "$MIRROR_NAME" || DIE "variable MIRROR_NAME has no value, check file $conf."
    fi

    local folder=""
    local remotefilelist
    local packages repofiles
    local problemfiles=""
    local arg

    # options
    local mode=fast   # show, optimized, fast
    local has_filelist=no

    for arg in "$@" ; do
        case "$arg" in
            --2) : # not used anymore
                 # check mirror2 instead of mirror1
                 # MIRROR_URL=https://github.com/endeavouros-team/mirrors/releases/tag/"${RELEASE_TAGS[1]}"
                 # findpart=/endeavouros-team/mirrors/releases/download/"${RELEASE_TAGS[1]}"/
                 ;;
            --slow) mode=slow ;;
            --fast) mode=fast ;;
            --optimized) mode=optimized ;;
            --filelist) has_filelist=yes ;;   # use repofiles.txt
            -*) Usage ; return ;;
            *) folder="$arg" ;;
        esac
    done

    test -n "$folder" || folder=.
    test -d "$folder" || DIE "folder $folder does not exist!"
#    test -r "$folder/endeavouros.db" || {
#        echo2 "$(basename $0): nothing to see here."
#        return
#    }

    echo2 "Fetching $MIRROR_NAME package info..."
    remotefilelist="$(curl -s "$MIRROR_URL" | grep $findpart | sed -e 's|^.*'$findpart'||' -e 's|" rel=.*$||')"
    test -n "$remotefilelist" || DIE "cannot fetch package info from '$MIRROR_URL'."
    MIRROR_URL="$(echo "$MIRROR_URL" | sed 's|/tag/|/download/|')"

    pushd "$folder" >/dev/null

    packages="$(ls -1 *.pkg.tar.*)"

    local SigLevel="$(grep -A3 "^\[$REPONAME\]$" /etc/pacman.conf | grep "^SigLevel = " | awk '{print $3}')"
    case "$SigLevel" in
        Required) repofiles="$(echo $REPONAME.{db,files}{,.tar.$REPO_COMPRESSOR}{,.sig})" ;;
        *)        repofiles="$(echo $REPONAME.{db,files}{,.tar.$REPO_COMPRESSOR})" ;;
    esac

    # Check files. 'NameCheck' is very fast but unreliable. 'ContentsCheck' is quite slow but reliable.
    local tmpdir=$(mktemp -d)
    ContentsCheck $repofiles                 # This should make sure all is OK ! (?)
    if [ "$has_filelist" = "yes" ] ; then
        ContentsCheck repofiles.txt
    fi

    case "$mode" in
        fast)
            NameCheck $packages
            ;;
        slow)
            ContentsCheck $packages
            ;;
        optimized)
            for arg in $packages ; do
                case "$arg" in
                    # icon theme packages are very big
                    paper-icon-theme-*.pkg.tar.xz | paper-icon-theme-*.pkg.tar.zst | \
                    arc-x-icons-theme-*.pkg.tar.xz | arc-x-icons-theme-*.pkg.tar.zst)
                        NameCheck "$arg" ;;
                    *)
                        ContentsCheck "$arg" ;;
                esac
            done
            ;;
    esac
    rm -rf $tmpdir

    if [ -z "$problemfiles" ] ; then
        echo2 "No issues."
    else
        echo2 -n "Problematic files: "
        echo $problemfiles
    fi
    popd >/dev/null
}

Main "$@"
