# This script provides a logging function 'log' that can be sourced in other scripts.
# It logs messages to both the terminal and a specified logfile, supporting multiple log levels.
# The log function takes three parameters: log level, log message, and optionally the logfile. If no logfile is specified, it writes to retrodeck/logs/retrodeck.log.
# 
# Supported logging levels (controlled by the variable 'logging_level'):
# - none: No logs are produced.
# - info: Logs informational messages (i) and errors (e).
# - warn: Logs warnings (w), informational messages (i), and errors (e).
# - debug: Logs all message types (d, w, i, e).
#
# Type of log messages:
# - d: Debug message (logged only in debug level).
# - i: Informational message (logged in debug, info, and warn levels).
# - w: Warning message (logged in debug and warn levels).
# - e: Error message (logged in all levels except none).
#
# Example usage:
# log w "foo" -> Logs a warning with message "foo" to the default log file retrodeck/logs/retrodeck.log.
# log e "bar" -> Logs an error with message "bar" to the default log file retrodeck/logs/retrodeck.log.
# log i "baz" rekku.log -> Logs an informational message "baz" to the specified log file retrodeck/logs/rekku.log.
#
# The function auto-detects if the shell is sh and avoids colorizing the output in that case.

log() {
  # Exit immediately if logging_level is "none"
  if [[ $logging_level == "none" ]]; then
    return
  fi

  local level="$1"          # Current message level
  local message="$2"        # Message to log
  local logfile="${3:-$rd_logs_folder/retrodeck.log}"  # Default log file
  local timestamp="$(date +[%Y-%m-%d\ %H:%M:%S.%3N])"   # Timestamp
  local colorize_terminal=true

  # Determine the calling function, or use [FWORK]
  local caller="${FUNCNAME[1]:-FWORK}"
  caller="${caller^^}"  # Convert to uppercase

  # Check if the shell is sh to avoid colorization
  if [ "${SHELL##*/}" = "sh" ]; then
    colorize_terminal=false
  fi

  # Internal function to check if the message should be logged
  should_log() {
    case "$logging_level" in
      debug) return 0 ;;  # Log everything
      info) [[ "$level" == "i" || "$level" == "e" ]] && return 0 ;;
      warn) [[ "$level" != "d" ]] && return 0 ;;
      error) [[ "$level" == "e" ]] && return 0 ;;
    esac
    return 1
  }

  if should_log; then
    # Define colors based on the message level
    case "$level" in
      d)
        color="\e[32m[DEBUG]"
        prefix="[DEBUG]"
        ;;
      e)
        color="\e[31m[ERROR]"
        prefix="[ERROR]"
        ;;
      w)
        color="\e[33m[WARN]"
        prefix="[WARN]"
        ;;
      i)
        color="\e[34m[INFO]"
        prefix="[INFO]"
        ;;
      *)
        color="\e[37m[LOG]"
        prefix="[LOG]"
        ;;
    esac

    # Build the message to display
    if [ "$colorize_terminal" = true ]; then
      colored_message="$color [$caller] $message\e[0m"
    else
      colored_message="$timestamp $prefix [$caller] $message"
    fi
    log_message="$timestamp $prefix [$caller] $message"

    # If silent mode is not active, print the message to the terminal
    if [[ "$LOG_SILENT" != "true" ]]; then
      echo -e "$colored_message" >&2
    fi

    # Ensure the log file exists
    if [ ! -f "$logfile" ]; then
      if [[ ! -d "$(dirname "$logfile")" ]]; then
        mkdir -p "$(dirname "$logfile")"
      fi
      touch "$logfile"
    fi

    # Write the log to the file
    echo "$log_message" >> "$logfile"
  fi
}


# The rotate_logs function manages log file rotation to limit the number of logs retained.
# It compresses the current log file into a .tar.gz archive, increments the version of 
# older log files (e.g., retrodeck.1.tar.gz to retrodeck.2.tar.gz), and deletes the oldest 
# archive if it exceeds the maximum limit (default: 3 rotated logs). After rotation, 
# the original log file is cleared for continued logging.

rotate_logs() {
  local logfile="${1:-$rd_logs_folder/retrodeck.log}"  # Default log file
  local max_logs=3  # Maximum number of rotated logs to keep

  # Rotate existing logs
  for ((i=max_logs; i>0; i--)); do
    if [[ -f "${logfile}.${i}.tar.gz" ]]; then
      if (( i == max_logs )); then
        # Remove the oldest log if it exceeds the limit
        rm -f "${logfile}.${i}.tar.gz"
      else
        # Rename log file to the next number
        mv "${logfile}.${i}.tar.gz" "${logfile}.$((i+1)).tar.gz"
      fi
    fi
  done

  # Compress the current log file if it exists
  if [[ -f "$logfile" ]]; then
    # Compress without directory structure and suppress tar output
    tar -czf "${logfile}.1.tar.gz" -C "$(dirname "$logfile")" "$(basename "$logfile")" --remove-files &>/dev/null
  fi
}