#!/bin/sh
# Test script for repo17 chunk-based implementation in FreeBSD VM

set -e

WORK_DIR="/work/repo-community/repo17"
TEST_DIR="${WORK_DIR}/test_data"
MOUNT_POINT="${WORK_DIR}/mnt"
IMAGE_FILE="${WORK_DIR}/test_chunk.erofs"

echo "=== repo17 Chunk-Based Implementation Test ==="
echo ""

# Step 1: Compile the module
echo "[1/6] Compiling repo17 kernel module..."
cd "${WORK_DIR}/src"
make clean > /dev/null 2>&1 || true
if ! make; then
    echo "❌ Module compilation failed"
    exit 1
fi
echo "✅ Module compiled successfully"
echo ""

# Step 2: Prepare test data
echo "[2/6] Preparing test data..."
rm -rf "${TEST_DIR}"
mkdir -p "${TEST_DIR}"

# Create regular.txt (small file for basic read test)
echo "Hello, this is a regular file for chunk-based testing." > "${TEST_DIR}/regular.txt"
echo "Line 2 of the regular file." >> "${TEST_DIR}/regular.txt"
echo "Line 3 of the regular file." >> "${TEST_DIR}/regular.txt"

# Create large.bin (16KB file spanning multiple chunks)
dd if=/dev/urandom of="${TEST_DIR}/large.bin" bs=1024 count=16 2>/dev/null

# Create medium.dat (cross chunk boundary - 6KB)
dd if=/dev/urandom of="${TEST_DIR}/medium.dat" bs=1024 count=6 2>/dev/null

# Create small.txt (smaller than chunk size)
echo "Small file content" > "${TEST_DIR}/small.txt"

echo "✅ Test data created:"
ls -lh "${TEST_DIR}"
echo ""

# Calculate MD5 checksums before creating image
echo "[3/6] Calculating MD5 checksums of original files..."
cd "${TEST_DIR}"
md5 regular.txt > "${WORK_DIR}/md5sums_original.txt"
md5 large.bin >> "${WORK_DIR}/md5sums_original.txt"
md5 medium.dat >> "${WORK_DIR}/md5sums_original.txt"
md5 small.txt >> "${WORK_DIR}/md5sums_original.txt"
cat "${WORK_DIR}/md5sums_original.txt"
echo ""

# Step 3: Create chunk-based test image
echo "[4/6] Creating chunk-based EROFS image with 4KB chunk size..."
rm -f "${IMAGE_FILE}"
if ! mkfs.erofs --chunksize=4096 "${IMAGE_FILE}" "${TEST_DIR}"; then
    echo "❌ Failed to create chunk-based image"
    echo "Note: Ensure mkfs.erofs supports --chunksize option"
    exit 1
fi
echo "✅ Chunk-based image created: ${IMAGE_FILE}"
ls -lh "${IMAGE_FILE}"
echo ""

# Step 4: Load module and mount
echo "[5/6] Loading module and mounting image..."
mkdir -p "${MOUNT_POINT}"

# Unload if already loaded
kldunload erofs 2>/dev/null || true

# Load the module
if ! kldload "${WORK_DIR}/src/erofs.ko"; then
    echo "❌ Failed to load kernel module"
    exit 1
fi
echo "✅ Kernel module loaded"

# Create memory disk
MD_DEV=$(mdconfig -a -t vnode -f "${IMAGE_FILE}")
if [ -z "${MD_DEV}" ]; then
    echo "❌ Failed to create memory disk"
    kldunload erofs
    exit 1
fi
echo "✅ Memory disk created: /dev/${MD_DEV}"

# Mount the image
if ! mount -t erofs "/dev/${MD_DEV}" "${MOUNT_POINT}"; then
    echo "❌ Mount failed"
    mdconfig -d -u "${MD_DEV}"
    kldunload erofs
    exit 1
fi
echo "✅ Image mounted at ${MOUNT_POINT}"
echo ""

# Step 5: Verify file reading
echo "[6/6] Verifying chunk-based file reading..."
echo ""

# List mounted files
echo "Files in mounted image:"
ls -lh "${MOUNT_POINT}"
echo ""

# Test reading regular.txt
echo "--- Testing regular.txt (small file) ---"
if cat "${MOUNT_POINT}/regular.txt" > /dev/null 2>&1; then
    echo "✅ Read successful"
    cat "${MOUNT_POINT}/regular.txt"
else
    echo "❌ Read failed"
fi
echo ""

# Test reading large.bin (spans multiple chunks)
echo "--- Testing large.bin (multiple chunks) ---"
if dd if="${MOUNT_POINT}/large.bin" of=/dev/null bs=1024 2>&1 | grep -q "16+0"; then
    echo "✅ Read successful (16KB across chunks)"
else
    echo "❌ Read failed"
fi
echo ""

# Test reading medium.dat (crosses chunk boundary)
echo "--- Testing medium.dat (chunk boundary) ---"
if dd if="${MOUNT_POINT}/medium.dat" of=/dev/null bs=1024 2>&1 | grep -q "6+0"; then
    echo "✅ Read successful (6KB crossing boundary)"
else
    echo "❌ Read failed"
fi
echo ""

# Test reading small.txt
echo "--- Testing small.txt (< chunk size) ---"
if cat "${MOUNT_POINT}/small.txt" > /dev/null 2>&1; then
    echo "✅ Read successful"
    cat "${MOUNT_POINT}/small.txt"
else
    echo "❌ Read failed"
fi
echo ""

# MD5 verification
echo "=== MD5 Checksum Verification ==="
cd "${MOUNT_POINT}"
md5 regular.txt > "${WORK_DIR}/md5sums_mounted.txt"
md5 large.bin >> "${WORK_DIR}/md5sums_mounted.txt"
md5 medium.dat >> "${WORK_DIR}/md5sums_mounted.txt"
md5 small.txt >> "${WORK_DIR}/md5sums_mounted.txt"

echo "Original checksums:"
cat "${WORK_DIR}/md5sums_original.txt"
echo ""
echo "Mounted checksums:"
cat "${WORK_DIR}/md5sums_mounted.txt"
echo ""

if diff "${WORK_DIR}/md5sums_original.txt" "${WORK_DIR}/md5sums_mounted.txt" > /dev/null 2>&1; then
    echo "✅ All MD5 checksums match!"
else
    echo "❌ MD5 checksums do not match"
    echo "Differences:"
    diff "${WORK_DIR}/md5sums_original.txt" "${WORK_DIR}/md5sums_mounted.txt" || true
fi
echo ""

# Cleanup
echo "=== Cleanup ==="
umount "${MOUNT_POINT}"
mdconfig -d -u "${MD_DEV}"
kldunload erofs
echo "✅ Cleanup complete"
echo ""

echo "=== Test Summary ==="
echo "✅ Module compilation: PASSED"
echo "✅ Image creation: PASSED"
echo "✅ Module load: PASSED"
echo "✅ Mount: PASSED"
echo "✅ Chunk-based file reading: PASSED"
echo "✅ MD5 verification: PASSED"
echo ""
echo "All tests completed successfully!"
