#!/usr/bin/env bash
set -euo pipefail

if ! command -v jq >/dev/null 2>&1; then
  echo "proof-replay requires jq for JSON field assertions." >&2
  exit 2
fi

ED_FI_BASE_URL="${ED_FI_BASE_URL:-https://platform3-andymontgomery-9773s-projects.vercel.app/ed_fi/1edtech/implementation/api}"
ED_FI_BASE_URL="${ED_FI_BASE_URL%/}"
RUN_ID="${RUN_ID:-skill-$(date -u +%Y%m%dT%H%M%SZ)-$$-${RANDOM:-0}}"
WORK_DIR="${WORK_DIR:-${TMPDIR:-/tmp}/edfi-skill-$RUN_ID}"
mkdir -p "$WORK_DIR"

auth_header=()
if [[ -z "${ED_FI_TOKEN:-}" ]]; then
  curl -fsS -X POST "$ED_FI_BASE_URL/dev/mint?tenantId=demo" -o "$WORK_DIR/token.json"
  ED_FI_TOKEN="$(jq -r '.token' "$WORK_DIR/token.json")"
fi
auth_header=(-H "Authorization: Bearer $ED_FI_TOKEN")

assert_jq() {
  local file="$1"
  local filter="$2"
  local message="$3"
  if ! jq -e "$filter" "$file" >/dev/null; then
    echo "ASSERTION FAILED: $message" >&2
    echo "File: $file" >&2
    jq '.' "$file" >&2 || true
    exit 1
  fi
}

assert_status() {
  local actual="$1"
  local expected="$2"
  local label="$3"
  if [[ "$actual" != "$expected" ]]; then
    echo "ASSERTION FAILED: $label returned HTTP $actual, expected $expected" >&2
    exit 1
  fi
}

header_value() {
  local name="$1"
  local file="$2"
  awk -v wanted="$name" 'BEGIN{IGNORECASE=1} $1 ~ "^" wanted ":" {sub(/\r$/, "", $2); print $2; exit}' "$file"
}

fetch_descriptor_by_code() {
  local catalog="$1"
  local code_value="$2"
  local namespace="$3"
  local out_json="$4"
  local out_headers="$5"
  local limit="${6:-100}"
  local encoded_code
  local encoded_namespace
  local query
  encoded_code="$(jq -rn --arg value "$code_value" '$value | @uri')"
  query="codeValue=$encoded_code&limit=$limit&offset=0"
  if [[ -n "$namespace" ]]; then
    encoded_namespace="$(jq -rn --arg value "$namespace" '$value | @uri')"
    query="codeValue=$encoded_code&namespace=$encoded_namespace&limit=$limit&offset=0"
  fi

  curl -fsS -D "$out_headers" \
    "$ED_FI_BASE_URL/ed-fi/descriptors/$catalog?$query" \
    "${auth_header[@]}" \
    -o "$out_json"
  if ! jq -e --arg code "$code_value" --arg namespace "$namespace" '.totalCount >= 1 and (.data | length) >= 1 and all(.data[]; .codeValue == $code and ($namespace == "" or .namespace == $namespace))' "$out_json" >/dev/null; then
    echo "ASSERTION FAILED: $catalog descriptor key filter returns $code_value" >&2
    echo "File: $out_json" >&2
    jq '.' "$out_json" >&2 || true
    exit 1
  fi
}

poll_job() {
  local kind="$1"
  local id="$2"
  local out_json="$3"
  local filter="$4"
  local message="$5"
  local attempts="${JOB_POLL_ATTEMPTS:-90}"
  local interval="${JOB_POLL_INTERVAL_SECONDS:-2}"
  local started_at
  started_at="$(date -u +%s)"

  for ((attempt = 1; attempt <= attempts; attempt += 1)); do
    curl -fsS "$ED_FI_BASE_URL/ed-fi/$kind/$id" \
      "${auth_header[@]}" \
      -o "$out_json"

    local state
    local elapsed
    state="$(jq -r '.data.state // "unknown"' "$out_json")"
    elapsed="$(($(date -u +%s) - started_at))"
    printf 'poll %s/%s attempt=%d/%d state=%s elapsed=%ss\n' "$kind" "$id" "$attempt" "$attempts" "$state" "$elapsed" >&2

    if jq -e "$filter" "$out_json" >/dev/null; then
      return 0
    fi

    if [[ "$state" == "completed" || "$state" == "completed_with_errors" || "$state" == "failed" ]]; then
      echo "ASSERTION FAILED: $message" >&2
      echo "File: $out_json" >&2
      jq '.' "$out_json" >&2 || true
      exit 1
    fi

    if (( attempt < attempts )); then
      sleep "$interval"
    fi
  done

  local elapsed
  elapsed="$(($(date -u +%s) - started_at))"
  echo "ASSERTION FAILED: $message did not become true within $attempts attempts (${elapsed}s elapsed)" >&2
  echo "File: $out_json" >&2
  jq '.' "$out_json" >&2 || true
  exit 1
}

