#!/usr/bin/env bash
# ntopng.sh - install/remove ntopng on Debian 13 (trixie) from the ntop apt repo
# Usage: sudo ./ntopng.sh add|remove|status   (IFACE=eth1 ./ntopng.sh add to override iface)

set -euo pipefail

IFACE="${IFACE:-eth0}"
[[ $IFACE =~ ^[A-Za-z0-9._@:-]+$ ]] || { echo "invalid IFACE" >&2; exit 1; }
REPO_LIST=/etc/apt/sources.list.d/ntop.list
CONF=/etc/ntopng/ntopng.conf

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

usage() {
    echo "Usage: $0 {add|remove|status}"
    exit 2
}

repo_ok() {
    # Kept for reference: the flat-repo check is unused since ntopng is
    # installed from the package index via direct deb download.
    return 0
}

add() {
    echo "[*] Installing prerequisites"
    export DEBIAN_FRONTEND=noninteractive
    apt-get update -y || true
    apt-get install -y ca-certificates curl

    # The ntop trixie tree is not consumable as an apt repo: the Packages
    # indexes carry x64/./ and all/./ Filename prefixes while the Release
    # files live only inside the subdirectories. The debs are therefore
    # downloaded directly and installed with dpkg.
    echo "[*] Resolving ntop packages from the trixie package index"
    local work debs pkg comp hit sha stanza url f
    work=$(mktemp -d /tmp/ntop-debs.XXXXXX)
    debs=""
    for pkg in ntopng ntopng-data ndpi pfring ntop-license; do
        hit=""; sha=""
        for comp in x64 all; do
            # Fetch the index once per component and pull both the Filename
            # and the SHA256 out of the same stanza; the window is wide
            # enough to reach the SHA256: field below Filename. The `|| true`
            # guards keep a SIGPIPE (grep -m1 closing the pipe early) from
            # failing the pipeline under pipefail and zeroing the hit.
            stanza=$(curl -fsSL "https://packages.ntop.org/apt-stable/trixie/${comp}/Packages.gz" | zcat \
                | grep -A40 "^Package: ${pkg}$") || true
            hit=$(printf '%s\n' "${stanza}" | grep -m1 "^Filename:" | awk '{print $2}') || true
            sha=$(printf '%s\n' "${stanza}" | grep -m1 "^SHA256:" | awk '{print $2}') || true
            if [[ -n ${hit} && -n ${sha} ]]; then
                break
            fi
            hit=""; sha=""
        done
        if [[ -z ${hit} || -z ${sha} ]]; then
            echo "[!] package ${pkg} (with SHA256) not found in the ntop trixie index" >&2
            rm -rf "${work}"
            exit 1
        fi
        url="https://packages.ntop.org/apt-stable/trixie/${hit}"
        f="${work}/$(basename "${hit}")"
        echo "    ${pkg} <- ${url}"
        curl -fsSL -o "${f}" "${url}"
        echo "[*] Verifying SHA256 of ${f}"
        if ! echo "${sha}  ${f}" | sha256sum -c -; then
            echo "[!] SHA256 mismatch for ${pkg} (${url})" >&2
            rm -rf "${work}"
            exit 1
        fi
        debs="${debs} ${f}"
    done

    echo "[*] Installing ntopng debs with dpkg"
    dpkg -i ${debs} || apt-get -f install -y
    rm -rf "${work}"

    echo "[*] Configuring ${CONF} (interface=${IFACE}, web port 3000)"
    touch "${CONF}"
    # Drop any pre-existing -i= / -w= lines we manage plus the package-default
    # -W=3001 HTTPS line (3001 stays reserved for the main instance's default;
    # the suricata reader instance lives on 3002), then re-add
    sed -i -e '/^-i=/d' -e '/^-w=3000$/d' -e '/^-W=3001$/d' "${CONF}"
    grep -q '^-i=' "${CONF}" || echo "-i=${IFACE}" >> "${CONF}"
    grep -q '^-w=3000' "${CONF}" || echo "-w=3000" >> "${CONF}"

    echo "[*] Enabling ntopng.service"
    systemctl daemon-reload || true
    systemctl enable --now ntopng.service

    echo "[+] ntopng installed (web UI on port 3000)"
}

remove() {
    echo "[*] Stopping and disabling ntopng.service"
    systemctl stop ntopng.service 2>/dev/null || true
    systemctl disable ntopng.service 2>/dev/null || true

    echo "[*] Removing ntopng-suricata.service unit if present"
    systemctl disable --now ntopng-suricata.service 2>/dev/null || true
    rm -f /etc/systemd/system/ntopng-suricata.service
    systemctl daemon-reload

    echo "[*] Purging ntopng packages"
    export DEBIAN_FRONTEND=noninteractive
    apt-get purge -y ntopng ntopng-data 2>/dev/null || true

    echo "[*] Removing repo file, leftover keyring and state"
    rm -f "${REPO_LIST}" /etc/apt/keyrings/ntop.gpg
    rm -rf /var/lib/ntopng
    rm -rf /var/lib/apt/lists/packages.ntop.org* 2>/dev/null || true

    echo "[*] apt-get autoremove --purge"
    apt-get autoremove --purge -y

    echo "[+] ntopng removed"
}

status() {
    echo "[*] ntopng service:"
    systemctl is-active ntopng.service 2>/dev/null && systemctl is-enabled ntopng.service 2>/dev/null || echo "inactive/not installed"
    echo "[*] Port 3000:"
    if ss -ltn 2>/dev/null | grep -q ':3000 '; then
        echo "listening"
    else
        echo "not listening"
    fi
}

case "${1:-}" in
    add)    add ;;
    remove) remove ;;
    status) status ;;
    *)      usage ;;
esac
