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

ROOT_DIR="$(cd "$(dirname "$0")/../.." && pwd)"
cd "$ROOT_DIR"

SANDBOX="$ROOT_DIR/sandbox/rho-repo-doctor"
REPO="$SANDBOX/repo"
MIGRATE_REPO="$SANDBOX/migrate-repo"
USER1_ID="rho://id/github/rho-owner"
USER2_ID="rho://id/github/rho-collab"
REQUEST_PATH="rho/messages/inbox/rho-owner/request.yaml.rhoenc"

rm -rf "$SANDBOX"
mkdir -p "$REPO"

git -C "$REPO" init >/dev/null
git -C "$REPO" config user.name "Rho Doctor Test"
git -C "$REPO" config user.email "doctor@example.test"
git -C "$REPO" config commit.gpgsign false

./rho repo init \
  --root "$REPO" \
  --repo-id rho://repo/local/doctor \
  --owner "$USER1_ID" >/dev/null

RHO_HOME="$SANDBOX/user1-rho-home" ./rho id init \
  --github rho-owner \
  --display-name "Rho Owner" \
  --generate-ssh-key >/dev/null
RHO_HOME="$SANDBOX/user2-rho-home" ./rho id init \
  --github rho-collab \
  --display-name "Rho Collaborator" \
  --generate-ssh-key >/dev/null

RHO_HOME="$SANDBOX/user1-rho-home" ./rho id export \
  --identity "$USER1_ID" \
  --out "$REPO/rho/participants/rho-owner.yaml" >/dev/null
RHO_HOME="$SANDBOX/user2-rho-home" ./rho id export \
  --identity "$USER2_ID" \
  --out "$REPO/rho/participants/rho-collab.yaml" >/dev/null

cat > "$REPO/rho/membership.yaml" <<EOF
version: 1
members:
  - identity: $USER1_ID
    role: owner
  - identity: $USER2_ID
    role: collaborator
EOF

