#!/bin/bash

## Copyright (C) 2026 - 2026 ENCRYPTED SUPPORT LLC <adrelanos@whonix.org>
## See the file COPYING for copying conditions.

## AI-Assisted

## Runner-side helper that caches the derivative-maker build's apt package
## downloads across CI runs. Adapts the developer-meta-files
## apt-install-with-cache pattern (runner-owned sidecar + seed/snapshot) to
## the approx package cache the docker build mounts.
##
## docker-run's CACHER_VOLUME ($HOME/approx_cache_mnt) is chowned to the
## in-container approx uid/gid (101:102, mode 770) by its volume_prepare(),
## so the unprivileged runner cannot 'tar' it directly - the exact
## root-owned-dir case actions/cache must avoid. actions/cache therefore
## operates on a runner-owned sidecar; this script seeds the approx dir from
## the sidecar before the build and snapshots newly-downloaded packages back
## after.
##
## Usage (from .github/workflows/local-build.yml):
##   ./ci/approx-cache-sidecar seed       # after actions/cache restore, before build
##   ./ci/approx-cache-sidecar snapshot   # after the build (if: always)
##
## The paired actions/cache step MUST NOT use restore-keys (G-A-007): its
## cache-key carries a hashFiles() so a workflow/package change invalidates.

set -o errexit
set -o nounset
set -o pipefail
set -o errtrace
shopt -s inherit_errexit
shopt -s shift_verbose

## No sensible developer-machine invocation (it sudo-chowns a cache dir to the
## approx uid); mirrors developer-meta-files' apt-install-with-cache guard.
if [ "${CI:-}" != "true" ] && [ "${ALLOW_LOCAL:-}" != "true" ]; then
   printf '%s\n' "${BASH_SOURCE[0]}: refusing to run outside CI (CI != 'true'). Set ALLOW_LOCAL=true to override." >&2
   exit 1
fi

## Must match docker-run's CACHER_VOLUME path + volume_prepare's chown target
## (VOLUMES entry "${CACHER_VOLUME}" "101:102" "770"). Pre-seeding the dir with
## these exact perms makes volume_prepare's 'if [ ! -d ]' guard skip it,
## leaving the seeded contents in place for the in-container approx.
approx_dir="${HOME}/approx_cache_mnt"
sidecar_dir="${HOME}/.approx-cache-sidecar"
## Pinned at image build: docker-setup pre-creates the 'approx' user/group
## with these fixed ids before installing the approx package, so this literal
## is guaranteed correct rather than dependent on dynamic system-uid allocation.
approx_uid_gid="101:102"
approx_mode="770"

runner_uid_gid="$(id -u):$(id -g)"

case "${1:-}" in
   seed)
      mkdir --parents -- "${sidecar_dir}" "${approx_dir}"
      ## Runner-to-runner copy (no sudo needed); empty sidecar (cache miss) is
      ## a no-op. Then apply the approx uid/gid + mode volume_prepare expects.
      cp --archive --update=none -- "${sidecar_dir}/." "${approx_dir}/"
      sudo --non-interactive -- chown --recursive -- "${approx_uid_gid}" "${approx_dir}"
      sudo --non-interactive -- chmod --recursive -- "${approx_mode}" "${approx_dir}"
      ;;
   snapshot)
      [ -d "${approx_dir}" ] || exit 0
      mkdir --parents -- "${sidecar_dir}"
      ## approx_dir is now approx-owned (101:102); sudo to read it, then hand
      ## the sidecar back to the runner so actions/cache can tar it on post.
      sudo --non-interactive -- cp --archive --update=none -- "${approx_dir}/." "${sidecar_dir}/"
      sudo --non-interactive -- chown --recursive -- "${runner_uid_gid}" "${sidecar_dir}"
      ;;
   *)
      printf '%s\n' "usage: ${BASH_SOURCE[0]} <seed|snapshot>" >&2
      exit 64
      ;;
esac
