#!/usr/bin/env sh
set -eu

# Check OpenAPI contract levels for multi-module layout.
# - For PRs targeting main: require provider contract level >= L2.
# - Always require info.x-contract-level exists and is L0-L3.
#
# Expected locations:
# - spec/<module>/openapi.provider.yaml
# - spec/<module>/openapi.deps.yaml (optional)

require_provider_l2="${REQUIRE_PROVIDER_L2:-0}"

die() {
  echo "ERROR: $*" >&2
  exit 1
}

level_rank() {
  case "$1" in
    L0) echo 0;;
    L1) echo 1;;
    L2) echo 2;;
    L3) echo 3;;
    *) echo -1;;
  esac
}

extract_level() {
  # Extracts the first occurrence of info.x-contract-level: L?
  # Accepts patterns like:
  #   x-contract-level: L2
  #   x-contract-level: "L2"
  # under info:
  file="$1"

  awk '
    BEGIN{in_info=0; level=""}
    {
      # detect "info:" at any indentation
      if ($0 ~ /^[[:space:]]*info:[[:space:]]*$/) { in_info=1; info_indent=match($0,/[^ ]/)-1; next }
      if (in_info==1) {
        # if indentation decreases or new top-level key begins, leave info block
        cur_indent=match($0,/[^ ]/)-1;
        if (cur_indent <= info_indent && $0 ~ /^[^[:space:]]/ ) { in_info=0 }
      }
      if (in_info==1 && level=="" && $0 ~ /^[[:space:]]*x-contract-level:[[:space:]]*/) {
        line=$0
        sub(/^[[:space:]]*x-contract-level:[[:space:]]*/,"",line)
        gsub(/"|\047/,"",line)
        # strip comments
        sub(/[[:space:]]*#.*/,"",line)
        gsub(/[[:space:]]+/,"",line)
        level=line
      }
    }
    END{print level}
  ' "$file"
}

check_file_level() {
  file="$1"
  kind="$2" # provider|deps

  [ -f "$file" ] || die "Missing OpenAPI file: $file"

  level="$(extract_level "$file" | tr -d '\r')"
  [ -n "$level" ] || die "$file: missing info.x-contract-level (expected under info: x-contract-level: L0|L1|L2|L3)"

  rank="$(level_rank "$level")"
  [ "$rank" -ge 0 ] || die "$file: invalid x-contract-level '$level' (expected L0|L1|L2|L3)"

  if [ "$kind" = "provider" ] && [ "$require_provider_l2" = "1" ]; then
    if [ "$rank" -lt 2 ]; then
      die "$file: provider contract-level must be >= L2 for merge-to-main (current: $level)"
    fi
  fi

  echo "OK: $file level=$level"
}

# Find all provider openapi files under spec/*
provider_files="$(find spec -mindepth 2 -maxdepth 2 -type f -name 'openapi.provider.yaml' 2>/dev/null || true)"
[ -n "$provider_files" ] || die "No provider OpenAPI found. Expected at least one spec/<module>/openapi.provider.yaml"

# Provider files always must have a valid level; for main merges, require >= L2
for f in $provider_files; do
  check_file_level "$f" provider

done

# Deps files are optional, but if present must have valid level
for d in $(find spec -mindepth 2 -maxdepth 2 -type f -name 'openapi.deps.yaml' 2>/dev/null || true); do
  check_file_level "$d" deps

done

echo "All OpenAPI contract level checks passed."
