#!/bin/bash

set -e

export ZSTD_CLEVEL=19
export ZSTD_NBTHREADS="$(nproc)"

pub=/srv/msys2repo
staging=/home/repo/staging

SIGNWITHKEY=()
if [ -n "${GPGKEY}" ]
then
    SIGNWITHKEY=(-u "${GPGKEY}")
    gpg --recv-key "0x${GPGKEY}"
fi
gpg --detach-sign "${SIGNWITHKEY[@]}" "${0}"
rm "${0}.sig"

(
    shopt -s nullglob
    for f in "${staging}"/*/*/*.{pkg,src}.tar.zst
    do
        echo "$f"

        # Verify that the archives aren't corrupt or truncated etc.
        zstd --quiet --test "$f"

        # Sign, if not already
        test -f "$f.sig" || gpg --detach-sign "${SIGNWITHKEY[@]}" "$f"

        # Make sure the signature file got written properly
        gpg --list-packets "$f.sig" > /dev/null
    done
)

update_packages() {
    local repo="${1}"
    shift
    local path="${1}"
    shift
    local srcpath="${1}"
    shift

    # Skip embedded signatures for everything but msys
    # https://github.com/msys2/msys2-devtools/issues/5
    local repo_options=()
    if [ "${repo}" = "msys" ]; then
        repo_options=(--include-sigs)
    fi

    local files=( $(find "${staging}/${path}" -name "*.pkg.tar.*" -not -name "*.sig") )
    if [ "${#files[@]}" -gt 0 ]
    then
        echo "==> ${path}"

        cp "${pub}/${path}/${repo}".{db,files}{,.tar.zst}{,.sig} "${staging}/${path}/"
        repo-add "${repo_options[@]}" -n -p -s -v "${staging}/${path}/${repo}.db.tar.zst" "${files[@]}"
        zstd --quiet --test "${staging}/${path}/${repo}.db.tar.zst"
        zstd --quiet --test "${staging}/${path}/${repo}.files.tar.zst"
        gpg --verify "${staging}/${path}/${repo}.db.tar.zst.sig" "${staging}/${path}/${repo}.db.tar.zst"
        gpg --verify "${staging}/${path}/${repo}.files.tar.zst.sig" "${staging}/${path}/${repo}.files.tar.zst"
        mv "${staging}/${path}"/* "${pub}/${path}/"

        # check packages
        inrepo="$(bsdtar -xOf "${pub}/${path}/${repo}.db.tar.zst" "*/desc" | grep -A 1 %FILENAME% | sed -e '/^%FILENAME%$/d' -e '/^--$/d' | sed -r 's/^(.*)$/\1\n\1.sig/' | sort)"
        infs="$(find "${pub}/${path}" -name "*.pkg.tar.*" -printf '%f\n' | sort)"
        for f in $(echo "${inrepo}" | grep -vxF -f <(echo "${infs}"))
        do
            echo "==> WARNING: '${f}' is missing."
        done

        # check sources
        inrepo="$(bsdtar -xOf "${pub}/${path}/${repo}.db.tar.zst" "*/desc" | grep -A 4 -e %BASE% | awk '/^%BASE%$/ { getline; printf "%s-", $0; getline; getline; getline; printf "%s\n", $0 }' | sort | uniq)"
        infs="$(find "${pub}/${srcpath}" -name "*.src.tar.*" -not -name "*.src.tar.*.sig" -printf '%f\n' | sort | rev | cut -d. -f 4- | rev)"
        for f in $(echo "${inrepo}" | grep -vxF -f <(echo "${infs}"))
        do
            echo "==> WARNING: '${f}.src.tar.*' is missing."
        done
        infssig="$(find "${pub}/${srcpath}" -name "*.src.tar.*.sig" -printf '%f\n' | sort | rev | cut -d. -f 5- | rev)"
        for f in $(echo "${inrepo}" | grep -vxF -f <(echo "${infssig}"))
        do
            echo "==> WARNING: '${f}.src.tar.*.sig' is missing."
        done

        echo
    fi
}

update_sources() {
    local path="${1}"
    shift

    if [ -n "$(find "${staging}/${path}/sources" -name "*.src.tar.*")" ]
    then
        echo "==> ${path}"
        mv "${staging}/${path}/sources"/* "${pub}/${path}/sources/"
    fi
}

update_sources mingw
update_sources msys

update_packages mingw64 "mingw/mingw64"  "mingw/sources"
update_packages mingw32 "mingw/mingw32"    "mingw/sources"
update_packages ucrt64  "mingw/ucrt64"  "mingw/sources"
update_packages clang64 "mingw/clang64" "mingw/sources"
update_packages clang32 "mingw/clang32" "mingw/sources"
update_packages clangarm64 "mingw/clangarm64" "mingw/sources"
update_packages mingwarm64 "mingw/mingwarm64" "mingw/sources"
update_packages msys    "msys/x86_64"   "msys/sources"
update_packages msys    "msys/i686"     "msys/sources"

date +%s > "${pub}/lastupdate"
