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

BASE_URL="${CASE_BASE_URL:-https://platform3-andymontgomery-9773s-projects.vercel.app/case/1edtech/implementation/api}"
DOC_ID="${CASE_CHECK_DOC_ID:-3ea5c35f-5b3f-5e4d-905a-483c134316ec}"
ITEM_ID="${CASE_CHECK_ITEM_ID:-91910dfe-0045-55d7-8fc3-cf1149fe4637}"
PAGE_LIMIT="${CASE_CHECK_LIMIT:-5}"
WRITE_ALIGNMENT="false"

for arg in "$@"; do
  case "$arg" in
    --write-alignment) WRITE_ALIGNMENT="true" ;;
    -h|--help)
      cat <<'HELP'
Usage: checks/case_surface_check.sh [--write-alignment]

Calls the live CASE surface and verifies that the skill-pack browser recipe
reproduces the platform's own package-export answer key. It does not parse
CASE schemas, validate CFPackages locally, infer graph membership, or carry
copied standards data.

Environment:
  CASE_BASE_URL       Defaults to the canonical Platform3 CASE API.
  CASE_TOKEN          Optional. If absent, the check mints a demo token.
  CASE_CHECK_DOC_ID   Optional CFDocument identifier to verify.
  CASE_CHECK_ITEM_ID  Optional CFItem identifier for association context.
  CASE_CHECK_LIMIT    Optional first-page size for CFItems, default 5.
HELP
      exit 0
      ;;
    *)
      echo "Unknown argument: $arg" >&2
      exit 2
      ;;
  esac
done

need() {
  if ! command -v "$1" >/dev/null 2>&1; then
    echo "Missing required command: $1" >&2
    exit 127
  fi
}

need curl
need jq

urlencode() {
  jq -nr --arg v "$1" '$v|@uri'
}

api_get() {
  curl -fsS "$BASE_URL$1" -H "Authorization: Bearer $CASE_TOKEN"
}

if [ -z "${CASE_TOKEN:-}" ]; then
  CASE_TOKEN="$(curl -fsS -X POST "$BASE_URL/dev/mint?tenantId=demo" | jq -r '.token')"
fi

if [ -z "$CASE_TOKEN" ] || [ "$CASE_TOKEN" = "null" ]; then
  echo "Could not obtain CASE_TOKEN" >&2
  exit 1
fi

DOC_JSON="$(api_get "/ims/case/v1p1/CFDocuments/$DOC_ID")"
DOC_URI="$(printf '%s' "$DOC_JSON" | jq -r '.CFDocument.uri')"
DOC_TITLE="$(printf '%s' "$DOC_JSON" | jq -r '.CFDocument.title')"

if [ -z "$DOC_URI" ] || [ "$DOC_URI" = "null" ]; then
  echo "CFDocument $DOC_ID did not include CFDocument.uri" >&2
  exit 1
fi

DOC_URI_ENCODED="$(urlencode "$DOC_URI")"
ITEMS_JSON="$(api_get "/ims/case/v1p1/CFItems?CFDocumentURI=$DOC_URI_ENCODED&limit=$PAGE_LIMIT&offset=0")"
PACKAGE_JSON="$(api_get "/ims/case/v1p1/CFPackages/$DOC_ID")"
TARGET_JSON="$(api_get "/ims/case/v1p1/CFItems/$ITEM_ID")"
ASSOCIATIONS_JSON="$(api_get "/ims/case/v1p1/CFItemAssociations/$ITEM_ID")"

PACKAGE_DOC_ID="$(printf '%s' "$PACKAGE_JSON" | jq -r '.CFDocument.identifier')"
LIST_COUNT="$(printf '%s' "$ITEMS_JSON" | jq -r '.count')"
PACKAGE_ITEM_COUNT="$(printf '%s' "$PACKAGE_JSON" | jq -r '.CFItems | length')"

if [ "$PACKAGE_DOC_ID" != "$DOC_ID" ]; then
  echo "Package export answered for $PACKAGE_DOC_ID, expected $DOC_ID" >&2
  exit 1
fi

if [ "$LIST_COUNT" != "$PACKAGE_ITEM_COUNT" ]; then
  echo "CFItems list count ($LIST_COUNT) did not match package export item count ($PACKAGE_ITEM_COUNT)" >&2
  exit 1
fi

while IFS= read -r item_id; do
  [ -z "$item_id" ] && continue
  if ! printf '%s' "$PACKAGE_JSON" | jq -e --arg id "$item_id" 'any(.CFItems[]; .identifier == $id)' >/dev/null; then
    echo "First-page CFItem $item_id was not present in package export" >&2
    exit 1
  fi
