#!/usr/bin/env bash
# Run-scoped TEMP/TMP owner for the Linux CI test leg.
#
# Tests and their force-killed descendants may never reach Rust destructors. The workflow
# parent therefore owns one directory outside the test process tree, reaps processes first,
# and invokes this script's cleanup phase while the runner step is still alive.
set -euo pipefail

PHASE="${1:?usage: test-temp-sandbox.sh <setup|cleanup>}"
PREFIX="spt-test-tmp-"

ci_error() {
  echo "::error::$*"
}

require_env() {
  local name=$1
  if [ -z "${!name:-}" ]; then
    ci_error "CI-TMP: required environment variable $name is empty"
    exit 1
  fi
}

case "$PHASE" in
  setup)
    require_env RUNNER_TEMP
    require_env GITHUB_ENV

    run_id="${GITHUB_RUN_ID:-local}"
    run_attempt="${GITHUB_RUN_ATTEMPT:-0}"
    sandbox=$(mktemp -d -- "${RUNNER_TEMP%/}/${PREFIX}${run_id}-${run_attempt}-XXXXXX")

    if ! {
      printf 'SPT_CI_TEST_TMP=%s\n' "$sandbox"
      printf 'TEMP=%s\n' "$sandbox"
      printf 'TMP=%s\n' "$sandbox"
      # Rust's Unix temp_dir implementation reads TMPDIR; TEMP/TMP remain set for
      # cross-platform helpers and child processes that honor those conventional names.
      printf 'TMPDIR=%s\n' "$sandbox"
    } >> "$GITHUB_ENV"; then
      rm -rf -- "$sandbox"
      ci_error "CI-TMP: could not publish sandbox environment"
      exit 1
    fi

    echo "CI-TMP setup: $sandbox"
    ;;

  cleanup)
    sandbox="${SPT_CI_TEST_TMP:-}"
    if [ -z "$sandbox" ]; then
      echo "CI-TMP cleanup: setup did not create a sandbox"
      exit 0
    fi
    require_env RUNNER_TEMP

    if [ ! -e "$sandbox" ] && [ ! -L "$sandbox" ]; then
      echo "CI-TMP cleanup: already absent: $sandbox"
      exit 0
    fi

    if ! runner_root=$(readlink -f -- "$RUNNER_TEMP"); then
      ci_error "CI-TMP: could not resolve RUNNER_TEMP: $RUNNER_TEMP"
      exit 1
    fi
    if ! sandbox_root=$(readlink -f -- "$sandbox"); then
      ci_error "CI-TMP cleanup cannot resolve sandbox; it remains or is an unsafe link: $sandbox"
      exit 1
    fi
    parent=${sandbox_root%/*}
    leaf=${sandbox_root##*/}
    if [ "$parent" != "$runner_root" ]; then
      ci_error "CI-TMP: refusing to recursively remove sandbox outside RUNNER_TEMP: $sandbox_root"
      exit 1
    fi
    case "$leaf" in
      "$PREFIX"*) ;;
      *)
        ci_error "CI-TMP: refusing to recursively remove sandbox without $PREFIX prefix: $sandbox_root"
        exit 1
        ;;
    esac

    for attempt in 1 2 3 4 5; do
      if ! rm -rf -- "$sandbox_root"; then
        echo "::warning::CI-TMP cleanup attempt $attempt/5 could not remove $sandbox_root"
      fi
      if [ ! -e "$sandbox_root" ] && [ ! -L "$sandbox_root" ]; then
        echo "CI-TMP cleanup: removed $sandbox_root on attempt $attempt/5"
        exit 0
      fi
      if [ "$attempt" -lt 5 ]; then
        echo "::warning::CI-TMP cleanup attempt $attempt/5 left $sandbox_root; retrying"
        sleep "$attempt"
      fi
    done

    ci_error "CI-TMP cleanup failed after 5 attempts; sandbox remains: $sandbox_root"
    exit 1
    ;;

  *)
    ci_error "usage: test-temp-sandbox.sh <setup|cleanup>"
    exit 2
    ;;
esac