cat > "$REPO/rho/policy/permissions.yaml" <<EOF
version: 1
permissions:
  - id: owner_inbox
    pattern: rho/messages/inbox/rho-owner/**
    write:
      allowed:
        - members
    read:
      encrypted_to:
        - $USER1_ID
EOF
cat > "$REPO/rho/policy/crypto.yaml" <<EOF
version: 1
crypto:
  signatures: ssh
  encryption: x25519-recipient-envelope
  transparent_git_filters: enabled
  filter: rho-crypt
EOF
printf "rho/messages/inbox/rho-owner/** filter=rho-crypt diff=rho-crypt\n" >> "$REPO/.gitattributes"

RHO_HOME="$SANDBOX/user2-rho-home" ./rho id import \
  "$REPO/rho/participants/rho-owner.yaml" >/dev/null
mkdir -p "$REPO/rho/messages/inbox/rho-owner"
cat > "$SANDBOX/request.yaml" <<EOF
version: 1
request:
  note: private request for owner
EOF
RHO_HOME="$SANDBOX/user2-rho-home" ./rho crypto seal \
  "$SANDBOX/request.yaml" \
  --recipient "$USER1_ID" \
  --out "$REPO/$REQUEST_PATH" \
  --repo-root "$REPO" \
  --path "$REQUEST_PATH" \
  --purpose rho.bundle >/dev/null

DATASET_UUID="77777777-8888-9999-aaaa-bbbbbbbbbbbb"
mkdir -p "$REPO/datasets/public/$DATASET_UUID/mock"
printf "date,symbol,price\n2026-06-15,RHO,1.00\n" > "$REPO/datasets/public/$DATASET_UUID/mock/prices-mock.csv"
MOCK_SHA256="$(shasum -a 256 "$REPO/datasets/public/$DATASET_UUID/mock/prices-mock.csv" | awk '{print $1}')"
cat > "$REPO/datasets/public/$DATASET_UUID/dataset.yaml" <<EOF
version: 1
dataset:
  uuid: $DATASET_UUID
  name: doctor-dataset
  owner: $USER1_ID
  variants:
    mock:
      tier: mock
      relative_path: mock/prices-mock.csv
      file_name: prices-mock.csv
      mime_type: text/csv
      sha256: $MOCK_SHA256
    real:
      tier: real
      availability: private
      staged_under_user_folder: true
EOF

git -C "$REPO" add .gitattributes rho datasets
if RHO_HOME="$SANDBOX/user1-rho-home" ./rho repo doctor --root "$REPO" >"$SANDBOX/doctor-unsigned-governance-stdout.txt" 2>"$SANDBOX/doctor-unsigned-governance-stderr.txt"; then
  echo "doctor allowed unsigned governance manifests" >&2
  exit 1
fi
grep -q "governance signature missing for rho.yaml" "$SANDBOX/doctor-unsigned-governance-stderr.txt"
RHO_HOME="$SANDBOX/user1-rho-home" ./rho repo sign-governance --root "$REPO" >"$SANDBOX/sign-governance-initial.txt"
RHO_HOME="$SANDBOX/user1-rho-home" ./rho repo doctor --root "$REPO" >"$SANDBOX/doctor-pass.txt"
grep -q "rho repo doctor passed" "$SANDBOX/doctor-pass.txt"
grep -q "governance: passed" "$SANDBOX/doctor-pass.txt"
grep -q "migration: legacy inbox path rho/messages/inbox/rho-owner/ should move to rho/messages/inbox/id/github/rho-owner/" "$SANDBOX/doctor-pass.txt"

cp -R "$REPO" "$MIGRATE_REPO"
RHO_HOME="$SANDBOX/user1-rho-home" ./rho repo migrate-inbox-paths \
  --root "$MIGRATE_REPO" \
  --dry-run \
  > "$SANDBOX/migrate-inbox-dry-run.txt"
grep -q "dry-run: move rho/messages/inbox/rho-owner -> rho/messages/inbox/id/github/rho-owner" "$SANDBOX/migrate-inbox-dry-run.txt"
test -d "$MIGRATE_REPO/rho/messages/inbox/rho-owner"
test ! -e "$MIGRATE_REPO/rho/messages/inbox/id/github/rho-owner"
RHO_HOME="$SANDBOX/user1-rho-home" ./rho repo migrate-inbox-paths \
  --root "$MIGRATE_REPO" \
  > "$SANDBOX/migrate-inbox.txt"
grep -q "moved rho/messages/inbox/rho-owner -> rho/messages/inbox/id/github/rho-owner" "$SANDBOX/migrate-inbox.txt"
grep -q "updated inbox policy patterns: 1" "$SANDBOX/migrate-inbox.txt"
grep -q "legacy inbox paths migrated: 1" "$SANDBOX/migrate-inbox.txt"
test ! -e "$MIGRATE_REPO/rho/messages/inbox/rho-owner"
test -f "$MIGRATE_REPO/rho/messages/inbox/id/github/rho-owner/request.yaml.rhoenc"
grep -q "pattern: rho/messages/inbox/id/github/rho-owner/\\*\\*" "$MIGRATE_REPO/rho/policy/permissions.yaml"
grep -Fq "rho/messages/inbox/id/github/rho-owner/** filter=rho-crypt" "$MIGRATE_REPO/.gitattributes"
RHO_HOME="$SANDBOX/user1-rho-home" ./rho repo sign-governance --root "$MIGRATE_REPO" > "$SANDBOX/migrate-sign-governance.txt"
RHO_HOME="$SANDBOX/user1-rho-home" ./rho repo doctor --root "$MIGRATE_REPO" > "$SANDBOX/migrate-doctor-pass.txt"
grep -q "rho repo doctor passed" "$SANDBOX/migrate-doctor-pass.txt"
if grep -q "migration: legacy inbox path" "$SANDBOX/migrate-doctor-pass.txt"; then
  echo "doctor still reported legacy inbox after migration" >&2
  exit 1
fi

cp "$REPO/rho.yaml" "$SANDBOX/rho.yaml.good"
cat > "$REPO/rho.yaml" <<EOF
rho: 1
project:
  id: rho://repo/local/doctor
  owner: $USER1_ID
transport:
  kind: git
members:
  file: rho/membership.yaml
participants:
  path: rho/participants/
permissions:
  file: rho/policy/permissions.yaml
crypto:
  file: rho/policy/crypto.yaml
auth:
  file: rho/policy/auth.yaml
tools:
  path: rho/tools/
resources:
  file: rho/missing-resources.yaml
EOF
if RHO_HOME="$SANDBOX/user1-rho-home" ./rho repo doctor --root "$REPO" >"$SANDBOX/doctor-rho-yaml-fail-stdout.txt" 2>"$SANDBOX/doctor-rho-yaml-fail-stderr.txt"; then
  echo "doctor allowed dangling rho.yaml resource reference" >&2
  exit 1
fi
grep -q "rho.yaml resources.file must be rho/resources.yaml" "$SANDBOX/doctor-rho-yaml-fail-stderr.txt"
cp "$SANDBOX/rho.yaml.good" "$REPO/rho.yaml"

cp "$REPO/rho/membership.yaml" "$SANDBOX/membership.good.yaml"
cat >> "$REPO/rho/membership.yaml" <<EOF
  - identity: $USER2_ID
    role: collaborator
EOF
if RHO_HOME="$SANDBOX/user1-rho-home" ./rho repo doctor --root "$REPO" >"$SANDBOX/doctor-duplicate-member-stdout.txt" 2>"$SANDBOX/doctor-duplicate-member-stderr.txt"; then
  echo "doctor allowed duplicate membership identity" >&2
  exit 1
fi
grep -q "duplicate member identity: $USER2_ID" "$SANDBOX/doctor-duplicate-member-stderr.txt"
cp "$SANDBOX/membership.good.yaml" "$REPO/rho/membership.yaml"

sed 's/rho-collab/rho-guest/g' "$REPO/rho/participants/rho-collab.yaml" > "$REPO/rho/participants/rho-guest.yaml"
if RHO_HOME="$SANDBOX/user1-rho-home" ./rho repo doctor --root "$REPO" >"$SANDBOX/doctor-orphan-participant-stdout.txt" 2>"$SANDBOX/doctor-orphan-participant-stderr.txt"; then
  echo "doctor allowed participant bundle outside membership" >&2
  exit 1
fi
grep -q "participant is not admitted in membership: rho/participants/rho-guest.yaml -> rho://id/github/rho-guest" "$SANDBOX/doctor-orphan-participant-stderr.txt"
rm "$REPO/rho/participants/rho-guest.yaml"

RHO_HOME="$SANDBOX/user1-rho-home" ./rho repo sign-governance --root "$REPO" >"$SANDBOX/sign-governance.txt"
test -f "$REPO/rho/membership.rhosig.yaml"
test -f "$REPO/rho/policy/permissions.rhosig.yaml"
test -f "$REPO/datasets/public/$DATASET_UUID/dataset.rhosig.yaml"
RHO_HOME="$SANDBOX/user1-rho-home" ./rho repo doctor --root "$REPO" >"$SANDBOX/doctor-governance-pass.txt"
grep -q "governance: passed" "$SANDBOX/doctor-governance-pass.txt"

printf "\n# tampered after governance signing\n" >> "$REPO/rho/membership.yaml"
if RHO_HOME="$SANDBOX/user1-rho-home" ./rho repo doctor --root "$REPO" >"$SANDBOX/doctor-governance-fail-stdout.txt" 2>"$SANDBOX/doctor-governance-fail-stderr.txt"; then
  echo "doctor allowed tampered governance manifest" >&2
  exit 1
fi
grep -q "signature verification failed" "$SANDBOX/doctor-governance-fail-stderr.txt"
RHO_HOME="$SANDBOX/user1-rho-home" ./rho repo sign-governance --root "$REPO" >"$SANDBOX/resign-governance.txt"

cat > "$REPO/datasets/public/$DATASET_UUID/dataset.yaml" <<EOF
version: 1
dataset:
  uuid: $DATASET_UUID
  owner: $USER1_ID
  name: doctor-dataset
  mock_path: datasets/public/$DATASET_UUID/mock/prices-mock.csv
  real_tier: private
EOF
if RHO_HOME="$SANDBOX/user1-rho-home" ./rho repo doctor --root "$REPO" >"$SANDBOX/doctor-dataset-fail-stdout.txt" 2>"$SANDBOX/doctor-dataset-fail-stderr.txt"; then
  echo "doctor allowed malformed dataset manifest" >&2
  exit 1
fi
grep -q "missing dataset.variants" "$SANDBOX/doctor-dataset-fail-stderr.txt"
cat > "$REPO/datasets/public/$DATASET_UUID/dataset.yaml" <<EOF
version: 1
dataset:
  uuid: $DATASET_UUID
  name: doctor-dataset
  owner: $USER1_ID
  variants:
    mock:
      tier: mock
      relative_path: mock/prices-mock.csv
      file_name: prices-mock.csv
      mime_type: text/csv
      sha256: $MOCK_SHA256
    real:
      tier: real
      availability: private
      staged_under_user_folder: true
EOF

cat > "$REPO/datasets/public/$DATASET_UUID/dataset.yaml" <<EOF
version: 1
dataset:
  uuid: $DATASET_UUID
  name: doctor-dataset
  owner: rho://id/github/rho-guest
  variants:
    mock:
      tier: mock
      relative_path: mock/prices-mock.csv
      file_name: prices-mock.csv
      mime_type: text/csv
      sha256: $MOCK_SHA256
    real:
      tier: real
      availability: private
      staged_under_user_folder: true
EOF
if RHO_HOME="$SANDBOX/user1-rho-home" ./rho repo doctor --root "$REPO" >"$SANDBOX/doctor-dataset-owner-fail-stdout.txt" 2>"$SANDBOX/doctor-dataset-owner-fail-stderr.txt"; then
  echo "doctor allowed dataset owner outside membership" >&2
  exit 1
fi
grep -q "dataset owner is not a member" "$SANDBOX/doctor-dataset-owner-fail-stderr.txt"
cat > "$REPO/datasets/public/$DATASET_UUID/dataset.yaml" <<EOF
version: 1
dataset:
  uuid: $DATASET_UUID
  name: doctor-dataset
  owner: $USER1_ID
  variants:
    mock:
      tier: mock
      relative_path: mock/prices-mock.csv
      file_name: prices-mock.csv
      mime_type: text/csv
      sha256: $MOCK_SHA256
    real:
      tier: real
      availability: private
      staged_under_user_folder: true
EOF

cat > "$REPO/rho/policy/crypto.yaml" <<EOF
version: 1
crypto:
  signatures: ssh
  encryption: x25519-recipient-envelope
  transparent_git_filters: disabled
EOF
if RHO_HOME="$SANDBOX/user1-rho-home" ./rho repo doctor --root "$REPO" >"$SANDBOX/doctor-crypto-fail-stdout.txt" 2>"$SANDBOX/doctor-crypto-fail-stderr.txt"; then
  echo "doctor allowed contradictory crypto filter policy" >&2
  exit 1
fi
grep -q "crypto.transparent_git_filters is disabled but .gitattributes uses filter=rho-crypt" "$SANDBOX/doctor-crypto-fail-stderr.txt"
cat > "$REPO/rho/policy/crypto.yaml" <<EOF
version: 1
crypto:
  signatures: ssh
  encryption: x25519-recipient-envelope
  transparent_git_filters: enabled
  filter: rho-crypt
EOF

cat > "$REPO/rho/messages/inbox/rho-owner/plaintext.yaml" <<EOF
version: 1
request:
  note: this should have been encrypted
EOF
if RHO_HOME="$SANDBOX/user1-rho-home" ./rho repo doctor --root "$REPO" >"$SANDBOX/doctor-fail-stdout.txt" 2>"$SANDBOX/doctor-fail-stderr.txt"; then
  echo "doctor allowed plaintext protected path" >&2
  exit 1
fi
grep -q "private-read file is not encrypted: rho/messages/inbox/rho-owner/plaintext.yaml" "$SANDBOX/doctor-fail-stderr.txt"

echo "inspect sandbox: $SANDBOX"
find "$SANDBOX" \
  -path "*/.git" -prune -o \
  -maxdepth 7 -type f -print | sort
echo "rho repo doctor e2e passed"
