#!/bin/bash
# ==============================================================================================
# ============================= Docker Syslog Filter ===========================================
# ==============================================================================================
#
# PURPOSE
# ─────────────────────────────────────────────────────────────────────────────
# Suppresses Docker veth/docker0 network interface messages from syslog. Run
# once at array start via ARRAY_START_SCRIPTS before any containers start.
# Idempotent — completely silent when the filter is already in place.
#
# Every container start/stop generates kernel messages like:
#   "veth2a3b4c5: renamed from eth0"
#   "docker0: port 1(veth...) entered forwarding state"
# 50+ containers at array start = 200–400 lines of noise in the first minute,
# completely masking real events.
#
# ==============================================================================================
# OPERATIONAL MODEL
# ==============================================================================================
#
#   1. Build the expected rsyslog filter content
#   2. Compare against the file already on disk
#        identical → exit silently, no write, no rsyslog restart
#        missing or different → write the filter, then restart rsyslog
#   3. Verify rsyslog came back up after the restart
#
# Runs before any container starts, so the first wave of veth messages at array
# start is already being filtered.
#
# ==============================================================================================
# DESIGN PRINCIPLES
# ==============================================================================================
#
# Idempotent Content Check
#   Checks whether the filter file already exists with exactly the expected content.
#   If already correct → silent exit, no rsyslog restart. Only writes and restarts
#   rsyslog when the filter is missing or content has changed. Running at every boot
#   without this would cause an unnecessary rsyslog restart on every array start.
#
# rsyslog Drop Rule
#   Creates FILTER_FILE (/etc/rsyslog.d/ignore-docker-veth.conf).
#   Uses RainerScript `stop` action — messages matching "veth" or "docker0" are
#   dropped before reaching any output target, including the log file.
#
# ==============================================================================================
# OPERATIONAL SAFEGUARDS
# ==============================================================================================
#
# Root Required
#   Writing to /etc/rsyslog.d/ requires root.
#
# Single Instance Lock
#   acquire_lock prevents concurrent runs at array start.
#
# rsyslog Process Verify
#   Confirms rsyslog is running after restart.
#
# Silent on Success
#   Runs every boot — no noise when filter is already correct.
#
# ==============================================================================================
# CONFIGURATION
# ==============================================================================================
#
# master.conf
#
#   FILTER_FILE
#       Path for the rsyslog drop filter config file.
#       (default: /etc/rsyslog.d/ignore-docker-veth.conf)
#
# ==============================================================================================
# RUNTIME MODES
# ==============================================================================================
#
# docker_syslog_filter.sh
#     Check filter file. Write and restart rsyslog only if changed. Silent if correct.
#
# docker_syslog_filter.sh --dry-run
#     Show what would be written without writing or restarting rsyslog.
#
# docker_syslog_filter.sh --status
#     Show current filter file content and rsyslog process state.
#
# docker_syslog_filter.sh --log
#     Verbose output showing the content comparison and any changes applied.
#
# ==============================================================================================

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"

source "$SCRIPT_DIR/../load_config.sh"

parse_args "$@"

# Expected filter content — used for idempotent check
EXPECTED_FILTER='if ($msg contains "veth" or $msg contains "docker0") then {
    stop
}'

# ==============================================================================================
# ━━━ Setup ━━━
# ==============================================================================================
if [[ "$EUID" -ne 0 ]]; then
    error "Must be run as root — writing to /etc/rsyslog.d/ requires root"
    exit 1
fi


acquire_lock

detect_hosts

[[ "$DRY_RUN" == true ]] && warn "DRY RUN — no changes will be made"

