#!/usr/bin/env bash
# cleanup-orphan-checks.sh — remove orphan check entities + check_defs.
#
# These are leftovers from the old shortSlug() collision bug: check entities
# with truncated 8-hex slugs (e.g. check:ssh-script:0d31fdd1) that have no
# live target and are disabled. They pollute the entity table and the checks
# view. The audit_knowledge_graph tool reports them as `orphan_checks`.
#
# Risk class: config_mutation (deletes rows). DRY-RUN by default; pass --apply
# to actually delete. Review the listed slugs first — they must all match the
# legacy random-slug pattern and be disabled.
#
# Usage:
#   cleanup-orphan-checks.sh            # dry-run: list what would be deleted
#   cleanup-orphan-checks.sh --apply    # delete check_defs rows, then entities
#
# Connects via the OIKOS_TEST... no — via the running postgres container by
# default, or OIKOS_PSQL if set.
set -euo pipefail

PSQL_CMD="${OIKOS_PSQL:-docker exec -i oikos-postgres-1 psql -U oikos -d oikos}"
PATTERN='^check:(ping|ssh-script|disk):[0-9a-f]{8}$'

# Orphan = matches the legacy random-slug pattern AND has no enabled check_def
# pointing at a real target. A random-slug check that IS enabled and has a live
# target is a working check with a bad slug — keep it (deleting would drop
# monitoring), and flag it for a slug fix instead.
ORPHAN_PRED="e.type='check' AND e.slug ~ '$PATTERN'
  AND NOT EXISTS (SELECT 1 FROM check_defs cd
                  WHERE cd.entity_id = e.id AND cd.enabled AND cd.target_id IS NOT NULL)"

echo "== orphan checks matching /$PATTERN/ (no enabled check_def w/ target) =="
$PSQL_CMD -tAc "SELECT count(*) FROM entities e WHERE $ORPHAN_PRED;"

echo "== details (slug, state, enabled) =="
$PSQL_CMD -F ' | ' -Ac "
SELECT e.slug, COALESCE(e.state,'(null)'),
       COALESCE((SELECT cd.enabled::text FROM check_defs cd WHERE cd.entity_id=e.id LIMIT 1),'no-check_def')
FROM entities e
WHERE $ORPHAN_PRED
ORDER BY e.slug;" | head -60

if [ "${1:-}" != "--apply" ]; then
  echo
  echo "DRY RUN — no rows deleted. Re-run with --apply to delete:"
  echo "  check_defs whose check entity is an orphan, then those entities."
  exit 0
fi

echo
echo "== applying (config_mutation) =="
# check_defs first, then the dependent rows an entity owns (status, signals,
# metrics), then the orphan check entities. FKs prevent a plain entity delete.
$PSQL_CMD -v ON_ERROR_STOP=1 <<SQL
BEGIN;
DELETE FROM check_defs WHERE entity_id IN (SELECT id FROM entities e WHERE $ORPHAN_PRED);
WITH ids AS (SELECT id FROM entities e WHERE $ORPHAN_PRED)
DELETE FROM metric_samples WHERE entity_id IN (SELECT id FROM ids);
WITH ids AS (SELECT id FROM entities e WHERE $ORPHAN_PRED)
DELETE FROM signals WHERE entity_id IN (SELECT id FROM ids) OR target_entity_id IN (SELECT id FROM ids);
WITH ids AS (SELECT id FROM entities e WHERE $ORPHAN_PRED)
DELETE FROM entity_status WHERE entity_id IN (SELECT id FROM ids);
WITH ids AS (SELECT id FROM entities e WHERE $ORPHAN_PRED)
DELETE FROM relationships WHERE source_id IN (SELECT id FROM ids) OR target_id IN (SELECT id FROM ids);
DELETE FROM entities e WHERE $ORPHAN_PRED;
COMMIT;
SQL

echo "== remaining orphans (should be 0) =="
$PSQL_CMD -tAc "SELECT count(*) FROM entities e WHERE $ORPHAN_PRED;"
