#!/bin/sh
# SPDX-License-Identifier: GPL-3.0-or-later

set -euo pipefail

TEST_COUNT=0
TEST_FAILED=0
TESTDIR=""
SEEDFILES=""

setup() {
    SEEDFILES="${1:?Usage: setup <path-to-seedfiles>}"
    TESTDIR="$(mktemp -d /tmp/seedfiles-integ-XXXXXX)"
    TEST_COUNT=0
    TEST_FAILED=0
    trap teardown EXIT
}

teardown() {
    if [ -n "$TESTDIR" ] && [ -d "$TESTDIR" ]; then
        rm -rf "$TESTDIR"
    fi
}

write_conf() {
    printf '%s\n' "$@" > "$TESTDIR/conf"
}

plan() {
    echo "1..$1"
}

ok() {
    TEST_COUNT=$((TEST_COUNT + 1))
    echo "ok $TEST_COUNT - $1"
}

not_ok() {
    TEST_COUNT=$((TEST_COUNT + 1))
    TEST_FAILED=$((TEST_FAILED + 1))
    echo "not ok $TEST_COUNT - $1${2:+ # $2}"
}

run_test() {
    local desc="$1"
    shift
    local rc=0
    "$@" >/dev/null 2>&1 || rc=$?
    if [ $rc -eq 0 ]; then
        ok "$desc"
    else
        not_ok "$desc" "exit code $rc"
    fi
}

run_test_fail() {
    local desc="$1"
    shift
    local rc=0
    "$@" >/dev/null 2>&1 || rc=$?
    if [ $rc -ne 0 ]; then
        ok "$desc"
    else
        not_ok "$desc" "expected failure but succeeded"
    fi
}

assert_exists() {
    if [ -e "$1" ]; then
        ok "$1 exists"
    else
        not_ok "$1 exists" "path missing"
    fi
}

assert_not_exists() {
    if [ ! -e "$1" ]; then
        ok "$1 does not exist"
    else
        not_ok "$1 does not exist" "path exists"
    fi
}

assert_file_equals() {
    if [ ! -f "$1" ]; then
        not_ok "$1 content matches" "file missing"
        return
    fi
    local content
    content="$(cat "$1")"
    if [ "$content" = "$2" ]; then
        ok "$1 content matches"
    else
        not_ok "$1 content matches" "got '$content', expected '$2'"
    fi
}

assert_symlink_to() {
    if [ ! -L "$1" ]; then
        not_ok "$1 symlink target" "not a symlink"
        return
    fi
    local target
    target="$(readlink "$1")"
    if [ "$target" = "$2" ]; then
        ok "$1 symlink target"
    else
        not_ok "$1 symlink target" "got '$target', expected '$2'"
    fi
}

assert_mode() {
    if [ ! -e "$1" ]; then
        not_ok "$1 mode is $2" "path missing"
        return
    fi
    local mode
    mode="$(stat -c '%a' "$1")"
    if [ "$mode" = "$2" ]; then
        ok "$1 mode is $2"
    else
        not_ok "$1 mode is $2" "got $mode"
    fi
}

assert_dir_empty() {
    if [ ! -d "$1" ]; then
        not_ok "$1 is empty directory" "not a directory"
        return
    fi
    if [ -z "$(ls -A "$1")" ]; then
        ok "$1 is empty directory"
    else
        not_ok "$1 is empty directory" "directory not empty"
    fi
}

done_testing() {
    if [ "$TEST_FAILED" -gt 0 ]; then
        exit 1
    fi
}
