#!/usr/bin/env bash
# retoor <retoor@molodetz.nl>

set -uo pipefail
cd "$(dirname "${BASH_SOURCE[0]}")" 2>/dev/null || true

REPO_DIR="${DEVPLACE_REPO_DIR:-/home/retoor/projects/devplacepy}"
cd "$REPO_DIR" || { echo "Cannot cd into $REPO_DIR - set DEVPLACE_REPO_DIR"; exit 1; }

if [ -x "$REPO_DIR/.venv/bin/devplace" ]; then
    DEVPLACE="$REPO_DIR/.venv/bin/devplace"
elif command -v devplace >/dev/null 2>&1; then
    DEVPLACE="devplace"
else
    echo "Cannot find the devplace binary (looked in $REPO_DIR/.venv/bin and PATH)."
    echo "Run 'make install' once to create the .venv, or activate it yourself."
    exit 1
fi

if [ -x "$REPO_DIR/.venv/bin/python" ]; then
    PYTHON="$REPO_DIR/.venv/bin/python"
elif command -v python3 >/dev/null 2>&1; then
    PYTHON="python3"
else
    echo "Cannot find a python interpreter (looked in $REPO_DIR/.venv/bin and PATH)."
    exit 1
fi

DIRS=(
    data/uploads
    data/uploads/attachments
    data/uploads/project_files
    data/zips
    data/zip_staging
    data/fork_staging
    data/seo_reports
    data/deepsearch
    data/isslop
    data/container_workspaces
    data/workspace_state
)

show_sizes() {
    echo "--- $1 ---"
    for d in "${DIRS[@]}"; do
        if [ -d "$d" ]; then
            printf "  %-10s  %s\n" "$(du -sh "$d" 2>/dev/null | cut -f1)" "$d"
        else
            printf "  %-10s  %s\n" "-" "$d (absent)"
        fi
    done
    echo
}

FAILED=()

run() {
    echo "=== devplace $* ==="
    "$DEVPLACE" "$@"
    local status=$?
    if [ "$status" -ne 0 ]; then
        echo "!!! FAILED (exit $status): devplace $*"
        FAILED+=("devplace $*")
    fi
    echo
}

echo "########################################"
echo "# DevPlace maintenance cleanup"
echo "# backups and news are deliberately excluded"
echo "########################################"
echo

show_sizes "BEFORE"

run attachments prune
run zips prune
run zips clear
run forks prune
run forks clear
run seo prune
run seo clear
run seo-meta prune
run seo-meta clear
run deepsearch prune
run deepsearch clear
run isslop prune
run isslop clear
run quiz prune
run game market prune
run game steals prune
run messaging prune-tickets
run devii tasks prune
run accounts prune
run containers prune
run containers prune-builds
run containers gc-workspaces

show_sizes "AFTER"

echo "########################################"
echo "# Soft-deleted attachment / project-file blobs still on disk"
echo "# (READ-ONLY report - nothing below this line deletes anything;"
echo "#  none of the commands above purge these, only the admin Trash"
echo "#  'Purge' button per-event, or accounts prune, do that today)"
echo "########################################"
"$PYTHON" - "$REPO_DIR" <<'PY'
import sqlite3
import sys
from pathlib import Path

repo_dir = Path(sys.argv[1])
data_dir = Path(__import__("os").environ.get("DEVPLACE_DATA_DIR", str(repo_dir / "data")))
db_path = data_dir / "devplace.db"


def human(n):
    n = float(n)
    for unit in ("B", "KB", "MB", "GB", "TB"):
        if n < 1024:
            return f"{n:.1f}{unit}"
        n /= 1024
    return f"{n:.1f}PB"


if not db_path.exists():
    print(f"  {db_path} does not exist, skipping")
    raise SystemExit(0)

con = sqlite3.connect(f"file:{db_path}?mode=ro", uri=True)
try:
    cur = con.cursor()

    def columns(table):
        return {row[1] for row in cur.execute(f"PRAGMA table_info('{table}')")}

    # attachments: data/uploads/attachments/{directory}/{stored_name}, plus any
    # {stem}_thumb.* sibling thumbnail (see attachments._unlink_attachment_files)
    cols = columns("attachments")
    if {"directory", "stored_name", "deleted_at"} <= cols:
        rows = cur.execute(
            "SELECT directory, stored_name FROM attachments WHERE deleted_at IS NOT NULL"
        ).fetchall()
        base = data_dir / "uploads" / "attachments"
        present, total = 0, 0
        for directory, stored_name in rows:
            if not directory or not stored_name:
                continue
            fp = base / directory / stored_name
            if fp.exists():
                present += 1
                try:
                    total += fp.stat().st_size
                except OSError:
                    pass
                stem = Path(stored_name).stem
                for thumb in (base / directory).glob(f"{stem}_thumb.*"):
                    try:
                        total += thumb.stat().st_size
                    except OSError:
                        pass
        print(
            f"  attachments:   {len(rows)} soft-deleted row(s), "
            f"{present} still on disk, {human(total)} reclaimable"
        )
    else:
        print(f"  attachments: unexpected schema, columns={sorted(cols)}")

    # project_files: data/uploads/project_files/{directory}/{stored_name},
    # only rows with is_binary=1 have a blob at all (text lives in the DB row)
    cols = columns("project_files")
    if {"directory", "stored_name", "deleted_at", "is_binary"} <= cols:
        rows = cur.execute(
            "SELECT directory, stored_name FROM project_files "
            "WHERE deleted_at IS NOT NULL AND is_binary = 1"
        ).fetchall()
        base = data_dir / "uploads" / "project_files"
        present, total = 0, 0
        for directory, stored_name in rows:
            if not directory or not stored_name:
                continue
            fp = base / directory / stored_name
            if fp.exists():
                present += 1
                try:
                    total += fp.stat().st_size
                except OSError:
                    pass
        print(
            f"  project_files: {len(rows)} soft-deleted binary row(s), "
            f"{present} still on disk, {human(total)} reclaimable"
        )
    else:
        print(f"  project_files: unexpected schema, columns={sorted(cols)}")
finally:
    con.close()
PY
echo

if [ "${#FAILED[@]}" -gt 0 ]; then
    echo "########################################"
    echo "# ${#FAILED[@]} command(s) failed:"
    for cmd in "${FAILED[@]}"; do
        echo "#   $cmd"
    done
    echo "########################################"
    exit 1
fi

echo "All commands completed successfully."
