#!/usr/bin/env bash
#
# onx-service-logs — journalctl log tail for a systemd unit
#
# Stdin:  JSON {"unit":"httpd", "lines":200, "since":"1 hour ago"}
# Stdout: JSON {"unit":..., "lines":[{"time":...,"level":...,"message":...},...]}
# Exit:   0=ok  1=invalid_input  3=execution_fail

set -euo pipefail

die_input() { printf '{"error":"%s","code":1}\n' "$*" >&2; exit 1; }
die_exec()  { printf '{"error":"%s","code":3}\n' "$*" >&2; exit 3; }
json_str()  { printf '%s' "$1" | sed 's/\\/\\\\/g; s/"/\\"/g'; }

INPUT=$(cat)
UNIT=$(echo "$INPUT"  | grep -oP '"unit"\s*:\s*"\K[^"]+'        2>/dev/null || true)
LINES=$(echo "$INPUT" | grep -oP '"lines"\s*:\s*\K\d+'           2>/dev/null || echo "200")
SINCE=$(echo "$INPUT" | grep -oP '"since"\s*:\s*"\K[^"]+'        2>/dev/null || echo "1 hour ago")

[[ -z "$UNIT" ]]             && die_input "unit alani gerekli"
[[ "$UNIT" =~ ^[a-zA-Z0-9._@:-]{1,64}$ ]] || die_input "Gecersiz unit adi"
[[ "$UNIT" == *"/"* ]]        && die_input "Gecersiz unit adi"

# Clamp lines to reasonable range
[[ "$LINES" -gt 1000 ]] && LINES=1000
[[ "$LINES" -lt 1 ]]    && LINES=50

# Validate since — only allow safe characters
[[ "$SINCE" =~ ^[a-zA-Z0-9\ \-:]+$ ]] || SINCE="1 hour ago"

# Get journal output as JSON per-line
RAW=$(journalctl -u "${UNIT}" \
  --since "${SINCE}" \
  -n "${LINES}" \
  --output=json-pretty \
  --no-pager \
  2>/dev/null || true)

if [[ -z "$RAW" ]]; then
  # journalctl returned nothing
  printf '{"unit":"%s","lines":[]}\n' "$(json_str "$UNIT")"
  exit 0
fi

# Transform journald JSON to our simplified format
# We expect one JSON object per line from --output=json (not json-pretty for easier parsing)
RAW=$(journalctl -u "${UNIT}" \
  --since "${SINCE}" \
  -n "${LINES}" \
  --output=json \
  --no-pager \
  2>/dev/null || true)

ENTRIES="["
FIRST=1
while IFS= read -r line; do
  [[ -z "$line" ]] && continue
  _TIME=$(echo "$line" | grep -oP '"__REALTIME_TIMESTAMP"\s*:\s*"\K[^"]+' || true)
  _MSG=$(echo  "$line" | grep -oP '"MESSAGE"\s*:\s*"\K[^"]+' || true)
  _PRIO=$(echo "$line" | grep -oP '"PRIORITY"\s*:\s*"\K[^"]+' || true)

  # Convert epoch microseconds to readable time
  _TS="—"
  if [[ "$_TIME" =~ ^[0-9]+$ ]]; then
    _TS=$(date -d "@$(( _TIME / 1000000 ))" '+%Y-%m-%d %H:%M:%S' 2>/dev/null || echo "—")
  fi

  # Map syslog priority to level label
  case "$_PRIO" in
    0|1|2|3) _LVL="error"   ;;
    4)       _LVL="warning" ;;
    5|6)     _LVL="info"    ;;
    7)       _LVL="debug"   ;;
    *)       _LVL="info"    ;;
  esac

  _MSG_SAFE=$(json_str "${_MSG:-}")
  _TS_SAFE=$(json_str "$_TS")

  [[ "$FIRST" -eq 0 ]] && ENTRIES="${ENTRIES},"
  ENTRIES="${ENTRIES}{\"time\":\"${_TS_SAFE}\",\"level\":\"${_LVL}\",\"message\":\"${_MSG_SAFE}\"}"
  FIRST=0
done <<< "$RAW"

ENTRIES="${ENTRIES}]"

printf '{"unit":"%s","lines":%s}\n' "$(json_str "$UNIT")" "$ENTRIES"
exit 0