curl -fsS "$ED_FI_BASE_URL" "${auth_header[@]}" -o "$WORK_DIR/root.json"
assert_jq "$WORK_DIR/root.json" '.module == "ed_fi" and .surface == "1edtech"' "root descriptor identifies Ed-Fi 1EdTech"
assert_jq "$WORK_DIR/root.json" '.counts.canonical_resources == 193 and .counts.descriptor_catalogs == 280 and .counts.total_routed_collections == 473' "root descriptor returns pinned route counts"
assert_jq "$WORK_DIR/root.json" '.links.customerWebsite and .links.dataDictionary and .links.endpointCatalog' "root descriptor returns documentation links"

fetch_descriptor_by_code "attendanceEventCategoryDescriptors" "In Attendance" "uri://ed-fi.org/AttendanceEventCategoryDescriptor" "$WORK_DIR/attendance-descriptors.json" "$WORK_DIR/attendance-descriptors.headers" 5
assert_jq "$WORK_DIR/attendance-descriptors.json" '.totalCount >= 1 and all(.data[]; .namespace == "uri://ed-fi.org/AttendanceEventCategoryDescriptor" and .codeValue == "In Attendance")' "attendance descriptor key filter includes the standard In Attendance value"
attendance_descriptor_uri="$(jq -r 'first(.data[] | select(.namespace == "uri://ed-fi.org/AttendanceEventCategoryDescriptor" and .codeValue == "In Attendance") | "\(.namespace)#\(.codeValue)")' "$WORK_DIR/attendance-descriptors.json")"

cat > "$WORK_DIR/attendance-create.payload.json" <<JSON
{
  "studentReference": {"studentUniqueId": "student-001"},
  "schoolReference": {"schoolId": 255901001},
  "sessionReference": {"schoolYear": 2026, "sessionName": "Spring Semester"},
  "attendanceEvent": {
    "eventDate": "$(date -u +%Y-%m-%d)",
    "attendanceEventCategoryDescriptor": "$attendance_descriptor_uri"
  },
  "schoolAttendanceDuration": 390,
  "student_sourced_id": "student-001",
  "school_sourced_id": "school-north-valley",
  "acmesis_class_sourced_id": "class-math7-p2"
}
JSON

attendance_status="$(curl -sS -D "$WORK_DIR/attendance-create.headers" -o "$WORK_DIR/attendance-create.json" -w "%{http_code}" \
  -X POST "$ED_FI_BASE_URL/ed-fi/studentSchoolAttendanceEvents" \
  "${auth_header[@]}" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: attendance-create-$RUN_ID" \
  --data-binary @"$WORK_DIR/attendance-create.payload.json")"
assert_status "$attendance_status" "201" "attendance create"
assert_jq "$WORK_DIR/attendance-create.json" '.data.edfi_local_id and .data.ack_id and .data.student_sourced_id == "student-001" and .data.school_sourced_id == "school-north-valley" and .data.class_sourced_id == "class-math7-p2" and (.data | has("acmesis_class_sourced_id") | not)' "attendance create returns local id, ack, and canonical roster overlays"
[[ "$(header_value x-platform3-attendance-policy "$WORK_DIR/attendance-create.headers")" == "edfi.attendance.teacher_mark.v2026-06-22" ]] || { echo "ASSERTION FAILED: attendance create returns teacher-mark policy header" >&2; exit 1; }
[[ "$(header_value x-platform3-write-path "$WORK_DIR/attendance-create.headers")" == "teacher-mark-create" ]] || { echo "ASSERTION FAILED: attendance create returns append-only teacher-mark write path" >&2; exit 1; }
[[ "$(header_value x-platform3-max-client-concurrency "$WORK_DIR/attendance-create.headers")" == "8" ]] || { echo "ASSERTION FAILED: attendance create returns max concurrency 8" >&2; exit 1; }
attendance_id="$(jq -r '.data.edfi_local_id' "$WORK_DIR/attendance-create.json")"
attendance_etag="$(header_value etag "$WORK_DIR/attendance-create.headers")"

