#!/usr/bin/env bash
# crowdsec-suricata.sh - let CrowdSec parse Suricata eve.json via acquis.yaml
# Usage: sudo ./crowdsec-suricata.sh enable|disable|status

set -euo pipefail

ACQUIS=/etc/crowdsec/acquis.yaml
BEGIN_MARK="# BEGIN crowdsec-suricata"
END_MARK="# END crowdsec-suricata"
EVE_LOG=/var/log/suricata/eve.json

# Re-exec with sudo if not root
if [[ ${EUID} -ne 0 ]]; then
    exec sudo -E "$0" "$@"
fi

usage() {
    echo "Usage: $0 {enable|disable|status}"
    exit 2
}

# Remove a previously appended block. Debian's acquis.yaml ends without a
# trailing '---'; the separator this script adds before the marked block is
# only removed when it ends up as the last line of the file, so any foreign
# blocks around it are left intact.
strip_block() {
    [[ -f ${ACQUIS} ]] || return 0
    sed -i "/^${BEGIN_MARK}$/,/^${END_MARK}$/d" "${ACQUIS}"
    sed -i -e '$ { /^---$/d; }' "${ACQUIS}"
}

# Reload crowdsec and make sure it actually came back up. If the reload
# leaves the unit dead, try a restart; if it still will not stay up, fail
# loudly.
reload_crowdsec() {
    systemctl reload crowdsec.service 2>/dev/null || true
    if ! systemctl is-active --quiet crowdsec.service; then
        echo "[i] crowdsec not active after reload; restarting"
        systemctl restart crowdsec.service
    fi
    if ! systemctl is-active --quiet crowdsec.service; then
        echo "[!] crowdsec failed to (re)start; check 'journalctl -u crowdsec.service'" >&2
        exit 1
    fi
}

enable() {
    if [[ ! -x /usr/bin/cscli ]]; then
        echo "[!] cscli not found; run ../crowdsec.sh add first" >&2
        exit 1
    fi

    echo "[*] Installing collection crowdsecurity/suricata"
    cscli hub update
    cscli collections install crowdsecurity/suricata

    echo "[*] Appending marked block to ${ACQUIS}"
    touch "${ACQUIS}"
    local backup tlog
    backup=$(mktemp)
    cp "${ACQUIS}" "${backup}"
    # Idempotent: drop any previously appended block first, then re-append.
    strip_block
    # The LEADING '---' starts a fresh YAML document. Debian's acquis.yaml
    # ends WITHOUT a trailing '---', so appending the block bare would merge
    # both halves into one broken document and kill crowdsec.
    cat >> "${ACQUIS}" <<EOF
---
${BEGIN_MARK}
filenames:
  - ${EVE_LOG}
labels:
  type: suricata
${END_MARK}
EOF

    echo "[*] Validating with 'crowdsec -t'"
    tlog=$(mktemp)
    if ! crowdsec -t >"${tlog}" 2>&1; then
        echo "[!] crowdsec -t failed; restoring ${ACQUIS} from backup" >&2
        tail -n 20 "${tlog}" >&2 || true
        cp "${backup}" "${ACQUIS}"
        rm -f "${backup}" "${tlog}"
        exit 1
    fi
    rm -f "${backup}" "${tlog}"

    echo "[*] Reloading crowdsec"
    reload_crowdsec
    echo "[+] CrowdSec now parses ${EVE_LOG}"
}

disable() {
    if [[ ! -f ${ACQUIS} ]]; then
        echo "[*] ${ACQUIS} not present; nothing to do"
        exit 0
    fi

    echo "[*] Removing marked block from ${ACQUIS}"
    strip_block

    echo "[*] Reloading crowdsec"
    reload_crowdsec
    echo "[+] CrowdSec no longer parses ${EVE_LOG}"
}

status() {
    echo "[*] acquisition block:"
    if grep -qF "${BEGIN_MARK}" "${ACQUIS}" 2>/dev/null; then
        echo "present in ${ACQUIS}"
        sed -n "/^${BEGIN_MARK}$/,/^${END_MARK}$/p" "${ACQUIS}"
    else
        echo "absent"
    fi
    echo "[*] suricata collection:"
    if command -v cscli >/dev/null 2>&1; then
        cscli collections list 2>/dev/null | grep -i suricata || echo "not installed"
    else
        echo "cscli not installed"
    fi
}

case "${1:-}" in
    enable)  enable ;;
    disable) disable ;;
    status)  status ;;
    *)       usage ;;
esac
