#!/usr/bin/env bash
# Lumotia rebrand-migration dogfood drill.
#
# Launches the real lumotia binary against synthetic legacy magnotia state
# planted on disk, then probes the post-startup state to confirm both
# migration paths ran:
#   1. paths.rs:    ~/.local/share/magnotia/  ->  ~/.local/share/lumotia/
#                   magnotia.db -> lumotia.db
#   2. tauri_app_data_migration.rs:
#                   ~/.local/share/uk.co.corbel.magnotia/  copied via staging to
#                   ~/.local/share/consulting.corbel.lumotia/  (legacy preserved
#                   as a backup)
#
# Modes:
#   (default)            Sandbox. Sets HOME=<tempdir>, plants legacy state
#                        inside, launches the binary, verifies, tears down.
#                        Faithful on Linux. NOT faithful on macOS (Tauri 2
#                        uses NSSearchPathForDirectoriesInDomains which
#                        ignores HOME overrides and would write to your
#                        real Application Support tree).
#   --against-real-home  Real $HOME. Refuses to run if any lumotia data
#                        already exists at the real paths. Backs up the
#                        legacy planting before running so cleanup can
#                        restore your real-home tree to its pre-drill
#                        state.
#
# Flags:
#   --keep               Keep the sandbox dir / preserved backups after the
#                        run for manual inspection.
#   --timeout SECS       How long to wait for the binary to come up and run
#                        the migration. Default 20s. Bump on slow hardware
#                        or when running under a debugger.
#   --binary PATH        Override the default ./target/debug/lumotia.
#
# Exit codes:
#   0  all probes passed
#   1  a probe failed (migration did not produce the expected on-disk state)
#   2  argument error
#   3  preflight check failed (real-home already has lumotia data, binary
#      missing, unsupported platform for sandbox mode, ...)

set -euo pipefail

MODE="sandbox"
KEEP=false
TIMEOUT_SECS=20
BINARY="./target/debug/lumotia"

# ---- arg parsing -----------------------------------------------------------

while [[ $# -gt 0 ]]; do
    case "$1" in
        --against-real-home) MODE="real-home"; shift ;;
        --keep)              KEEP=true; shift ;;
        --timeout)           TIMEOUT_SECS="$2"; shift 2 ;;
        --binary)            BINARY="$2"; shift 2 ;;
        -h|--help)
            sed -n '2,33p' "$0" | sed 's/^# \{0,1\}//'
            exit 0 ;;
        *) echo "Unknown option: $1" >&2; exit 2 ;;
    esac
done

# ---- preflight -------------------------------------------------------------

if [[ ! -x "$BINARY" ]]; then
    echo "FAIL: binary not found at $BINARY. Run 'cargo build -p lumotia' first." >&2
    exit 3
fi

PLATFORM="$(uname -s)"
if [[ "$MODE" == "sandbox" && "$PLATFORM" == "Darwin" ]]; then
    echo "FAIL: sandbox mode is not faithful on macOS." >&2
    echo "      Tauri 2 uses NSSearchPathForDirectoriesInDomains which ignores HOME overrides." >&2
    echo "      Either run on Linux or use --against-real-home (with backup discipline)." >&2
    exit 3
fi

# Real-home mode: refuse to run if the user already has lumotia data on
# disk. We'd risk merging fake planted state into real data on cleanup.
if [[ "$MODE" == "real-home" ]]; then
    REAL_HOME="$HOME"
    REAL_LUMOTIA_DATA="${XDG_DATA_HOME:-$REAL_HOME/.local/share}/lumotia"
    REAL_LUMOTIA_TAURI="${XDG_DATA_HOME:-$REAL_HOME/.local/share}/consulting.corbel.lumotia"
    for p in "$REAL_LUMOTIA_DATA" "$REAL_LUMOTIA_TAURI" "$REAL_HOME/.lumotia"; do
        if [[ -e "$p" ]]; then
            echo "FAIL: $p already exists. Refusing to run in real-home mode against existing data." >&2
            echo "      Either back it up manually and remove the original, or run in sandbox mode." >&2
            exit 3
        fi
    done
fi

# ---- sandbox setup ---------------------------------------------------------

