#!/usr/bin/env bash

set -euo pipefail
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
readonly ROOT RESULTS="${ROOT}/results" IMAGE="serein-ddd-04-node"
cd "${ROOT}"
milliseconds() { perl -MTime::HiRes=time -e 'printf "%.0f\n", time * 1000'; }
capture() {
  local name="$1" expectation="$2"
  shift 2
  local directory="${RESULTS}/${name}" started finished exit_code
  mkdir -p "${directory}"
  printf '%q ' "$@" | sed -E 's/[[:space:]]+$//' >"${directory}/command.txt"; printf '\n' >>"${directory}/command.txt"
  started="$(milliseconds)"; set +e; "$@" >"${directory}/output.txt.tmp" 2>&1; exit_code=$?; set -e; finished="$(milliseconds)"
  sed -E -e 's/[[:space:]]+$//' -e '${/^$/d;}' "${directory}/output.txt.tmp" >"${directory}/output.txt"; rm "${directory}/output.txt.tmp"
  printf 'expectation=%s\nexit_code=%s\nduration_ms=%s\n' "${expectation}" "${exit_code}" "$((finished - started))" >"${directory}/metadata.txt"
  [[ "${expectation}" == pass && ${exit_code} -eq 0 ]] || [[ "${expectation}" == fail && ${exit_code} -ne 0 ]]
}
mutation_case() {
  local name="$1" temporary source
  temporary="$(mktemp -d)"
  capture "mutations/${name}/generate" pass node mutate.mjs "${name}" "${temporary}"
  source="$(node -e "const fs=require('fs');console.log(JSON.parse(fs.readFileSync(process.argv[1])).source)" "${RESULTS}/mutations/${name}/generate/output.txt")"
  capture "diffs/${name}" fail diff -u --label "${source} (clean)" --label "${source} (${name})" "${ROOT}/${source}" "${temporary}/${source}"
  capture "negative/${name}" fail docker run --rm --volume "${temporary}:/candidate:ro" "${IMAGE}" node verify.mjs /candidate
  rm -rf "${temporary}"
}
rm -rf "${RESULTS}"; mkdir -p "${RESULTS}"
capture setup/build pass docker build --tag "${IMAGE}" .
capture environment/node pass docker run --rm "${IMAGE}" node --version
capture positive/tests pass docker run --rm "${IMAGE}" node --test tests/*.test.mjs
capture analysis/contract pass docker run --rm "${IMAGE}" node verify.mjs
capture analysis/comparison pass docker run --rm "${IMAGE}" node render-comparison.mjs
for mutation in http-implies-ohs omit-consumer language-without-owner \
  redefine-v1-quantity change-v1-unit required-v1-field remove-current-enum \
  accept-unknown-version accept-unknown-enum collapse-version-axes \
  auth-break-same-service schema-without-consumer \
  claim-migration-without-version retire-active-v1 target-is-current \
  consumer-semantic-fork remove-support-owner weighted-score; do
  mutation_case "${mutation}"
done
capture sources/primary pass docker run --rm "${IMAGE}" node source-evidence.mjs
capture provenance/manifest pass docker run --rm "${IMAGE}" node source-manifest.mjs
capture verification/results pass docker run --rm --volume "${RESULTS}:/experiment/results:ro" "${IMAGE}" node verify-results.mjs
echo "DDD-04 evidence retained in ${RESULTS}"