done <<EOF
$(printf '%s' "$ITEMS_JSON" | jq -r '.CFItems[].identifier')
EOF

ALIGNMENT_SUMMARY='null'
if [ "$WRITE_ALIGNMENT" = "true" ]; then
  RUN_ID="skill-check-$(date +%s)-$$"
  ALIGNMENT_ID="align-$RUN_ID"
  EXTERNAL_ID="lesson-$RUN_ID"
  TARGET_URI="$(printf '%s' "$TARGET_JSON" | jq -r '.CFItem.uri')"
  REQUEST_JSON="$(jq -n \
    --arg alignmentId "$ALIGNMENT_ID" \
    --arg externalId "$EXTERNAL_ID" \
    --arg cfItemUri "$TARGET_URI" \
    --arg cfItemIdentifier "$ITEM_ID" \
    '{
      alignmentId: $alignmentId,
      externalSystem: "case-skill-pack-check",
      externalId: $externalId,
      cfItemUri: $cfItemUri,
      cfItemIdentifier: $cfItemIdentifier,
      label: "CASE skill-pack surface check",
      metadata: {source: "case_surface_check"}
    }')"

  CREATE_JSON="$(curl -fsS -X POST "$BASE_URL/ims/case/v1p1/Alignments" \
    -H "Authorization: Bearer $CASE_TOKEN" \
    -H "Content-Type: application/json" \
    -H "Idempotency-Key: $ALIGNMENT_ID" \
    -d "$REQUEST_JSON")"
  VERIFY_JSON="$(api_get "/ims/case/v1p1/Alignments?externalSystem=case-skill-pack-check&externalId=$EXTERNAL_ID")"
  VERIFY_COUNT="$(printf '%s' "$VERIFY_JSON" | jq -r '.count')"
  if [ "$VERIFY_COUNT" != "1" ]; then
    echo "Alignment verification count was $VERIFY_COUNT, expected 1" >&2
    exit 1
  fi
  ALIGNMENT_SUMMARY="$(jq -n \
    --arg alignmentId "$ALIGNMENT_ID" \
    --arg externalId "$EXTERNAL_ID" \
    --arg created "$(printf '%s' "$CREATE_JSON" | jq -r '.Alignment.alignmentId // .alignmentId // empty')" \
    '{alignmentId: $alignmentId, externalSystem: "case-skill-pack-check", externalId: $externalId, createdAlignmentId: $created}')"
fi

jq -n \
  --arg status "passed" \
  --arg baseUrl "$BASE_URL" \
  --arg documentId "$DOC_ID" \
  --arg documentUri "$DOC_URI" \
  --arg documentTitle "$DOC_TITLE" \
  --arg listCount "$LIST_COUNT" \
  --arg pageReturned "$(printf '%s' "$ITEMS_JSON" | jq -r '.CFItems | length')" \
  --arg packageAssociations "$(printf '%s' "$PACKAGE_JSON" | jq -r '.CFAssociations | length')" \
  --arg itemId "$ITEM_ID" \
  --arg itemCode "$(printf '%s' "$TARGET_JSON" | jq -r '.CFItem.humanCodingScheme // .CFItem.identifier')" \
  --arg parentCount "$(printf '%s' "$ASSOCIATIONS_JSON" | jq -r '(.CFAssociationSet.parents // []) | length')" \
  --argjson alignment "$ALIGNMENT_SUMMARY" \
  '{
    status: $status,
    tenantMode: "demo unless CASE_TOKEN was supplied",
    baseUrl: $baseUrl,
    answerKey: "GET /ims/case/v1p1/CFPackages/{sourcedId}",
    checks: [
      "CFDocument detail returned the target framework",
      "CFItems?CFDocumentURI count matched CFPackage export",
      "first page CFItem identifiers were present in CFPackage export",
      "CFItemAssociations returned relationship context for the target item"
    ],
    document: {
      identifier: $documentId,
      uri: $documentUri,
      title: $documentTitle
    },
    cfItems: {
      count: ($listCount | tonumber),
      firstPageReturned: ($pageReturned | tonumber),
      packageAssociationCount: ($packageAssociations | tonumber)
    },
    targetItem: {
      identifier: $itemId,
      humanCodingScheme: $itemCode,
      parentCount: ($parentCount | tonumber)
    },
    optionalAlignmentWrite: $alignment,
    surfaceOwnedLogic: {
      localSchemaParser: false,
      localPackageValidator: false,
      copiedStandardsCatalog: false,
      copiedEnumerationTables: false,
      graphRepairOrDedup: false,
      publisherUriInference: false
    }
  }'
