#!/usr/bin/env bash

set -euo pipefail

ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
RESULTS="${ROOT}/results"
IMAGE="serein-pers-02-reconstitution"
readonly ROOT RESULTS IMAGE

if [[ "${RESULTS}" != "${ROOT}/results" ]]; then
  echo "refusing to clear an unexpected results directory" >&2
  exit 65
fi

cd "${ROOT}"

milliseconds() { perl -MTime::HiRes=time -e 'printf "%.0f\n", time * 1000'; }

capture() {
  local name="$1" expected="$2"
  shift 2
  local directory="${RESULTS}/${name}" started finished actual
  mkdir -p "${directory}"
  { printf '%q' "$1"; for argument in "${@:2}"; do printf ' %q' "${argument}"; done; printf '\n'; } >"${directory}/command.txt"
  started="$(milliseconds)"
  set +e
  "$@" >"${directory}/output.txt.tmp" 2>&1
  actual=$?
  set -e
  finished="$(milliseconds)"
  sed -E -e 's/[[:space:]]+$//' -e '${/^$/d;}' "${directory}/output.txt.tmp" >"${directory}/output.txt"
  rm "${directory}/output.txt.tmp"
  printf 'expected_exit_code=%s\nexit_code=%s\nduration_ms=%s\n' "${expected}" "${actual}" "$((finished - started))" >"${directory}/metadata.txt"
  if [[ ${actual} -ne ${expected} ]]; then
    echo "FAILED: ${name} exited ${actual}; expected ${expected}" >&2
    return 1
  fi
  printf '%-52s exit %s as expected\n' "${name}" "${actual}"
}

in_container() { docker run --rm --volume "${RESULTS}:/experiment/results" "${IMAGE}" "$@"; }
evidence_case() {
  docker run --rm --volume "${RESULTS}/behavior/$1:/artifacts" --env ARTIFACT_DIR=/artifacts "${IMAGE}" php tests/run.php "$1"
}
mutant_case() { docker run --rm "${IMAGE}" sh -lc "php mutate.php $1 && php tests/run.php $2"; }
mutant_analysis() { docker run --rm "${IMAGE}" sh -lc "php mutate.php $1 && php analyze.php"; }
mutation_diff() { docker run --rm "${IMAGE}" sh -lc "cp $2 /tmp/original.php && php mutate.php $1 >/dev/null && diff -u /tmp/original.php $2"; }

rm -rf "${RESULTS}/analysis" "${RESULTS}/behavior" "${RESULTS}/diffs" "${RESULTS}/environment" "${RESULTS}/negative" "${RESULTS}/setup" "${RESULTS}/sources" "${RESULTS}/verification"
mkdir -p "${RESULTS}"

capture setup/build 0 docker build --load --tag "${IMAGE}" .
capture environment/php 0 in_container php --version
capture sources/primary 0 in_container php source-evidence.php
capture analysis/inventory 0 in_container php analyze.php
capture behavior/full-suite 0 in_container php tests/run.php --all

for case_name in current-creation creation-refusals legacy-load unknown-status identity-version lifecycle-mismatch corrupt-lines framework-evidence; do
  capture "behavior/${case_name}" 0 evidence_case "${case_name}"
done

capture negative/load-through-creation 1 mutant_case load-through-creation legacy-load
capture negative/record-during-reconstitution 1 mutant_case record-during-reconstitution legacy-load
capture negative/apply-current-deadline-on-load 1 mutant_case apply-current-deadline-on-load legacy-load
capture negative/accept-unknown-status 1 mutant_case accept-unknown-status unknown-status
capture negative/default-empty-identity 1 mutant_case default-empty-identity identity-version
capture negative/reset-stored-version 1 mutant_case reset-stored-version legacy-load
capture negative/recalculate-stored-total 1 mutant_case recalculate-stored-total corrupt-lines
capture negative/create-then-clear-in-mapper 1 mutant_analysis create-then-clear-in-mapper

capture diffs/load-through-creation 1 mutation_diff load-through-creation src/OrderMapper.php
capture diffs/record-during-reconstitution 1 mutation_diff record-during-reconstitution src/Order.php
capture diffs/apply-current-deadline-on-load 1 mutation_diff apply-current-deadline-on-load src/Order.php
capture diffs/accept-unknown-status 1 mutation_diff accept-unknown-status src/Order.php
capture diffs/default-empty-identity 1 mutation_diff default-empty-identity src/Order.php
capture diffs/reset-stored-version 1 mutation_diff reset-stored-version src/Order.php
capture diffs/recalculate-stored-total 1 mutation_diff recalculate-stored-total src/Order.php
capture diffs/create-then-clear-in-mapper 1 mutation_diff create-then-clear-in-mapper src/OrderMapper.php

capture verification/results 0 in_container php verify-results.php
echo "Evidence retained in ${RESULTS}"
