#!/bin/bash
set -euo pipefail

# ------------------ CHECK FOR SUDO/ROOT ------------------ #
if [[ $EUID -ne 0 ]]; then
  echo "❌ This script must be run as root or with sudo."
  echo "   Please rerun it using: sudo $0 $*"
  exit 1
fi

# ------------------ CONFIG / DEFAULTS ------------------ #
TARGET=""
ACL_MODE=""
PERM_BITS=""
CHMOD_MODE=""
OWNER=""
DRY_RUN=false
LOG_FILE=""
MAX_LOG_BACKUPS=5

# ------------------ LOGGING ------------------ #
log() {
  if [[ -n "$LOG_FILE" ]]; then
    echo -e "$@" | tee -a "$LOG_FILE"
  else
    echo -e "$@"
  fi
}

rotate_log() {
  if [[ -n "$LOG_FILE" && -f "$LOG_FILE" ]]; then
    log "📦 Rotating log file: $LOG_FILE"
    for ((i=MAX_LOG_BACKUPS; i>=1; i--)); do
      [[ -f "$LOG_FILE.$i" ]] && mv "$LOG_FILE.$i" "$LOG_FILE.$((i+1))"
    done
    mv "$LOG_FILE" "$LOG_FILE.1"
  fi
}

logpipe() {
  if [[ -n "$LOG_FILE" ]]; then tee -a "$LOG_FILE"; else cat; fi
}

# ------------------ HELP MESSAGE ------------------ #
usage() {
  cat <<EOF
Usage: $0 --target DIR [--acl add|remove] [--chmod MODE] [--bits BITS] [--owner USER[:GROUP]] [--dry-run] [--log FILE]

Options:
  --target DIR         Directory to operate on (required)
  --acl MODE           Set ACL mode: "add" or "remove"
  --chmod MODE         Apply chmod mode recursively (e.g., 755, 644)
  --bits BITS          Add/remove special bits (e.g., u+s, g-s, +t, -t) (comma-separated)
  --owner USER[:GROUP] Change ownership recursively (e.g., dbi or dbi:users)
  --dry-run            Show what would be done without making changes
  --log FILE           Log output to FILE and rotate it (keeps 5 backups)
  --help               Show this help

Examples:
  $0 --target /data --acl remove --bits g-s,-t --chmod 755 --owner dbi:docker --log /var/log/permtool.log
EOF
}

# ------------------ ARGUMENT PARSING ------------------ #
while [[ $# -gt 0 ]]; do
  case $1 in
    --target) TARGET="$2"; shift 2 ;;
    --acl) ACL_MODE="$2"; shift 2 ;;
    --chmod) CHMOD_MODE="$2"; shift 2 ;;
    --bits) PERM_BITS="$2"; shift 2 ;;
    --owner) OWNER="$2"; shift 2 ;;
    --log) LOG_FILE="$2"; shift 2 ;;
    --dry-run) DRY_RUN=true; shift ;;
    --help) usage; exit 0 ;;
    *) echo "Unknown option: $1"; usage; exit 1 ;;
  esac
done

# ------------------ VALIDATION ------------------ #
if [[ -z "$TARGET" ]]; then
  echo "❌ --target is required"
  usage
  exit 1
fi

if [[ ! -d "$TARGET" ]]; then
  echo "❌ Target '$TARGET' is not a directory."
  exit 1
fi

[[ -n "$LOG_FILE" ]] && rotate_log

# ------------------ EXECUTION ------------------ #
log "🔧 Working on: $TARGET"
$DRY_RUN && log "⚠️ DRY RUN MODE ENABLED"
[[ -n "$LOG_FILE" ]] && log "📝 Logging to: $LOG_FILE"

# 🔹 Handle ACL
if [[ "$ACL_MODE" == "remove" ]]; then
  log "🧹 Removing all ACLs from $TARGET..."
  $DRY_RUN && echo "setfacl -bR '$TARGET'" | logpipe || setfacl -bR "$TARGET"
elif [[ "$ACL_MODE" == "add" ]]; then
  log "➕ Add ACL requested – no default ACL rule defined. Skipping actual operation."
fi

# 🔹 Handle chmod (applies to all files and dirs)
if [[ -n "$CHMOD_MODE" ]]; then
  log "🛠 Applying chmod $CHMOD_MODE recursively..."
  find "$TARGET" -print0 | while IFS= read -r -d '' file; do
    [[ -L "$file" ]] && continue  # skip symlinks
    $DRY_RUN && echo "chmod $CHMOD_MODE '$file'" || chmod "$CHMOD_MODE" "$file"
  done | logpipe
fi

# 🔹 Handle permission bits
if [[ -n "$PERM_BITS" ]]; then
  IFS=',' read -ra BITS <<< "$PERM_BITS"
  for bit in "${BITS[@]}"; do
    log "🔁 Applying bit '$bit' recursively..."
    find "$TARGET" -print0 | while IFS= read -r -d '' file; do
      [[ -L "$file" ]] && continue
      $DRY_RUN && echo "chmod $bit '$file'" || chmod "$bit" "$file"
    done | logpipe
  done
fi

# 🔹 Handle ownership
if [[ -n "$OWNER" ]]; then
  log "👤 Changing ownership to $OWNER recursively..."
  find "$TARGET" -print0 | while IFS= read -r -d '' file; do
    [[ -L "$file" ]] && continue
    $DRY_RUN && echo "chown $OWNER '$file'" || chown "$OWNER" "$file"
  done | logpipe
fi

log "✅ Done."