#!/usr/bin/env bash
set -euo pipefail

ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
INSTALLER="$ROOT/packaging/install-kanboard.sh"

fail() {
    printf 'FAIL: %s\n' "$*" >&2
    exit 1
}

run_case() {
    local scenario="$1"
    local expected_status="$2"
    local sandbox deploy home fakebin previous output status active
    sandbox="$(mktemp -d)"
    deploy="$sandbox/deploy"
    home="$sandbox/home"
    fakebin="$sandbox/bin"
    mkdir -p "$deploy/packaging/kanboard/plugins" "$home/.config/overdeck" "$home/.local/share/overdeck/kanboard-plugin-releases/previous" "$fakebin"
    cp "$ROOT/packaging/kanboard/overdeck-kanboard.container" "$deploy/packaging/kanboard/"
    cp -a "$ROOT/packaging/kanboard/plugins/OverdeckIncidents" "$deploy/packaging/kanboard/plugins/"
    printf 'KANBOARD_API_TOKEN=test-token\n' >"$home/.config/overdeck/kanboard-app.env"
    previous="$home/.local/share/overdeck/kanboard-plugin-releases/previous"
    if [[ "$scenario" != first-install-failure ]]; then
        printf 'previous\n' >"$previous/marker"
        ln -s "$previous" "$home/.local/share/overdeck/kanboard-plugin-active"
    fi

    cat >"$fakebin/systemctl" <<'EOF'
#!/usr/bin/env bash
printf '%s\n' "$*" >>"$TEST_LOG/systemctl"
if [[ "$*" == *" restart "* || "$*" == *" restart overdeck-kanboard.service"* ]]; then
    active="$HOME/.local/share/overdeck/kanboard-plugin-active"
    [[ -e "$active" ]] || { printf 'missing Quadlet bind source: %s\n' "$active" >&2; exit 1; }
fi
EOF
    cat >"$fakebin/sleep" <<'EOF'
#!/usr/bin/env bash
exit 0
EOF
    cat >"$fakebin/curl" <<'EOF'
#!/usr/bin/env bash
if [[ "$*" != *"/jsonrpc.php"* ]]; then
    exit 0
fi
active="$(readlink "$HOME/.local/share/overdeck/kanboard-plugin-active" 2>/dev/null || true)"
if [[ "$active" == */empty ]]; then
    [[ "$TEST_SCENARIO" == first-install-failure ]] || exit 22
    printf '%s\n' '{"jsonrpc":"2.0","id":"deploy-canary","error":{"code":-32601,"message":"Method not found"}}'
    exit 0
fi
if [[ "$active" == */previous ]]; then
    [[ "$TEST_SCENARIO" == rollback-canary-failure ]] && exit 22
    printf '%s\n' '{"jsonrpc":"2.0","id":"deploy-canary","result":{"tasks":[],"high_water":0,"exhausted":true,"complete":true,"order":"id_desc"}}'
    exit 0
fi
[[ "$TEST_SCENARIO" == success ]] || exit 22
printf '%s\n' '{"jsonrpc":"2.0","id":"deploy-canary","result":{"tasks":[],"high_water":0,"exhausted":true,"complete":true,"order":"id_desc"}}'
EOF
    chmod +x "$fakebin/systemctl" "$fakebin/sleep" "$fakebin/curl"

    set +e
    output="$(HOME="$home" OVERDECK_DEPLOY_DIR="$deploy" TEST_LOG="$sandbox" TEST_SCENARIO="$scenario" PATH="$fakebin:$PATH" bash "$INSTALLER" 2>&1)"
    status=$?
    set -e
    [[ "$status" -eq "$expected_status" ]] || fail "$scenario status $status, expected $expected_status: $output"
    active="$(readlink "$home/.local/share/overdeck/kanboard-plugin-active" 2>/dev/null || true)"

    case "$scenario" in
        success)
            [[ -n "$active" && "$active" != "$previous" ]] || fail "success did not activate candidate"
            [[ -f "$active/Plugin.php" && ! -w "$active/Plugin.php" ]] || fail "success release is incomplete or writable"
            [[ "$(wc -l <"$sandbox/systemctl")" -eq 2 ]] || fail "success did not restart exactly once"
            ;;
        candidate-failure)
            [[ "$active" == "$previous" ]] || fail "candidate failure did not restore previous target"
            [[ "$(wc -l <"$sandbox/systemctl")" -eq 4 ]] || fail "candidate failure did not restart previous target"
            [[ "$output" == *"candidate canary failed; previous release restored"* ]] || fail "candidate failure lacked rollback receipt"
            ;;
        rollback-canary-failure)
            [[ "$active" == "$previous" ]] || fail "rollback failure did not restore previous target"
            [[ "$(wc -l <"$sandbox/systemctl")" -eq 4 ]] || fail "rollback failure did not restart previous target"
            [[ "$output" == *"rollback canary failed"* ]] || fail "rollback failure was not reported"
            ;;
        first-install-failure)
            [[ "$active" == "$home/.local/share/overdeck/kanboard-plugin-releases/empty" ]] || fail "first install failure did not activate empty plugin directory"
            [[ -d "$active" ]] || fail "first install failure left missing bind source"
            [[ "$(wc -l <"$sandbox/systemctl")" -eq 4 ]] || fail "first install failure did not restart plugin-absent service"
            [[ "$output" == *"candidate canary failed; empty plugin directory activated and absence verified"* ]] || fail "first install failure lacked absence receipt"
            ;;
    esac
    chmod -R u+w "$sandbox"
    rm -rf "$sandbox"
}

run_case success 0
run_case candidate-failure 1
run_case rollback-canary-failure 1
run_case first-install-failure 1
printf 'install-kanboard tests passed\n'
