#!/bin/bash

set -euo pipefail

PROGRAM="xivo-save-asterisk-crash-info"
CRASH_DIR="/var/spool/asterisk"
AST_LOG_DIR="/var/log/asterisk"
SYSLOG_DIR="/var/log"
PROCESSED_LIST="${CRASH_DIR}/.processed"

concat_file() {
  is_gzipped="${1}"; shift
  file="${1}"; shift
  dest="${1}"; shift

  if [ "$is_gzipped" == "true" ]; then
    zcat "$file" >> "$dest"
  elif [ "$(file -b --mime-type "$file" |cut -d '/' -f1)" == "text" ]; then
    cat "$file" >> "$dest"
  else
    # Return an error: we can't cat the file
    return 1
  fi
}

find_and_save_log() {
  local file_name="${1}"; shift
  local log_dir="${1}"; shift
  local file_pattern="${1}"; shift
  local log_pattern="${1}"; shift
  local crash_hour="${1}"; shift
  local dest_dir="${1}"; shift

  local tmp found match_file nb_files file_index is_gzipped

  tmp=$(mktemp)
  found=false
  match_file=$(find "$log_dir" -name "${file_pattern}*" -daystart -mtime -2 -exec zgrep -l "${log_pattern}" {} \;|sort -Vr)
  nb_files=$(echo "$match_file" | wc -w)
  file_index=0
  
  for f in $match_file; do
    file_index=$((file_index + 1))  
    is_gzipped=false

    gzip -qt "$f" &> /dev/null && is_gzipped=true
  
    if [ "$crash_hour" -ge 0 ] && [ "$crash_hour" -lt 1 ]; then
      logger -t "$PROGRAM" "✅ Ajout ${file_name} (00h mode) : $f"
      if ! concat_file "$is_gzipped" "$f" "$tmp"; then
        cp "$f" "$dest_dir"
      fi
      found=true
    else
      if [ "$nb_files" -eq 1 ]; then
        logger -t "$PROGRAM" "✅ Ajout ${file_name} : $f"
        if ! concat_file "$is_gzipped" "$f" "$tmp"; then
          cp "$f" "$dest_dir"
        fi
        found=true
      elif [ "$file_index" -eq "$nb_files" ]; then
        logger -t "$PROGRAM" "✅ Ajout ${file_name} (dernier fichier) : $f"
        if ! concat_file "$is_gzipped" "$f" "$tmp"; then
          cp "$f" "$dest_dir"
        fi
        found=true
      fi
    fi
  done

  if $found; then
    gzip -c "$tmp" > "$dest_dir/${file_name}.log.gz"
    logger -t "$PROGRAM" "✅ ${file_name}.log.gz généré : $dest_dir/${file_name}.log.gz"
  else
    logger -t "$PROGRAM" "❌ Aucun log ${file_name} trouvé pour $log_pattern"
  fi

  rm -f "$tmp"
}

touch "$PROCESSED_LIST"

find "$CRASH_DIR" -maxdepth 1 -type f -name "core.*.*" | while read -r corefile; do
  core_name=$(basename "$corefile")

  if grep -qF "$core_name" "$PROCESSED_LIST"; then
    continue
  fi

  timestamp=$(echo "$corefile" | awk -F '.' '{print $(NF)}')
  crash_hour=$(date -d "@$timestamp" "+%H")
  time_pattern=$(date -d "@$timestamp" "+%Y-%m-%d")

  # === CORE ===
  dest_dir="$CRASH_DIR/$core_name-info"
  mkdir -p "$dest_dir"
  logger -t "$PROGRAM" "💥 Crash détecté à $(date -d "@$timestamp")"
  gzip -c "$corefile" > "$dest_dir/$core_name.gz"
  logger -t "$PROGRAM" "✅ Core compressé : $core_name.gz"

  # === ASTERISK LOGS ===
  find_and_save_log asterisk "$AST_LOG_DIR" "full" "$time_pattern" "$crash_hour" "$dest_dir"

  # === SYSLOGS ===
  find_and_save_log syslog "$SYSLOG_DIR" "syslog" "$time_pattern" "$crash_hour" "$dest_dir"

  # Delete files
  rm -f "$corefile"
  
  echo "$core_name" >> "$PROCESSED_LIST"
done
