#!/usr/bin/env bash
set -euo pipefail

RSYNC_VERSION="${RSYNC_VERSION:-3.3.0}"
RSYNC_SRC_BASE="${RSYNC_SRC_BASE:-https://download.samba.org/pub/rsync/src}"
RSYNC_TARBALL="${RSYNC_TARBALL:-rsync-${RSYNC_VERSION}.tar.gz}"
RSYNC_TARBALL_SHA256="${RSYNC_TARBALL_SHA256:-}"

os="$(uname -s | tr '[:upper:]' '[:lower:]')"
arch="$(uname -m)"
if [[ "${arch}" == "aarch64" || "${arch}" == "arm64" ]]; then arch="arm64"; fi
if [[ "${arch}" == "x86_64" ]]; then arch="x86_64"; fi

if [[ "${os}" != "linux" ]]; then
  echo "build-rsync: supported on linux only (for reproducible official builds). Use system rsync on ${os} or build on a native runner." >&2
  exit 2
fi

repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
mkdir -p "${repo_root}/src/assets/rsync"
out="${repo_root}/src/assets/rsync/rsync_release_${os}_${arch}.bin"

tmp="$(mktemp -d)"
cleanup() { rm -rf "${tmp}"; }
trap cleanup EXIT

url="${RSYNC_SRC_BASE}/${RSYNC_TARBALL}"
sig_url_asc="${url}.asc"
sig_url_sig="${url}.sig"

echo "fetching ${url}"
curl -fsSL "${url}" -o "${tmp}/rsync.tar.gz"

verified=0
if command -v gpg >/dev/null 2>&1; then
  sig_file=""
  sig_url=""
  if curl -fsSL "${sig_url_asc}" -o "${tmp}/rsync.tar.gz.asc"; then
    sig_file="${tmp}/rsync.tar.gz.asc"
    sig_url="${sig_url_asc}"
  elif curl -fsSL "${sig_url_sig}" -o "${tmp}/rsync.tar.gz.sig"; then
    sig_file="${tmp}/rsync.tar.gz.sig"
    sig_url="${sig_url_sig}"
  fi

  if [[ -n "${sig_file}" ]]; then
    echo "verifying signature ${sig_url}"
    if gpg --batch --verify "${sig_file}" "${tmp}/rsync.tar.gz"; then
      verified=1
    else
      echo "build-rsync: gpg signature check failed (often because the public key is not in your keyring)." >&2
    fi
  fi
fi

if [[ "${verified}" -ne 1 ]]; then
  # Try to fetch official SHA256 first
  sha256_url="${url}.sha256"
  if curl -fsSL "${sha256_url}" -o "${tmp}/rsync.tar.gz.sha256" 2>/dev/null; then
    expected_sha256="$(cat "${tmp}/rsync.tar.gz.sha256" | tr -d ' \n' | cut -d' ' -f1)"
    echo "verifying sha256 (from official source) for ${url}"
    actual_sha256="$(sha256sum "${tmp}/rsync.tar.gz" | cut -d' ' -f1)"
    if [[ "${actual_sha256}" != "${expected_sha256}" ]]; then
      echo "build-rsync: sha256 mismatch!" >&2
      echo "  expected: ${expected_sha256}" >&2
      echo "  actual:   ${actual_sha256}" >&2
      exit 2
    fi
    echo "${tmp}/rsync.tar.gz: OK"
  elif [[ -n "${RSYNC_TARBALL_SHA256}" ]]; then
    # Fallback to embedded SHA256
    echo "verifying sha256 (embedded fallback) for ${url}"
    actual_sha256="$(sha256sum "${tmp}/rsync.tar.gz" | cut -d' ' -f1)"
    if [[ "${actual_sha256}" != "${RSYNC_TARBALL_SHA256}" ]]; then
      echo "build-rsync: sha256 mismatch!" >&2
      echo "  expected: ${RSYNC_TARBALL_SHA256}" >&2
      echo "  actual:   ${actual_sha256}" >&2
      exit 2
    fi
    echo "${tmp}/rsync.tar.gz: OK"
  else
    echo "build-rsync: could not verify ${url} (no gpg signature and no SHA256 available)." >&2
    echo "Set RSYNC_TARBALL_SHA256=<expected sha256> or install gpg with trusted key." >&2
    exit 2
  fi
fi

tar -C "${tmp}" -xzf "${tmp}/rsync.tar.gz"
set +o pipefail
extract_dir="$(tar -tzf "${tmp}/rsync.tar.gz" | head -n 1 | cut -d/ -f1)"
set -o pipefail
cd "${tmp}/${extract_dir}"

CC=musl-gcc CFLAGS="-O2" LDFLAGS="-static" ./configure --disable-xxhash --disable-zstd --disable-lz4 --disable-openssl
make -j"$(getconf _NPROCESSORS_ONLN 2>/dev/null || echo 2)"

mkdir -p "$(dirname "${out}")"
cp rsync "${out}"
chmod +x "${out}"
echo "built ${out}"
