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

UPLOAD_ROOT="/opt/rustypaste/upload"
QUARANTINE="/var/lib/rustypaste-quarantine"
LOG_FILE="/var/log/rustypaste-scan/scan.log"
LOCK_ROOT="/run/rustypaste-clamav"
file="${1:-}"

log() {
  local line
  line="$(date --iso-8601=seconds) $*"
  printf '%s\n' "$line" >> "$LOG_FILE"
  logger -t rustypaste-clamav -- "$*"
}

[[ -n "$file" ]] || { log "SCAN_ERROR reason=no_file"; exit 2; }
resolved="$(realpath -e -- "$file" 2>/dev/null || true)"
[[ -n "$resolved" && -f "$resolved" ]] || exit 0
upload_root="$(realpath -e -- "$UPLOAD_ROOT")"

case "$resolved" in
  "$upload_root"/*) ;;
  *) log "SCAN_REFUSED path=$resolved"; exit 2 ;;
esac

mkdir -p "$LOCK_ROOT"
lock_name="$(printf '%s' "$resolved" | sha256sum | awk '{print $1}')"
exec 9>"$LOCK_ROOT/$lock_name.lock"
flock -n 9 || exit 0

previous=-1
stable=0
for _ in {1..30}; do
  current="$(stat -c '%s' -- "$resolved" 2>/dev/null || echo -1)"
  [[ "$current" -ge 0 ]] || exit 0
  if [[ "$current" -eq "$previous" ]]; then
    stable=$((stable + 1))
    [[ "$stable" -ge 2 ]] && break
  else
    stable=0
  fi
  previous="$current"
  sleep 1
done

set +e
output="$(clamdscan --fdpass --no-summary -- "$resolved" 2>&1)"
rc=$?
set -e

case "$rc" in
  0) log "CLEAN file=$resolved size=$(stat -c '%s' -- "$resolved")" ;;
  1)
    timestamp="$(date +%Y%m%dT%H%M%S)"
    base="$(basename -- "$resolved")"
    destination="$QUARANTINE/${timestamp}-${lock_name:0:12}-${base}"
    mv -- "$resolved" "$destination"
    chmod 0600 "$destination"
    log "INFECTED original=$resolved quarantine=$destination scanner=$(printf '%q' "$output")"
    ;;
  *)
    log "SCAN_ERROR file=$resolved exit=$rc scanner=$(printf '%q' "$output")"
    exit "$rc"
    ;;
esac
