#!/usr/bin/env bash
# sdtm-check — run every SDTM delivery-conformance check over a directory.
#
#   sdtm-check <sdtm-dir> [-o outdir] [--expect DM,AE,LB] [--strict]
#   sdtm-check --selftest
#   sdtm-check --demo
#
# Exit code is 0 whenever the checks RAN, mirroring the individual scripts —
# findings are data for a reviewer, not a failure. Pass --strict for CI gating,
# which exits 1 if any check reports a blocking finding.
set -uo pipefail

HERE="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# Works from the repo (scripts/) and from inside the step image (/opt/clincoder).
if   [ -d "$HERE/../scripts" ];  then S="$HERE/../scripts"
elif [ -d /opt/clincoder ];      then S=/opt/clincoder
else echo "sdtm-check: cannot locate check scripts" >&2; exit 2; fi

SAMPLES=/root/mediforce/apps/landing-zone/sample-data

usage() { sed -n '2,10p' "${BASH_SOURCE[0]}" | sed 's/^# \{0,1\}//'; }

selftest() {
  local fail=0
  for t in structural consistency temporal ct-conformance; do
    printf '  %-16s ' "$t"
    if out=$(cd "$S/.." && Rscript "scripts/test-$t.R" 2>&1); then echo "$out"
    else echo "FAILED"; echo "$out" | tail -5 | sed 's/^/      /'; fail=1; fi
  done
  [ "$fail" -eq 0 ] && echo "self-test: all suites passed" || echo "self-test: FAILURES above" >&2
  return "$fail"
}

case "${1:-}" in
  ""|-h|--help) usage; exit 0 ;;
  --selftest)   echo "running check test suites:"; selftest; exit $? ;;
  --demo)
    d=$(mktemp -d)
    Rscript "$S/make-fixture.R" "$d" >/dev/null || { echo "fixture generation failed" >&2; exit 2; }
    echo "generated a delivery with known defects at $d"
    echo
    exec "${BASH_SOURCE[0]}" "$d" ;;
esac

DIR="$1"; shift
OUT=""; EXPECT=""; STRICT=0
while [ $# -gt 0 ]; do
  case "$1" in
    -o|--out)    OUT="${2:-}"; shift 2 ;;
    --expect)    EXPECT="${2:-}"; shift 2 ;;
    --strict)    STRICT=1; shift ;;
    *) echo "sdtm-check: unknown option '$1'" >&2; exit 2 ;;
  esac
done
[ -d "$DIR" ] || { echo "sdtm-check: no such directory: $DIR" >&2; exit 2; }
[ -n "$OUT" ] || OUT=$(mktemp -d)
mkdir -p "$OUT"

echo "SDTM delivery: $DIR"
echo "reports:       $OUT"
echo
printf '%-14s %10s %10s   %s\n' "CHECK" "FINDINGS" "BLOCKING" "DETAIL"

total_block=0; ran=0
run_one() {
  local name="$1" script="$2" json="$OUT/$3"; shift 3
  local line
  if ! line=$(Rscript "$S/$script" "$DIR" "$json" "$@" 2>&1); then
    printf '%-14s %10s %10s   %s\n' "$name" "-" "-" "ERROR: $(echo "$line" | tail -1)"
    return
  fi
  ran=$((ran+1))
  local f b
  f=$(python3 -c "import json;print(json.load(open('$json'))['findings_count'])" 2>/dev/null || echo "?")
  b=$(python3 -c "import json;print(json.load(open('$json'))['blocking_count'])" 2>/dev/null || echo "?")
  [ "$b" != "?" ] && total_block=$((total_block + b))
  printf '%-14s %10s %10s   %s\n' "$name" "$f" "$b" "$(basename "$json")"
}

run_one structural   structural-check.R      structural-findings.json  "$EXPECT"
run_one consistency  consistency-check.R     consistency-findings.json
run_one temporal     temporal-check.R        temporal-findings.json
run_one terminology  ct-conformance-check.R  ct-findings.json

echo
if [ "$total_block" -gt 0 ]; then
  echo "$total_block blocking finding(s) — a reviewer must adjudicate before the delivery is accepted:"
  python3 - "$OUT" <<'PY'
import json, sys, pathlib
for p in sorted(pathlib.Path(sys.argv[1]).glob("*findings.json")):
    try: d = json.load(open(p))
    except Exception: continue
    for f in d.get("findings") or []:
        if not f.get("blocking"): continue
        bits = [f"{k}={v}" for k, v in f.items()
                if k in ("domain","variable","usubjid","value","visitnum","start","end") and v]
        print(f"  [{d['check']}] {f.get('issue')}  " + "  ".join(str(b) for b in bits))
PY
else
  echo "no blocking findings."
fi
echo
echo "$ran/4 checks ran."

[ "$STRICT" -eq 1 ] && [ "$total_block" -gt 0 ] && exit 1
exit 0
