#!/usr/bin/env bash
# run-tests.sh — test suite untuk backup.sh.
# Suite menyiapkan sendiri folder kerja terisolasi (mktemp) beserta
# data contohnya, menyalin src/backup.sh dan config/backup.conf,
# lalu menjalankan rangkaian pengujian dengan assertion sederhana.
# Jalankan dari mana saja: bash tests/run-tests.sh

set -u

SCRIPT_DIR=$(cd "$(dirname "$0")" && pwd)
PROJ_DIR=$(dirname "$SCRIPT_DIR")

PASS=0
FAIL=0

# assert_eq <harapan> <nyata> <pesan>: bandingkan dua nilai.
assert_eq() {
    if [ "$1" = "$2" ]; then
        PASS=$((PASS + 1))
        printf 'OK    %s\n' "$3"
    else
        FAIL=$((FAIL + 1))
        printf 'GAGAL %s: harapan %s, nyata %s\n' "$3" "$1" "$2"
    fi
}

# --- siapkan folder kerja terisolasi ------------------------------------
WORK=$(mktemp -d)
cp "$PROJ_DIR/src/backup.sh" "$PROJ_DIR/config/backup.conf" "$WORK/"
cd "$WORK" || exit 1

# Data contoh (fixture) mengikuti config/backup.conf bawaan.
mkdir -p dokumen/laporan proyek/catatan
printf 'daftar tugas minggu ini\n' > dokumen/tugas.txt
printf 'laporan penjualan kuartal pertama\n' > dokumen/laporan/penjualan.txt
printf 'ide aplikasi cuaca\n' > proyek/catatan/ide.txt

# --- uji 1: eksekusi sukses keluar 0 ------------------------------------
STAMP=20260115 bash backup.sh > /dev/null 2>&1
assert_eq 0 "$?" "backup sukses keluar 0"
touch -d "2026-01-15 09:00" arsip/backup-20260115

# --- uji 2: arsip dan checksum dibuat -----------------------------------
[ -f arsip/backup-20260115/dokumen.tar.gz ]
assert_eq 0 "$?" "arsip dokumen.tar.gz dibuat"
[ -f arsip/backup-20260115/proyek.tar.gz ]
assert_eq 0 "$?" "arsip proyek.tar.gz dibuat"
[ -f arsip/backup-20260115/dokumen.tar.gz.sha256 ]
assert_eq 0 "$?" "checksum dokumen.tar.gz.sha256 dibuat"

# --- uji 3: isi arsip benar ----------------------------------------------
isi=$(tar -tzf arsip/backup-20260115/dokumen.tar.gz |
    grep -c '^dokumen/tugas.txt$')
assert_eq 1 "$isi" "tugas.txt tercantum di dalam arsip"

# --- uji 4: checksum arsip konsisten -------------------------------------
( cd arsip/backup-20260115 && sha256sum -c dokumen.tar.gz.sha256 \
    > /dev/null 2>&1 )
assert_eq 0 "$?" "checksum arsip cocok"

# --- uji 5: restore penuh identik dengan sumber ---------------------------
mkdir -p pulih
tar -xzf arsip/backup-20260115/dokumen.tar.gz -C pulih
tar -xzf arsip/backup-20260115/proyek.tar.gz -C pulih
diff -r dokumen pulih/dokumen > /dev/null 2>&1
assert_eq 0 "$?" "restore dokumen identik"
diff -r proyek pulih/proyek > /dev/null 2>&1
assert_eq 0 "$?" "restore proyek identik"

# --- uji 6: mirror mengikuti keadaan terkini -------------------------------
printf 'daftar tugas minggu ini (revisi)\n' > dokumen/tugas.txt
STAMP=20260116 bash backup.sh > /dev/null 2>&1
assert_eq 0 "$?" "backup kedua sukses keluar 0"
touch -d "2026-01-16 09:00" arsip/backup-20260116
diff -r dokumen arsip/mirror/dokumen > /dev/null 2>&1
assert_eq 0 "$?" "mirror memuat revisi terbaru"

# --- uji 7: rotasi menyisakan 3 run ---------------------------------------
# Waktu tiap folder ditandai agar urutan ls -t pasti deterministik.
for s in 20260117 20260118 20260119 20260120; do
    STAMP=$s bash backup.sh > /dev/null 2>&1
    touch -d "${s:0:4}-${s:4:2}-${s:6:2} 09:00" "arsip/backup-$s"
done
jumlah=$(ls -1d arsip/backup-* | wc -l)
assert_eq 3 "$jumlah" "rotasi menyisakan 3 run"
[ -d arsip/backup-20260120 ]
assert_eq 0 "$?" "run terbaru tetap ada"
[ ! -d arsip/backup-20260115 ]
assert_eq 0 "$?" "run tertua sudah dirotasi"

# --- uji 8: exit code untuk masalah konfigurasi dan sumber -----------------
printf 'BACKUP_DIRS=""\nBACKUP_DEST="arsip"\nKEEP_ARCHIVES=3\n' > kosong.conf
CONF=kosong.conf bash backup.sh > /dev/null 2>&1
assert_eq 1 "$?" "konfigurasi kosong keluar 1"
printf 'BACKUP_DIRS="dokumen foto"\nBACKUP_DEST="arsip"\nKEEP_ARCHIVES=3\n' > rusak.conf
CONF=rusak.conf bash backup.sh > /dev/null 2>&1
assert_eq 2 "$?" "sumber hilang keluar 2"

# --- uji 9: kunci flock menolak backup ganda -------------------------------
flock arsip/.backup.lock sleep 3 &
sleep 0.5
STAMP=20260121 bash backup.sh > /dev/null 2>&1
assert_eq 5 "$?" "backup ganda ditolak keluar 5"
wait

# --- ringkasan --------------------------------------------------------------
if [ "$FAIL" -eq 0 ]; then
    printf 'PASSED: %d/%d test lulus\n' "$PASS" "$PASS"
else
    printf 'FAILED: %d/%d test lulus\n' "$PASS" "$((PASS + FAIL))"
fi
cd / && rm -rf "$WORK"
[ "$FAIL" -eq 0 ]