if [[ "$MODE" == "sandbox" ]]; then
    SANDBOX="$(mktemp -d -t lumotia-dogfood-XXXXXX)"
    export HOME="$SANDBOX"
    unset XDG_DATA_HOME
    PLANT_ROOT="$SANDBOX/.local/share"
    echo "Sandbox: $SANDBOX (HOME overridden)"
else
    SANDBOX=""  # signal: don't tear down a sandbox at the end
    PLANT_ROOT="${XDG_DATA_HOME:-$HOME/.local/share}"
    echo "Real home: planting under $PLANT_ROOT"
fi

LOG_FILE="$(mktemp -t lumotia-dogfood-binary-XXXXXX.log)"

cleanup() {
    if [[ -n "${BINARY_PID:-}" ]] && kill -0 "$BINARY_PID" 2>/dev/null; then
        kill -TERM "$BINARY_PID" 2>/dev/null || true
        sleep 0.5
        kill -KILL "$BINARY_PID" 2>/dev/null || true
    fi
    if [[ "$KEEP" == "false" && -n "$SANDBOX" && -d "$SANDBOX" ]]; then
        rm -rf "$SANDBOX"
    fi
    if [[ "$KEEP" == "false" && "$MODE" == "real-home" ]]; then
        # Real-home cleanup: remove planted legacy state AND any
        # post-migration artefacts we created. We refused to start if
        # any of these existed, so removing them now is safe.
        rm -rf \
            "$PLANT_ROOT/magnotia" \
            "$PLANT_ROOT/uk.co.corbel.magnotia" \
            "$PLANT_ROOT/lumotia" \
            "$PLANT_ROOT/consulting.corbel.lumotia"
    fi
}
trap cleanup EXIT INT TERM

# ---- plant synthetic legacy state -----------------------------------------

mkdir -p "$PLANT_ROOT/magnotia/recordings/2026-05-13"
# Plant a sentinel non-DB file inside the legacy data dir to confirm the
# migration sweeps the whole tree, not just magnotia.db.
echo "fake-wav-bytes-for-dogfood-drill" > "$PLANT_ROOT/magnotia/recordings/2026-05-13/clip.wav"
# An empty file at magnotia.db is enough for the file-level rename probe.
# The Rust integration test (crates/storage/tests/legacy_db_migration.rs)
# covers the "DB still openable after rename" path with a real SQLite;
# this drill is about the LIVE BINARY at startup, not schema integrity.
: > "$PLANT_ROOT/magnotia/magnotia.db"

mkdir -p "$PLANT_ROOT/uk.co.corbel.magnotia/localStorage/leveldb"
echo "sentinel-leveldb-bytes" > "$PLANT_ROOT/uk.co.corbel.magnotia/localStorage/leveldb/000003.log"
echo '{"main":{"x":100,"y":200,"width":1280,"height":720}}' > "$PLANT_ROOT/uk.co.corbel.magnotia/window-state.json"

echo "Planted synthetic legacy state. Launching $BINARY..."

# ---- launch binary in background, give it time to run migrations ----------

# RUST_LOG forces lumotia_startup tracing events to disk regardless of any
# default filter. The setup hook logs `migrated legacy magnotia data dir`
# at info level on a successful rename.
RUST_LOG="lumotia_startup=info,lumotia=info" \
    "$BINARY" >"$LOG_FILE" 2>&1 &
BINARY_PID=$!

# Wait for either: the migration log line to appear, OR the timeout.
DEADLINE=$(( $(date +%s) + TIMEOUT_SECS ))
MIGRATED_DATA_DIR_SEEN=false
MIGRATED_TAURI_DIR_SEEN=false
while (( $(date +%s) < DEADLINE )); do
    if grep -q "migrated legacy magnotia data dir to lumotia" "$LOG_FILE" 2>/dev/null; then
        MIGRATED_DATA_DIR_SEEN=true
    fi
    if grep -qE "Migrated|migrated.*tauri.*app_data|copied legacy Tauri" "$LOG_FILE" 2>/dev/null; then
        MIGRATED_TAURI_DIR_SEEN=true
    fi
    if [[ "$MIGRATED_DATA_DIR_SEEN" == "true" ]]; then
        # Give the Tauri side another moment after the data-dir migration.
        sleep 1
        break
    fi
    sleep 0.5
done

# SIGTERM the binary cleanly. We don't need it running for the probes —
# all probes inspect the post-migration filesystem state.
if kill -0 "$BINARY_PID" 2>/dev/null; then
    kill -TERM "$BINARY_PID" || true