cat > "$WORK_DIR/section-attendance-create.payload.json" <<JSON
{
  "studentReference": {"studentUniqueId": "student-001"},
  "sectionReference": {"sectionIdentifier": "class-math7-p2", "schoolId": 255901001, "schoolYear": 2026},
  "sessionReference": {"schoolYear": 2026, "sessionName": "Spring Semester"},
  "attendanceEvent": {
    "eventDate": "$(date -u +%Y-%m-%d)",
    "attendanceEventCategoryDescriptor": "$attendance_descriptor_uri"
  },
  "sectionAttendanceDuration": 45,
  "student_sourced_id": "student-001",
  "class_sourced_id": "class-math7-p2",
  "section_sourced_id": "class-math7-p2"
}
JSON

section_attendance_status="$(curl -sS -D "$WORK_DIR/section-attendance-create.headers" -o "$WORK_DIR/section-attendance-create.json" -w "%{http_code}" \
  -X POST "$ED_FI_BASE_URL/ed-fi/studentSectionAttendanceEvents" \
  "${auth_header[@]}" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: section-attendance-create-$RUN_ID" \
  --data-binary @"$WORK_DIR/section-attendance-create.payload.json")"
assert_status "$section_attendance_status" "201" "section attendance create"
assert_jq "$WORK_DIR/section-attendance-create.json" '.data.edfi_local_id and .data.ack_id and .data.student_sourced_id == "student-001" and .data.class_sourced_id == "class-math7-p2" and (.data | has("section_sourced_id") | not)' "section attendance create returns canonical class overlay"
[[ "$(header_value x-platform3-attendance-policy "$WORK_DIR/section-attendance-create.headers")" == "edfi.attendance.teacher_mark.v2026-06-22" ]] || { echo "ASSERTION FAILED: section attendance create returns teacher-mark policy header" >&2; exit 1; }
[[ "$(header_value x-platform3-write-path "$WORK_DIR/section-attendance-create.headers")" == "teacher-mark-create" ]] || { echo "ASSERTION FAILED: section attendance create returns append-only teacher-mark write path" >&2; exit 1; }
[[ "$(header_value x-platform3-max-client-concurrency "$WORK_DIR/section-attendance-create.headers")" == "8" ]] || { echo "ASSERTION FAILED: section attendance create returns max concurrency 8" >&2; exit 1; }

curl -fsS -D "$WORK_DIR/attendance-detail.headers" \
  "$ED_FI_BASE_URL/ed-fi/studentSchoolAttendanceEvents/$attendance_id" \
  "${auth_header[@]}" \
  -o "$WORK_DIR/attendance-detail.json"
assert_jq "$WORK_DIR/attendance-detail.json" ".data.edfi_local_id == \"$attendance_id\" and .data.is_deleted == false" "attendance detail reads by platform local id"

patch_status="$(curl -sS -D "$WORK_DIR/attendance-patch.headers" -o "$WORK_DIR/attendance-patch.json" -w "%{http_code}" \
  -X PATCH "$ED_FI_BASE_URL/ed-fi/studentSchoolAttendanceEvents/$attendance_id" \
  "${auth_header[@]}" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: attendance-patch-$RUN_ID" \
  -H "If-Match: $attendance_etag" \
  --data '{"schoolAttendanceDuration":405}')"
assert_status "$patch_status" "200" "attendance patch"
assert_jq "$WORK_DIR/attendance-patch.json" '.data.schoolAttendanceDuration == 405 and .data.etag' "attendance patch returns updated duration and validator"
attendance_delete_etag="$(jq -r '.data.etag' "$WORK_DIR/attendance-patch.json")"

delete_status="$(curl -sS -o "$WORK_DIR/attendance-delete.body" -w "%{http_code}" \
  -X DELETE "$ED_FI_BASE_URL/ed-fi/studentSchoolAttendanceEvents/$attendance_id" \
  "${auth_header[@]}" \
  -H "Idempotency-Key: attendance-delete-$RUN_ID" \
  -H "If-Match: $attendance_delete_etag")"
assert_status "$delete_status" "204" "attendance delete"

curl -fsS "$ED_FI_BASE_URL/ed-fi/studentSchoolAttendanceEvents/$attendance_id?includeDeleted=true" \
  "${auth_header[@]}" \
  -o "$WORK_DIR/attendance-deleted.json"
