#!/bin/bash -xe
#
# Test the clevis-pkcs11-afunix-socket-unlock daemon's control socket
# protocol: device/key registration and retrieval, comma-in-passphrase
# handling, and malformed message rejection.
#
# No PKCS#11 hardware required — the daemon is a pure socket relay.
#

on_exit() {
    exit_status=$?
    if [ -n "${DAEMON_PID}" ] && kill -0 "${DAEMON_PID}" 2>/dev/null; then
        kill "${DAEMON_PID}" 2>/dev/null
        wait "${DAEMON_PID}" 2>/dev/null || true
    fi
    [ -d "${TMP}" ] && rm -rf "${TMP}"
    exit "${exit_status}"
}

if ! command -v socat >/dev/null 2>&1; then
    echo "SKIP: socat not installed"
    exit 77
fi

if ! command -v clevis-pkcs11-afunix-socket-unlock >/dev/null 2>&1; then
    echo "SKIP: clevis-pkcs11-afunix-socket-unlock not in PATH"
    exit 77
fi

trap 'on_exit' EXIT

TMP="$(mktemp -d)"
SOCK="${TMP}/test.sock"
CONTROL_SOCK="${TMP}/test.control.sock"
LOG="${TMP}/daemon.log"

# Start daemon: 1 iteration, no start delay
clevis-pkcs11-afunix-socket-unlock \
    -f "${SOCK}" -c "${CONTROL_SOCK}" -l "${LOG}" -t 3 -s 0 &
DAEMON_PID=$!
sleep 1

# Verify daemon is running
kill -0 "${DAEMON_PID}"

# --- Test 1: normal device,passphrase ---
echo -n "test-device,test-passphrase" | \
    socat UNIX-CONNECT:"${CONTROL_SOCK}" -

# Connect as a client and retrieve the key.
# The daemon identifies the device from the peer socket path.
# We use an abstract socket name containing "test-device" so
# get_key matches our registered device.
# Note: the daemon extracts the last /-delimited component of
# the peer abstract socket name as the device name.
socat - UNIX-CONNECT:"${SOCK}" < /dev/null 2>/dev/null || true
# The daemon may not find "test-device" from our peer name since
# the abstract name is generated by the kernel, but we can verify
# the daemon did not crash and accepted the connection.
test -n "${DAEMON_PID}"
kill -0 "${DAEMON_PID}"

# --- Test 2: passphrase containing commas ---
# The old strtok code would split "pass,word,with,commas" into 4
# separate tokens, logging "Adding device:" for each orphaned entry.
# The new strchr code splits only on the first comma, producing
# exactly one "Adding device:" log line per control message.
echo -n "comma-device,pass,word,with,commas" | \
    socat UNIX-CONNECT:"${CONTROL_SOCK}" -

kill -0 "${DAEMON_PID}"
grep "Adding device:comma-device" "${LOG}"

# Verify no orphaned entries were created — the old buggy code
# would log multiple "Adding device:" lines for a single message
# containing commas in the passphrase.
DEVICE_COUNT=$(grep -c "Adding device:" "${LOG}")
test "${DEVICE_COUNT}" -le 2

# --- Test 3: malformed message (no comma) ---
echo -n "no-delimiter-here" | \
    socat UNIX-CONNECT:"${CONTROL_SOCK}" -

# Verify daemon handled it gracefully
kill -0 "${DAEMON_PID}"
grep "Invalid control message" "${LOG}"

echo "All daemon socket tests passed"