# ==============================================================================================
# ━━━ Status ━━━
# ==============================================================================================
if [[ "$SHOW_STATUS" == true ]]; then
    echo ""
    echo "━━━━━ $ICON_SUMMARY SYSLOG FILTER STATUS ━━━━━"
    echo "$ICON_HOST    Identity:    $MY_ID ($LOCAL_SERVER_NAME)"
    echo "$ICON_HEALTH  Filter file: $FILTER_FILE"
    echo ""

    if [[ -f "$FILTER_FILE" ]]; then
        echo "  Filter file: EXISTS"
        echo ""
        echo "  Current content:"
        while IFS= read -r line; do
            echo "    $line"
        done < "$FILTER_FILE"
        echo ""

        if [[ "$(cat "$FILTER_FILE" 2>/dev/null)" == "$EXPECTED_FILTER" ]]; then
            echo "  $ICON_SUCCESS Content: correct ✅"
        else
            echo "  $ICON_WARN   Content: differs from expected — would be rewritten"
        fi
    else
        echo "  Filter file: NOT FOUND — would be created"
    fi

    echo ""
    echo "━━━ rsyslog Status ━━━"
    if platform_is_service_running rsyslog; then
        echo "  rsyslogd: running ✅"
    else
        echo "  rsyslogd: NOT running"
    fi
    echo "━━━━━━━━━━━━━━━━━━━━━━━"
    exit 0
fi

# ==============================================================================================
# ━━━ Idempotent Check ━━━
# ==============================================================================================
if [[ -f "$FILTER_FILE" ]] && \
   [[ "$(cat "$FILTER_FILE" 2>/dev/null)" == "$EXPECTED_FILTER" ]]; then
    echo "Syslog filter already correct ✅"
    exit 0
fi

# ==============================================================================================
# ━━━ Apply Filter ━━━
# ==============================================================================================
START=$(date +%s)

log "Filter file missing or outdated — applying..."

# Ensure rsyslog.d directory exists
if [[ "$DRY_RUN" == false ]]; then
    mkdir -p "$(dirname "$FILTER_FILE")" || {
        error "Failed to create directory: $(dirname "$FILTER_FILE")"
        exit 1
    }
fi

# Write filter file
if [[ "$DRY_RUN" == true ]]; then
    warn "DRY RUN — would write filter to: $FILTER_FILE"
    warn "Content:"
    echo "$EXPECTED_FILTER" | while IFS= read -r line; do
        echo "  $line"
    done
else
    echo "$EXPECTED_FILTER" > "$FILTER_FILE" || {
        error "Failed to write filter file: $FILTER_FILE"
        notify "Syslog filter write failed on $(hostname) ($MY_ID)" \
            "Syslog Filter" "warning"
        exit 1
    }
    log "Filter file written: $FILTER_FILE"
fi

# Restart rsyslog to apply
if [[ "$DRY_RUN" == true ]]; then
    warn "DRY RUN — would restart rsyslog"
else
    echo "Restarting rsyslog..."
    if platform_restart_service rsyslog; then
        sleep 2
        # Verify rsyslog actually running after restart
        if platform_is_service_running rsyslog; then
            echo "rsyslog restarted and running ✅"
        else
            error "rsyslog not running after restart"
            notify "rsyslog failed to start after filter update on $(hostname) ($MY_ID)" \
                "Syslog Filter" "warning"
            exit 1
        fi
    else
        error "rsyslog restart command failed"
        notify "rsyslog restart failed on $(hostname) ($MY_ID) — filter may not be active" \
            "Syslog Filter" "warning"
        exit 1
    fi
fi

END=$(date +%s)

# ==============================================================================================
# ━━━ Summary ━━━
# ==============================================================================================
echo ""
echo "━━━━━ $ICON_SUMMARY SYSLOG FILTER SUMMARY ━━━━━"
echo "$ICON_HOST    Identity:    $MY_ID ($LOCAL_SERVER_NAME)"
echo "$ICON_HEALTH  Filter file: $FILTER_FILE"
echo "$ICON_HEALTH  Targets:     veth / docker0"
echo "$ICON_TIME    Duration:    $(format_duration $(( END - START )))"
echo ""
if [[ "$DRY_RUN" == true ]]; then
    warn "DRY RUN — no changes made"
else
    echo "$ICON_DONE Status: done — Docker veth noise suppressed ✅"
fi
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"

exit 0