#!/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 docker image across CI
## runs. The image is built by docker/derivative-maker-docker-run's
## build_docker_image() via 'docker build', whose Dockerfile RUNs
## derivative-maker-docker-setup (an apt-get install of build-host tools that
## hits the mirrors directly - not the in-container approx cache). On ephemeral
## runners the image is rebuilt every run. Caching it lets build_docker_image's
## 'docker images' guard find it and skip the rebuild, so those packages are
## not re-downloaded.
##
## Complements ci/approx-cache-sidecar, which caches the OTHER apt workload:
## the in-container build's target-OS packages fetched through approx.
##
## Paired with an actions/cache step over $HOME/.dm-docker-image; the cache-key
## carries a hashFiles('docker/**') so a Dockerfile/setup change rebuilds. No
## restore-keys (G-A-007).
##
## Usage (from .github/workflows/local-build.yml):
##   ./ci/dm-docker-image-cache load    # if cache-hit, before the build
##   ./ci/dm-docker-image-cache save    # if cache-miss, after the build

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-manages the docker image
## store); mirrors ci/approx-cache-sidecar's 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 image_ref (it builds "${IMG}:$(uname --machine)").
image_arch="$(uname --machine)"
img="Kicksecure/derivative-maker-docker:${image_arch}"
cache_dir="${HOME}/.dm-docker-image"
image_tar="${cache_dir}/image.tar"

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

case "${1:-}" in
   load)
      ## Cache miss leaves no tar; nothing to load (build_docker_image will
      ## build the image itself).
      [ -f "${image_tar}" ] || exit 0
      ## A corrupted tar (partial write, disk/cache issue) must NOT block CI:
      ## treat a docker-load failure as a cache miss and drop the bad tar, so
      ## build_docker_image rebuilds the image instead of the job aborting.
      ## 'rm' (not safe-rm): a GitHub-hosted runner has no safe-rm installed,
      ## and the path is a fixed cache file, not user input.
      ## style-ok: no-safe-rm
      if ! sudo --non-interactive -- docker load --input "${image_tar}"; then
         printf '%s\n' "${BASH_SOURCE[0]}: WARNING: docker load failed; cache tar may be corrupted. Rebuilding the image." >&2
         rm --force -- "${image_tar}"
      fi
      ;;
   save)
      mkdir --parents -- "${cache_dir}"
      ## 'docker save' as root (the harness builds via 'sudo docker'); then
      ## hand the tar to the runner so actions/cache can read it on post.
      sudo --non-interactive -- docker save "${img}" --output "${image_tar}"
      sudo --non-interactive -- chown -- "${runner_uid_gid}" "${image_tar}"
      ;;
   *)
      printf '%s\n' "usage: ${BASH_SOURCE[0]} <load|save>" >&2
      exit 64
      ;;
esac
