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

ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"

tmpdir="$(mktemp -d)"
cleanup() {
  rm -rf "$tmpdir"
}
trap cleanup EXIT

mkdir -p "$tmpdir/presets" "$tmpdir/spec" "$tmpdir/wrappers"
cp "$ROOT/presets/_validate.mjs" "$tmpdir/presets/_validate.mjs"
cp "$ROOT/spec/presets.schema.json" "$tmpdir/spec/presets.schema.json"
cp "$ROOT/spec/runconfig.schema.json" "$tmpdir/spec/runconfig.schema.json"
cp "$ROOT/spec/events.schema.json" "$tmpdir/spec/events.schema.json"

cat >"$tmpdir/wrappers/codex.sh" <<'EOF'
#!/usr/bin/env bash
exit 0
EOF
chmod +x "$tmpdir/wrappers/codex.sh"

cat >"$tmpdir/wrappers/ca.sh" <<'EOF'
#!/usr/bin/env bash
exit 0
EOF
chmod +x "$tmpdir/wrappers/ca.sh"

cat >"$tmpdir/presets/adapters.json" <<'EOF'
{
  "version": "adapters/v1",
  "adapters": [
    {
      "id": "codex",
      "wrapper": "wrappers/codex.sh",
      "metered": true,
      "models": ["gpt-5.5-high", "gpt-5.5-low"]
    },
    {
      "id": "cursor",
      "wrapper": "wrappers/ca.sh",
      "metered": false,
      "models": ["composer-2.5"]
    },
    {
      "id": "north",
      "wrapper": "wrappers/north.sh",
      "metered": false,
      "models": ["composer-2.5"]
    }
  ]
}
EOF

cat >"$tmpdir/wrappers/north.sh" <<'EOF'
#!/usr/bin/env bash
exit 0
EOF
chmod +x "$tmpdir/wrappers/north.sh"

cat >"$tmpdir/presets/good.json" <<'EOF'
{
  "name": "good",
  "version": "preset/v1",
  "seats": {
    "coder": {
      "wrapper": "wrappers/codex.sh",
      "model": "gpt-5.5-high"
    },
    "reviewer": {
      "wrapper": "wrappers/ca.sh",
      "model": "composer-2.5"
    }
  }
}
EOF

good_output="$(cd "$tmpdir" && node presets/_validate.mjs 2>&1)"
case "$good_output" in
  *"validated 1 preset(s) and 3 example runconfig(s)"*) ;;
  *)
    echo "expected successful validation output, got:" >&2
    echo "$good_output" >&2
    exit 1
    ;;
esac

cat >"$tmpdir/presets/missing-model.json" <<'EOF'
{
  "name": "missing-model",
  "version": "preset/v1",
  "seats": {
    "coder": {
      "wrapper": "wrappers/codex.sh",
      "model": "gpt-4o"
    }
  }
}
EOF

if (cd "$tmpdir" && node presets/_validate.mjs >"$tmpdir/validate-crosscheck.out" 2>"$tmpdir/validate-crosscheck.err"); then
  echo "expected validator to reject uncataloged binding model" >&2
  exit 1
fi
grep -q 'binding model "gpt-4o" is not listed for adapter "codex"' "$tmpdir/validate-crosscheck.err"
rm -f "$tmpdir/presets/missing-model.json"

cat >"$tmpdir/presets/adapters.json" <<'EOF'
{
  "version": "adapters/v1",
  "adapters": [
    {
      "id": "codex",
      "wrapper": "wrappers/codex.sh",
      "metered": true,
      "models": ["gpt-5.5-high"]
    },
    {
      "id": "north",
      "wrapper": "wrappers/north.sh",
      "metered": false,
      "models": ["cohere/north-mini-code:free"]
    }
  ]
}
EOF

cat >"$tmpdir/spec/events.schema.json" <<'EOF'
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://local/harness/events.schema.json",
  "title": "Normalized harness events",
  "description": "Stateless per-line normalization target for claude/cursor/codex stream records.",
  "type": "object",
  "additionalProperties": true,
  "required": ["v", "seq", "position", "dialect", "kind", "subtype", "raw", "parsed"],
  "properties": {
    "v": { "const": "events/v1" },
    "seq": { "type": "integer", "minimum": 0 },
    "position": { "type": "integer", "minimum": 0 },
    "dialect": {
      "type": "string",
      "enum": ["claude", "cursor", "codex"]
    },
    "kind": { "type": "string", "enum": ["message", "tool_call", "status", "error"] },
    "subtype": { "type": "string", "minLength": 1 },
    "raw": { "type": "string" },
    "parsed": {}
  }
}
EOF

if (cd "$tmpdir" && node presets/_validate.mjs >"$tmpdir/validate-crosscheck.out" 2>"$tmpdir/validate-crosscheck.err"); then
  echo "expected validator to reject adapter id missing from dialect enum" >&2
  exit 1
fi
grep -q 'adapter id "north" is missing from spec/events.schema.json dialect enum' "$tmpdir/validate-crosscheck.err"

cat >"$tmpdir/presets/adapters.json" <<'EOF'
{
  "version": "adapters/v1",
  "adapters": [
    {
      "id": "codex",
      "wrapper": "wrappers/codex.sh",
      "metered": true,
      "models": ["gpt-5.5-high"]
    },
    {
      "id": "cursor",
      "wrapper": "wrappers/codex.sh",
      "metered": true,
      "models": ["gpt-5.5-low"]
    }
  ]
}
EOF

if (cd "$tmpdir" && node presets/_validate.mjs >"$tmpdir/validate-crosscheck.out" 2>"$tmpdir/validate-crosscheck.err"); then
  echo "expected validator to reject duplicate catalog wrapper paths" >&2
  exit 1
fi
grep -q 'duplicate adapter wrapper path: wrappers/codex.sh' "$tmpdir/validate-crosscheck.err"

echo "validate-crosscheck: ok"