fi
wait "$BINARY_PID" 2>/dev/null || true

# ---- probes ----------------------------------------------------------------

PROBES_PASSED=0
PROBES_FAILED=0
report_probe() {
    local name="$1"; local outcome="$2"; local detail="${3:-}"
    if [[ "$outcome" == "PASS" ]]; then
        printf '  PASS  %s\n' "$name"
        PROBES_PASSED=$(( PROBES_PASSED + 1 ))
    else
        printf '  FAIL  %s  %s\n' "$name" "$detail"
        PROBES_FAILED=$(( PROBES_FAILED + 1 ))
    fi
}

printf '\nProbe results:\n'

# 1. Data-dir migration: target exists at the new path.
if [[ -d "$PLANT_ROOT/lumotia" ]]; then
    report_probe "data-dir rename produced ~/.local/share/lumotia/" PASS
else
    report_probe "data-dir rename produced ~/.local/share/lumotia/" FAIL "(missing)"
fi

# 2. Data-dir migration: lumotia.db is at the new path.
if [[ -f "$PLANT_ROOT/lumotia/lumotia.db" ]]; then
    report_probe "magnotia.db renamed to lumotia.db at new path" PASS
else
    report_probe "magnotia.db renamed to lumotia.db at new path" FAIL "(missing)"
fi

# 3. Data-dir migration: legacy magnotia tree is gone (rename moved it).
if [[ ! -d "$PLANT_ROOT/magnotia" ]]; then
    report_probe "legacy ~/.local/share/magnotia/ removed by rename" PASS
else
    report_probe "legacy ~/.local/share/magnotia/ removed by rename" FAIL "(still on disk)"
fi

# 4. Data-dir migration: non-DB companion file carried along.
if [[ -f "$PLANT_ROOT/lumotia/recordings/2026-05-13/clip.wav" ]]; then
    report_probe "non-DB companion file carried along by directory rename" PASS
else
    report_probe "non-DB companion file carried along by directory rename" FAIL "(missing)"
fi

# 5. Tauri migration: webview/localStorage copied to new bundle id path.
if [[ -f "$PLANT_ROOT/consulting.corbel.lumotia/localStorage/leveldb/000003.log" ]]; then
    report_probe "Tauri app_data_dir copied to consulting.corbel.lumotia/" PASS
else
    report_probe "Tauri app_data_dir copied to consulting.corbel.lumotia/" FAIL "(localStorage missing)"
fi

# 6. Tauri migration: legacy uk.co.corbel.magnotia preserved as backup.
if [[ -f "$PLANT_ROOT/uk.co.corbel.magnotia/localStorage/leveldb/000003.log" ]]; then
    report_probe "legacy Tauri dir preserved as backup" PASS
else
    report_probe "legacy Tauri dir preserved as backup" FAIL "(missing — migration should NOT delete legacy)"
fi

# 7. Tauri migration: staging dir cleaned up.
if [[ ! -d "$PLANT_ROOT/consulting.corbel.lumotia.migrating" ]]; then
    report_probe "staging dir consulting.corbel.lumotia.migrating cleaned up" PASS
else
    report_probe "staging dir consulting.corbel.lumotia.migrating cleaned up" FAIL "(staging leaked)"
fi

# 8. Log line: lumotia_startup migration event appeared.
if [[ "$MIGRATED_DATA_DIR_SEEN" == "true" ]]; then
    report_probe "lumotia_startup logged the data-dir migration" PASS
else
    report_probe "lumotia_startup logged the data-dir migration" FAIL "(no log line within ${TIMEOUT_SECS}s)"
fi

# ---- summary --------------------------------------------------------------

printf '\nLog file: %s\n' "$LOG_FILE"
if [[ "$KEEP" == "true" && -n "$SANDBOX" ]]; then
    printf 'Sandbox preserved at: %s\n' "$SANDBOX"
fi

printf '\nPassed: %s / Failed: %s\n' "$PROBES_PASSED" "$PROBES_FAILED"

if (( PROBES_FAILED > 0 )); then
    printf '\nDrill FAILED. Inspect %s for clues.\n' "$LOG_FILE"
    exit 1
fi

printf '\nDrill PASSED. Rebrand migration runs end-to-end against real OS paths.\n'
