#!/usr/bin/env bash
#MISE description="Run the Go test suite"
set -euo pipefail

# Docker Compose project names are global on a developer machine, while tests may
# run this task from different worktrees. The scope keeps reusable test containers
# shared within one worktree without letting another checkout attach to them.
export TERAL_TEST_CONTAINER_SCOPE="${TERAL_TEST_CONTAINER_SCOPE:-$PWD}"

test_container_scope_hash="$(printf "%s" "${TERAL_TEST_CONTAINER_SCOPE}" | shasum -a 256 | cut -c1-12)"
export TERAL_TEST_COMPOSE_PROJECT="teral-test-${test_container_scope_hash}"

cleanup_test_containers() {
  local status=$?

  # The test helpers intentionally reuse containers across Go test processes
  # so integration tests do not pay Docker startup cost for every test target.
  # The shared containers should live for the duration of this mise task only.
  # Preserve the test runner's exit status and ignore Docker cleanup failures
  # so a teardown problem does not hide the original test result.
  docker compose -f "pkg/testutil/docker-compose.test.yaml" -p "${TERAL_TEST_COMPOSE_PROJECT}" down --volumes >/dev/null 2>&1 || true

  # Restate is not shared: every test gets its own container in its own project,
  # named after the scope plus the owning pid. The helpers remove theirs, and the
  # next run reaps any left by a killed process, but sweeping here keeps a killed
  # suite from leaving containers behind until someone runs tests again.
  #
  # The grep exits non-zero when there is nothing to reap, which is the normal
  # case, so the whole search is guarded: under `set -e` it would otherwise
  # abort this trap before the exit below and report a passing suite as failed.
  local abandoned_projects=""
  abandoned_projects="$(docker compose ls --all --format json 2>/dev/null \
    | grep -oE "\"Name\":\"${TERAL_TEST_COMPOSE_PROJECT}-[a-z]+-[0-9]+-[0-9]+\"" \
    | cut -d'"' -f4)" || true

  for project in ${abandoned_projects}; do
    docker compose -f "pkg/testutil/docker-compose.test.yaml" -p "${project}" down --volumes >/dev/null 2>&1 || true
  done

  exit "${status}"
}
trap cleanup_test_containers EXIT

rask "$@"
