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

file_size() {
    local file="$1"
    stat -c '%s' -- "$file" 2>/dev/null || printf '0\n'
}

available_bytes() {
    df --output=avail -B1 -- "$LOG_DIR" |
        awk 'NR == 2 { print $1; found = 1 } END { if (!found) exit 1 }'
}

prune_bee_diagnostic_logs() {
    local LOG_DIR="${1:-/var/log/bee_logs}"
    local MAX_DIAGNOSTIC_BYTES="${2:-$((512 * 1024 * 1024))}"
    local MIN_FREE_BYTES="${3:-$((10 * 1024 * 1024 * 1024))}"

    [[ "$MAX_DIAGNOSTIC_BYTES" =~ ^[0-9]+$ ]] || return 2
    [[ "$MIN_FREE_BYTES" =~ ^[0-9]+$ ]] || return 2
    [[ -d "$LOG_DIR" ]] || return 0

    # Keep the records ordered oldest-first so pressure removes the least
    # recent diagnostic evidence before newer evidence.  The NUL separator
    # keeps records safe even if an unexpected whitespace character appears
    # in a file name.  The first space is the timestamp delimiter; paths all
    # begin with the fixed absolute log directory.
    mapfile -d '' -t candidates < <(
        find -P "$LOG_DIR" -maxdepth 1 -type f \
            -name 'diagnostic-*.jsonl*' \
            -printf '%T@ %p\0' |
        sort -z -n
    )

    # A clean worker has no diagnostic files; there is nothing to prune and
    # no reason to inspect or remove any other file in the log directory.
    ((${#candidates[@]} > 0)) || return 0

    total_bytes=0
    for record in "${candidates[@]}"; do
        candidate="${record#* }"
        case "$candidate" in
            "$LOG_DIR"/diagnostic-*.jsonl*) ;;
            *) continue ;;
        esac
        size="$(file_size "$candidate")"
        [[ "$size" =~ ^[0-9]+$ ]] || continue
        total_bytes=$((total_bytes + size))
    done

    free_bytes="$(available_bytes 2>/dev/null || true)"
    [[ "$free_bytes" =~ ^[0-9]+$ ]] || return 0

    index=0
    while ((index < ${#candidates[@]} && (total_bytes > MAX_DIAGNOSTIC_BYTES || free_bytes < MIN_FREE_BYTES))); do
        candidate="${candidates[index]#* }"
        case "$candidate" in
            "$LOG_DIR"/diagnostic-*.jsonl*) ;;
            *) index=$((index + 1)); continue ;;
        esac

        # find -type f excludes links; retain the check immediately before rm so
        # a disappeared or replaced candidate is never treated as a target.
        if [[ ! -f "$candidate" || -L "$candidate" ]]; then
            index=$((index + 1))
            continue
        fi
        size="$(file_size "$candidate")"
        if [[ ! "$size" =~ ^[0-9]+$ ]]; then
            index=$((index + 1))
            continue
        fi
        if ! rm -- "$candidate"; then
            index=$((index + 1))
            continue
        fi

        total_bytes=$((total_bytes - size))
        free_bytes="$(available_bytes 2>/dev/null || true)"
        [[ "$free_bytes" =~ ^[0-9]+$ ]] || break
        index=$((index + 1))
    done
}

# Production execution has fixed paths and budgets.  Tests source this file
# and call the function with temporary inputs; command-line arguments are not
# interpreted by this entry point.
if [[ "${BASH_SOURCE[0]:-}" == "$0" ]]; then
    prune_bee_diagnostic_logs \
        "/var/log/bee_logs" \
        "$((512 * 1024 * 1024))" \
        "$((10 * 1024 * 1024 * 1024))"
fi
