#!/usr/bin/env bash
set -euo pipefail
###############################################################################
# relocate-cpanel-importer-roots.sh
#
# Moves the cpanel-importer sandbox's bind-mount roots from
#   /var/lib/whp/cpanel-importer-{extract,quarantine}      (host root fs)
# to
#   /docker/whp/cpanel-importer-{extract,quarantine}       (data disk)
#
# Why: the host root partition on a stock WHP install is small (commonly
# 50-100 GB); the /docker mount is the dedicated data disk (typically
# 500GB-2TB+). A multi-GB cpmove extract that overflows the host root
# leaves the OS in a precarious state — surfaced on whp02 alsacorp
# re-import where the host hit 93% / 6.4G free mid-tar and the container
# died with "No space left on device" on every subsequent file.
#
# Idempotent. Safe to re-run.
#
# Strategy:
#   1. Create the new /docker/whp/cpanel-importer-{extract,quarantine}
#      dirs with the same ownership/mode the panel expects (999:999 0750).
#   2. Move any contents of the legacy /var/lib/whp/* dirs into the new
#      locations (mv is constant-time on the same filesystem; cp+rm if
#      cross-fs). Anything already-relocated is skipped.
#   3. Symlink the legacy paths to the new ones so any script /
#      docs that still reference /var/lib/whp/cpanel-importer-* keeps
#      working. tar's bind mount, the panel's defensive chown, the
#      quarantine sweeper, the History panel — all of these resolve
#      paths via the kernel which follows symlinks transparently.
#
# Defense:
#   - Refuses to run if the new /docker/whp/* path is on the SAME
#     filesystem as /var/lib (in that case the relocation gains nothing
#     and an operator may have a non-standard mount layout we should
#     leave alone).
#   - Each per-import subdir move is wrapped in a per-dir check so a
#     partial run can be resumed.
###############################################################################

LEGACY_EXTRACT=/var/lib/whp/cpanel-importer-extract
LEGACY_QUAR=/var/lib/whp/cpanel-importer-quarantine
NEW_EXTRACT=/docker/whp/cpanel-importer-extract
NEW_QUAR=/docker/whp/cpanel-importer-quarantine

echo "=== Relocating cpanel-importer bind-mount roots to /docker/whp ==="

# Sanity: /docker should exist and be a different filesystem than /var/lib
if [ ! -d /docker ]; then
    echo "FATAL: /docker does not exist on this host; refusing to relocate"
    exit 1
fi
LEGACY_FS=$(stat -c %d /var/lib 2>/dev/null || echo unknown-legacy)
NEW_FS=$(stat -c %d /docker 2>/dev/null || echo unknown-new)
if [ "$LEGACY_FS" = "$NEW_FS" ]; then
    echo "Note: /var/lib and /docker are on the same filesystem; relocation"
    echo "doesn't free up the host root, but we'll still proceed so the panel"
    echo "uses the canonical /docker/whp paths going forward."
fi

# Create new roots with the panel-expected ownership.
mkdir -p "$NEW_EXTRACT" "$NEW_QUAR"
chown 999:999 "$NEW_EXTRACT" "$NEW_QUAR"
chmod 0750 "$NEW_EXTRACT" "$NEW_QUAR"
echo "[mkdir] $NEW_EXTRACT (999:999, 0750)"
echo "[mkdir] $NEW_QUAR (999:999, 0750)"

# Migrate per-import subdirs from the legacy locations if they exist as
# real dirs (not already-symlinks).
migrate_dir() {
    local legacy="$1"
    local new="$2"
    local label="$3"

    if [ ! -e "$legacy" ]; then
        echo "[migrate $label] legacy path $legacy doesn't exist; nothing to migrate"
        return 0
    fi
    if [ -L "$legacy" ]; then
        echo "[migrate $label] $legacy is already a symlink → $(readlink "$legacy"); skipping content move"
        return 0
    fi
    if [ ! -d "$legacy" ]; then
        echo "[migrate $label] $legacy exists but isn't a directory; refusing to touch"
        return 1
    fi

    # Move each per-import subdir individually so a partial run is
    # restartable. nullglob keeps the loop from running on an empty dir.
    shopt -s nullglob
    local moved=0
    for sub in "$legacy"/*; do
        local name=$(basename "$sub")
        local dest="$new/$name"
        if [ -e "$dest" ]; then
            echo "[migrate $label] $name already at $dest; skipping"
            continue
        fi
        echo "[migrate $label] moving $sub -> $dest"
        mv "$sub" "$dest" || cp -a "$sub" "$dest" && rm -rf "$sub"
        moved=$((moved + 1))
    done
    shopt -u nullglob
    echo "[migrate $label] moved $moved subdir(s)"
}

migrate_dir "$LEGACY_EXTRACT" "$NEW_EXTRACT" "extract"
migrate_dir "$LEGACY_QUAR"    "$NEW_QUAR"    "quarantine"

# Replace the legacy dirs with symlinks pointing at the new locations.
# If the legacy dir is now empty, rmdir + symlink. If it's already a
# symlink to the right target, refresh defensively.
relink() {
    local legacy="$1"
    local target="$2"

    if [ -L "$legacy" ]; then
        local current
        current=$(readlink "$legacy")
        if [ "$current" = "$target" ]; then
            echo "[symlink] $legacy already points to $target"
            return 0
        fi
        echo "[symlink] $legacy points to $current; refreshing to $target"
        ln -sfn "$target" "$legacy"
        return 0
    fi
    if [ -d "$legacy" ]; then
        # Only rmdir if empty (migration above should have emptied it).
        if rmdir "$legacy" 2>/dev/null; then
            echo "[symlink] removed empty $legacy"
        else
            echo "[symlink] $legacy is non-empty after migration; refusing to symlink (operator review needed)"
            return 1
        fi
    fi
    # Make sure the parent exists (fresh installs may not have /var/lib/whp yet)
    mkdir -p "$(dirname "$legacy")"
    ln -sfn "$target" "$legacy"
    echo "[symlink] $legacy -> $target"
}

relink "$LEGACY_EXTRACT" "$NEW_EXTRACT"
relink "$LEGACY_QUAR"    "$NEW_QUAR"

echo "=== Relocation complete ==="
echo "  /docker/whp/cpanel-importer-extract:    $(stat -c '%U:%G %a' "$NEW_EXTRACT")"
echo "  /docker/whp/cpanel-importer-quarantine: $(stat -c '%U:%G %a' "$NEW_QUAR")"
df -h /docker | tail -1 | awk '{ printf "  /docker disk: %s used / %s avail (%s)\n", $3, $4, $5 }'