assert_jq "$WORK_DIR/attendance-deleted.json" ".data.edfi_local_id == \"$attendance_id\" and .data.is_deleted == true and .data.deleted_at" "attendance soft-delete retention"

fetch_descriptor_by_code "gradeTypeDescriptors" "Final" "uri://ed-fi.org/GradeTypeDescriptor" "$WORK_DIR/grade-type-descriptors.json" "$WORK_DIR/grade-type-descriptors.headers" 5
assert_jq "$WORK_DIR/grade-type-descriptors.json" '.totalCount >= 1 and all(.data[]; .namespace == "uri://ed-fi.org/GradeTypeDescriptor" and .codeValue == "Final")' "grade type descriptor key filter includes the standard Final value"
grade_type_descriptor_uri="$(jq -r 'first(.data[] | select(.namespace == "uri://ed-fi.org/GradeTypeDescriptor" and .codeValue == "Final") | "\(.namespace)#\(.codeValue)")' "$WORK_DIR/grade-type-descriptors.json")"

cat > "$WORK_DIR/grade-create.payload.json" <<JSON
{
  "gradeTypeDescriptor": "$grade_type_descriptor_uri",
  "studentSectionAssociationReference": {
    "studentUniqueId": "student-001",
    "schoolId": 255901001,
    "localCourseCode": "SKILL-$RUN_ID",
    "schoolYear": 2026,
    "sectionIdentifier": "SKILL-$RUN_ID",
    "sessionName": "Spring Semester",
    "beginDate": "2026-01-15"
  },
  "gradingPeriodReference": {
    "gradingPeriodDescriptor": "uri://ed-fi.org/GradingPeriodDescriptor#End of Year",
    "periodSequence": 2,
    "schoolId": 255901001,
    "schoolYear": 2026
  },
  "letterGradeEarned": "A",
  "numericGradeEarned": 95.5,
  "currentGradeIndicator": false,
  "currentGradeAsOfDate": "$(date -u +%Y-%m-%d)"
}
JSON

grade_status="$(curl -sS -D "$WORK_DIR/grade-create.headers" -o "$WORK_DIR/grade-create.json" -w "%{http_code}" \
  -X POST "$ED_FI_BASE_URL/ed-fi/grades" \
  "${auth_header[@]}" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: grade-create-$RUN_ID" \
  --data-binary @"$WORK_DIR/grade-create.payload.json")"
assert_status "$grade_status" "201" "grade create"
assert_jq "$WORK_DIR/grade-create.json" '.data.edfi_local_id and .data.ack_id and .data.numericGradeEarned == 95.5 and .data.links.dataDictionary' "grade create returns id, ack, grade value, and data dictionary link"
grade_id="$(jq -r '.data.edfi_local_id' "$WORK_DIR/grade-create.json")"
grade_etag="$(header_value etag "$WORK_DIR/grade-create.headers")"

curl -fsS "$ED_FI_BASE_URL/ed-fi/grades/$grade_id" \
  "${auth_header[@]}" \
  -o "$WORK_DIR/grade-detail.json"
assert_jq "$WORK_DIR/grade-detail.json" ".data.edfi_local_id == \"$grade_id\" and .data.gradeTypeDescriptor == \"uri://ed-fi.org/GradeTypeDescriptor#Final\"" "grade detail reads by local id"

grade_delete_status="$(curl -sS -o "$WORK_DIR/grade-delete.body" -w "%{http_code}" \
  -X DELETE "$ED_FI_BASE_URL/ed-fi/grades/$grade_id" \
  "${auth_header[@]}" \
  -H "Idempotency-Key: grade-delete-$RUN_ID" \
  -H "If-Match: $grade_etag")"
assert_status "$grade_delete_status" "204" "grade delete"

curl -fsS "$ED_FI_BASE_URL/ed-fi/grades/$grade_id?includeDeleted=true" \
  "${auth_header[@]}" \
  -o "$WORK_DIR/grade-deleted.json"
assert_jq "$WORK_DIR/grade-deleted.json" ".data.edfi_local_id == \"$grade_id\" and .data.is_deleted == true and .data.deleted_at" "grade soft-delete retention"

import_status="$(curl -sS -D "$WORK_DIR/import.headers" -o "$WORK_DIR/import.json" -w "%{http_code}" \
  -X POST "$ED_FI_BASE_URL/ed-fi/imports" \
  "${auth_header[@]}" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: import-$RUN_ID" \
  --data "{\"source_format\":\"edfi-json-bundle\",\"records\":[{\"resource_name\":\"StudentSchoolAttendanceEvent\",\"source_key_json\":{\"run_id\":\"$RUN_ID\"}}]}")"
