#!/bin/bash

set -e
set -x

# Define log function first
log() {
    # Create log file if it doesn't exist
    if [ ! -f test.log ]; then
        touch test.log
        chmod 666 test.log
    fi
    echo "$(date "+%Y-%m-%d %H:%M:%S") $1" | tee -a test.log
}

# Install required dependencies with pip
if ! python3 -c "import libarchive" 2>/dev/null; then
    log "==> Installing required dependencies"
    python3 -m pip install libarchive-c || {
        log "ERROR: Failed to install libarchive-c with pip"
        exit 1
    }
fi

# Create test directory structure
log "==> Creating test structure"
TEST_DIR="$HOME/test-archive"
MOCK_UPSTREAM="/srv/mock-upstream"  # Mock the remote archive
mkdir -p "$TEST_DIR"
mkdir -p "$TEST_DIR/repos"
mkdir -p "$TEST_DIR/packages"
mkdir -p "$MOCK_UPSTREAM/core/os/x86_64"
mkdir -p "$MOCK_UPSTREAM/extra/os/x86_64"

# Create some test packages in mock upstream
log "==> Creating test packages"
echo "test package 1" > "$MOCK_UPSTREAM/core/os/x86_64/test-1.0-1-x86_64.pkg.tar.zst"
echo "test package 2" > "$MOCK_UPSTREAM/extra/os/x86_64/test-2.0-1-x86_64.pkg.tar.zst"

# Update test config to use local path instead of rsync
log "==> Writing test config"
cat > /tmp/archive.conf << EOF
ARCHIVE_RSYNC="$MOCK_UPSTREAM/"
ARCHIVE_DIR="$TEST_DIR"
ARCHIVE_USER=root
ARCHIVE_GROUP=root
PKGREGEX='\.pkg\.tar(\.(gz|bz2|xz|zst|lrz|lzo|Z|lz4|lz))?'
PKGSIGREGEX="\$PKGREGEX\.sig"
UMASK=022
ARCHIVE_REPO=1
REPO_DAYLY=1
REPO_PACKAGES=1
REPO_PACKAGES_INDEX=1
REPO_PACKAGES_FULL_SEARCH=0
REPO_RSYNC_TIMEOUT=60
ARCHIVE_ISO=0
EOF

export ARCHIVE_CONFIG=/tmp/archive.conf

# Wrap archive.sh to add logging
run_archive() {
    log "  -> Starting archive.sh"
    log "  -> Current directory: $(pwd)"
    log "  -> Contents of MOCK_UPSTREAM:"
    ls -la "$MOCK_UPSTREAM"
    log "  -> Contents of TEST_DIR:"
    ls -la "$TEST_DIR"
    
    # Run archive.sh with debug output
    DEBUG=1 ./archive.sh 2>&1 | while IFS= read -r line; do
        log "    $line"
    done
    
    local status=${PIPESTATUS[0]}
    log "  -> archive.sh finished with status $status"
    return $status
}

# Test Suite
run_tests() {
    log "==> Starting test suite"
    log "==> Using test directory: $TEST_DIR"
    log "==> Using config: $ARCHIVE_CONFIG"
    log "==> Contents of config:"
    cat "$ARCHIVE_CONFIG"

    log "==> Test 1: Basic archive sync"
    run_archive || {
        log "ERROR: Basic archive sync failed"
        exit 1
    }
    
    log "==> Test 2: Verify archive structure"
    test -d "$TEST_DIR/repos" || {
        log "ERROR: repos directory missing"
        exit 1
    }
    test -d "$TEST_DIR/packages" || {
        log "ERROR: packages directory missing"
        exit 1
    }
    
    log "==> Test 3: Test archive-cleaner"
    # Clean up any existing test files and links first
    rm -rf "$TEST_DIR/repos/2025/02/21"
    rm -rf "$TEST_DIR/packages/t/test"
    rm -rf "$TEST_DIR/packages/.all"

    # Create test environment for archive-cleaner
    mkdir -p "$TEST_DIR/repos/2025/02/21/core/os/x86_64"
    mkdir -p "$TEST_DIR/repos/2025/02/21/extra/os/x86_64"
    mkdir -p "$TEST_DIR/packages/t/test"
    mkdir -p "$TEST_DIR/packages/.all"

    # Create test packages with proper .BUILDINFO content
    # Note: Using tar to create proper package archives with .BUILDINFO files
    (
        cd "$TEST_DIR/repos/2025/02/21/core/os/x86_64"
        mkdir -p test1
        cat > test1/.BUILDINFO << EOF
format = 1
pkgname = test
pkgver = 1.0
pkgrel = 1
pkgarch = x86_64
packager = Arch Linux <arch@archlinux.org>
builddate = $(date +%s)
builddir = /build
startdir = /build
buildenv = !distcc
buildenv = color
buildenv = !ccache
buildenv = check
buildenv = !sign
installed = test-1.0-1-x86_64
EOF
        tar czf test-1.0-1-x86_64.pkg.tar.zst test1/.BUILDINFO
        rm -rf test1
    )

    (
        cd "$TEST_DIR/repos/2025/02/21/extra/os/x86_64"
        mkdir -p test2
        cat > test2/.BUILDINFO << EOF
format = 1
pkgname = test
pkgver = 2.0
pkgrel = 1
pkgarch = x86_64
packager = Arch Linux <arch@archlinux.org>
builddate = $(date +%s)
builddir = /build
startdir = /build
buildenv = !distcc
buildenv = color
buildenv = !ccache
buildenv = check
buildenv = !sign
installed = test-2.0-1-x86_64
EOF
        tar czf test-2.0-1-x86_64.pkg.tar.zst test2/.BUILDINFO
        rm -rf test2
    )

    # Create symlinks in packages tree
    ln -sr "$TEST_DIR/repos/2025/02/21/core/os/x86_64/test-1.0-1-x86_64.pkg.tar.zst" "$TEST_DIR/packages/t/test/"
    ln -sr "$TEST_DIR/repos/2025/02/21/extra/os/x86_64/test-2.0-1-x86_64.pkg.tar.zst" "$TEST_DIR/packages/t/test/"
    ln -sr "$TEST_DIR/repos/2025/02/21/core/os/x86_64/test-1.0-1-x86_64.pkg.tar.zst" "$TEST_DIR/packages/.all/"
    ln -sr "$TEST_DIR/repos/2025/02/21/extra/os/x86_64/test-2.0-1-x86_64.pkg.tar.zst" "$TEST_DIR/packages/.all/"

    # Run archive-cleaner with proper arguments and debug output
    ./archive-cleaner --repo "$TEST_DIR/repos/last" --archive "$TEST_DIR" --keep-years 1 || {
        log "ERROR: archive-cleaner failed"
        exit 1
    }

    # Verify cleaner results
    test -f "$TEST_DIR/repos/2025/02/21/core/os/x86_64/test-1.0-1-x86_64.pkg.tar.zst" || {
        log "ERROR: Expected package file missing after cleaning"
        exit 1
    }
    
    log "==> Test 4: Test incremental sync"
    echo "new package" > "$MOCK_UPSTREAM/core/os/x86_64/test-2.0-1-x86_64.pkg.tar.zst"
    run_archive || {
        log "ERROR: Incremental sync failed"
        exit 1
    }
    
    log "==> Test 5: Test hardlinking"
    find "$TEST_DIR" -type f -links +1 || {
        log "ERROR: No hardlinks found"
        exit 1
    }

    log "==> Final archive structure:"
    find "$TEST_DIR" -type f -exec ls -l {} \;
}

# Run tests
run_tests

log "==> All tests passed!"
