#!/usr/bin/env bash
# database/optimize -- OPTIMIZE TABLE on every table of a database
set -o pipefail
SELF=$(readlink -f "${BASH_SOURCE[0]}")
NV_BASE=$(cd "$(dirname "$SELF")/../../.." && pwd)
export NV_BASE
# shellcheck source=/dev/null
. "$NV_BASE/lib/core/bootstrap.sh"

nv_require_root || exit 1
ui_header "$(t db_m_optimize)"
db_available || { ui_err "$(t db_unreachable)"; exit 1; }

if [ $# -ge 1 ]; then name=$1; else
    printf '  %s: ' "$(t db_prompt_name)"
    read -r name || exit 130
fi
name=$(nv_trim "$name")
nv_valid_dbname "$name" || { ui_err "$(t db_bad_name)"; exit 2; }

ui_kv "$(t db_name)" "$name"
ui_info "$(t db_optimize_note)"
ui_confirm "$(t db_optimize_q)" n || exit 0

tables=$(db_root_exec "SELECT table_name FROM information_schema.tables WHERE table_schema='$name' AND engine='InnoDB'" 2>/dev/null)
[ -n "$tables" ] || { ui_info "$(t db_optimize_none)"; exit 0; }

ui_step "$(t db_optimize_running)"
before=$(db_root_exec "SELECT ROUND(SUM(data_length+index_length)/1024/1024,2) FROM information_schema.tables WHERE table_schema='$name'" 2>/dev/null)

ok=0; fail=0
for t in $tables; do
    if db_root_exec "OPTIMIZE TABLE \`$t\`" >/dev/null 2>&1; then
        ok=$((ok + 1))
    else
        fail=$((fail + 1))
        ui_warn "$(t db_optimize_failed_table "$t")"
    fi
done

after=$(db_root_exec "SELECT ROUND(SUM(data_length+index_length)/1024/1024,2) FROM information_schema.tables WHERE table_schema='$name'" 2>/dev/null)
nv_trace db-optimize "$name ok=$ok fail=$fail"

ui_blank
ui_kv "$(t db_optimize_ok)"   "$ok"
ui_kv "$(t backup_failed)"    "$fail"
ui_kv "$(t db_optimize_before)" "${before:-0} MB"
ui_kv "$(t db_optimize_after)"  "${after:-0} MB"
exit 0