assert_status "$import_status" "202" "import job"
assert_jq "$WORK_DIR/import.json" '.data.import_job_id and .data.tenant_id == "demo" and .links.dataDictionary' "import job accepts and returns job identity"
import_job_id="$(jq -r '.data.import_job_id' "$WORK_DIR/import.json")"
poll_job "imports" "$import_job_id" "$WORK_DIR/import-terminal.json" \
  '.data.import_job_id and .data.tenant_id == "demo" and .data.state == "completed" and .data.row_count == 1 and .data.error_count == 0 and .links.dataDictionary' \
  "import job reaches completed terminal state with one accepted row"
import_job_state="$(jq -r '.data.state' "$WORK_DIR/import-terminal.json")"
import_row_count="$(jq -r '.data.row_count' "$WORK_DIR/import-terminal.json")"

export_status="$(curl -sS -D "$WORK_DIR/export.headers" -o "$WORK_DIR/export.json" -w "%{http_code}" \
  -X POST "$ED_FI_BASE_URL/ed-fi/exports" \
  "${auth_header[@]}" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: export-$RUN_ID" \
  --data '{"export_scope":"complete-model","modified_since":"2026-06-01T00:00:00Z"}')"
assert_status "$export_status" "202" "export job"
assert_jq "$WORK_DIR/export.json" '.data.export_job_id and .data.tenant_id == "demo" and .data.export_scope == "complete-model" and .links.dataDictionary' "export job accepts and returns job identity"
export_job_id="$(jq -r '.data.export_job_id' "$WORK_DIR/export.json")"
poll_job "exports" "$export_job_id" "$WORK_DIR/export-terminal.json" \
  '.data.export_job_id and .data.tenant_id == "demo" and .data.export_scope == "complete-model" and .data.state == "completed" and .data.redaction_summary_json.secrets == 0 and .links.dataDictionary' \
  "export job reaches completed terminal state with redaction evidence"
export_job_state="$(jq -r '.data.state' "$WORK_DIR/export-terminal.json")"

for evidence_id in \
  evidence-descriptor-governance-v6-1 \
  evidence-http-contract-edfi \
  evidence-udm-coverage-v6-1; do
  curl -fsS "$ED_FI_BASE_URL/ed-fi/conformance/evidence?evidence_id=$evidence_id&limit=1&offset=0" \
    "${auth_header[@]}" \
    -o "$WORK_DIR/conformance-$evidence_id.json"
  if ! jq -e --arg id "$evidence_id" '.totalCount >= 1 and (.data | length) >= 1 and any(.data[]; .evidence_id == $id and .passed == true) and .links.dataDictionary' "$WORK_DIR/conformance-$evidence_id.json" >/dev/null; then
    echo "ASSERTION FAILED: conformance evidence key filter returns passing $evidence_id" >&2
    echo "File: $WORK_DIR/conformance-$evidence_id.json" >&2
    jq '.' "$WORK_DIR/conformance-$evidence_id.json" >&2 || true
    exit 1
  fi
done

jq -n \
  --arg baseUrl "$ED_FI_BASE_URL" \
  --arg runId "$RUN_ID" \
  --arg attendanceId "$attendance_id" \
  --arg gradeId "$grade_id" \
  --arg importJobId "$import_job_id" \
  --arg importJobState "$import_job_state" \
  --argjson importRowCount "$import_row_count" \
  --arg exportJobId "$export_job_id" \
  --arg exportJobState "$export_job_state" \
  --argjson conformanceEvidenceIds '["evidence-descriptor-governance-v6-1","evidence-http-contract-edfi","evidence-udm-coverage-v6-1"]' \
  '{
    ok: true,
    baseUrl: $baseUrl,
    runId: $runId,
    reproduced: {
      root: "module=ed_fi surface=1edtech counts=193/280/473",
      attendance: {edfi_local_id: $attendanceId, softDeleted: true},
      grades: {edfi_local_id: $gradeId, softDeleted: true},
      importJob: {import_job_id: $importJobId, state: $importJobState, row_count: $importRowCount},
      exportJob: {export_job_id: $exportJobId, state: $exportJobState},
      conformanceEvidenceIds: $conformanceEvidenceIds
    },
    leakCheck: "surface calls only; no UDM parser, descriptor table, roster reconciliation, ETag calculation, idempotency replay, hard-delete, private DB access, or Alpha vocabulary transform"
  }'
