#!/bin/sh
# Copyright 2026 California Institute of Technology
#
# You should have received a copy of the licensing terms for this
# software included in the file “LICENSE” located in the top-level
# directory of this package. If you did not, you can view a copy at
# http://dcc.ligo.org/M1500244/LICENSE.txt
#
# Manage the upstream tarballs for the current debian/changelog version:
#   term-scope_<ver>.orig.tar.xz         (tree at git tag v<ver>)
#   term-scope_<ver>.orig-vendor.tar.xz  (cargo vendor of the crate deps)
#
# debian/tarball-checksums records two sha256s per tarball:
#   *.tar     the uncompressed content — authoritative and reproducible
#             on any machine (git archive / cargo vendor / fixed tar
#             options are deterministic)
#   *.tar.xz  the released compressed bytes — reproducible only with
#             the same xz version (compressor output changes between
#             Debian releases, e.g. xz >= 5.8 block-splits by default)
#
# For a new version (no recorded checksums) the script generates the
# tarballs and records both sums.  For a recorded version it verifies
# what is in the parent directory, regenerating any missing tarball
# first: a content (.tar) mismatch is a hard error, while a compressed
# (.xz) mismatch with matching content just means a different
# compressor — fine for local builds, but do NOT upload such a tarball
# for an already-released version; fetch the released one instead
# (apt-get source / origtargz, or copy it from the release area).
#
# Run from the top of the repository on the debian branch.  Generating
# needs the vX.Y.Z tag, and network access for cargo vendor.

set -eu

PKG=term-scope
VERSION=$(dpkg-parsechangelog -SVersion | sed 's/-[0-9.]*$//')
TAG="v${VERSION}"
CHECKSUMS=debian/tarball-checksums
ORIG="${PKG}_${VERSION}.orig.tar.xz"
VENDOR="${PKG}_${VERSION}.orig-vendor.tar.xz"

WORKDIR=$(mktemp -d)
trap 'rm -rf "${WORKDIR}"' EXIT

recorded_sum() {
    awk -v f="$1" '$2 == f { print $1 }' "${CHECKSUMS}" 2>/dev/null
}

require_tag() {
    if ! git rev-parse -q --verify "refs/tags/${TAG}" >/dev/null; then
        echo "error: tag ${TAG} not found; tag the release on main first" >&2
        exit 1
    fi
}

# Write the uncompressed orig tar to stdout.
gen_orig_tar() {
    git archive --format=tar --prefix="${PKG}-${VERSION}/" "${TAG}"
}

# Write the uncompressed vendor tar to stdout.  Deterministic tar
# output: fixed order, ownership, and timestamps.
gen_vendor_tar() {
    require_tag
    echo "Vendoring crate dependencies for ${TAG}" >&2
    git archive --format=tar --prefix=src/ "${TAG}" | tar -x -C "${WORKDIR}"
    (cd "${WORKDIR}/src" && cargo vendor --locked vendor >/dev/null)
    tar -C "${WORKDIR}/src" --sort=name --owner=0 --group=0 \
        --numeric-owner --mtime="@$(git log -1 --format=%ct "${TAG}")" \
        -cf - vendor
}

# Single-threaded xz: multithreaded output is block-split and varies
# with thread count, even on one machine.
compress() {
    xz -9 -T1
}

generate() {
    # $1 = tarball file name, writes ../$1
    echo "Generating ../$1"
    case "$1" in
        *orig-vendor*) gen_vendor_tar | compress > "../$1" ;;
        *)             require_tag; gen_orig_tar | compress > "../$1" ;;
    esac
}

# --- New release: generate everything and record ---------------------
if [ -z "$(recorded_sum "${ORIG}")$(recorded_sum "${VENDOR}")" ]; then
    for f in "${ORIG}" "${VENDOR}"; do
        generate "${f}"
        (cd .. && sha256sum "${f}") >> "${CHECKSUMS}"
        printf '%s  %s\n' \
            "$(xz -dc "../${f}" | sha256sum | cut -d' ' -f1)" \
            "${f%.xz}" >> "${CHECKSUMS}"
    done
    echo "Recorded checksums in ${CHECKSUMS}; commit it.  Treat the"
    echo "tarballs as release artifacts: publish/copy them, since other"
    echo "compressor versions cannot regenerate identical .xz bytes."
    exit 0
fi

# --- Recorded version: regenerate what is missing, then verify -------
status=0
for f in "${ORIG}" "${VENDOR}"; do
    [ -f "../${f}" ] || generate "${f}"

    rec_tar=$(recorded_sum "${f%.xz}")
    rec_xz=$(recorded_sum "${f}")
    act_tar=$(xz -dc "../${f}" | sha256sum | cut -d' ' -f1)
    act_xz=$(cd .. && sha256sum "${f}" | cut -d' ' -f1)

    if [ "${act_tar}" != "${rec_tar}" ]; then
        echo "error: ../${f}: CONTENT does not match ${CHECKSUMS}" >&2
        echo "  recorded ${f%.xz}: ${rec_tar}" >&2
        echo "  actual:            ${act_tar}" >&2
        status=1
    elif [ "${act_xz}" != "${rec_xz}" ]; then
        echo "note: ../${f}: content verified, but the compressed bytes"
        echo "  differ from the released tarball (different xz version)."
        echo "  Fine for local builds; do NOT upload this file for an"
        echo "  already-released version — fetch the released tarball."
    else
        echo "Verified ${f} (byte-identical to release)"
    fi
done
exit "${status}"
