#!/usr/bin/env bash
# cPanel / DirectAdmin / Plesk / CloudLinux - PHP upload progress bulk manager
# Default: read-only preview. Changes require --apply.
set -Eeuo pipefail
shopt -s nullglob

SETTING='session.upload_progress.enabled'
DESIRED='session.upload_progress.enabled = Off'
PATTERN='^[[:space:]]*;?[[:space:]]*session\.upload_progress\.enabled[[:space:]]*='
MODE=check
RESTART=1

usage() {
  cat <<'HELP'
Usage (as root):
  bash php-upload-progress-manager.sh --check          Preview only (default)
  bash php-upload-progress-manager.sh --apply          Backup, update and restart running services
  bash php-upload-progress-manager.sh --apply --no-restart
  bash php-upload-progress-manager.sh --restart-only   Restart running PHP/web services

Updates installed PHP's global php.ini files and CloudLinux PHP Selector global settings.
Per-domain .user.ini, PHP-FPM pool overrides, and generated panel configs are not edited.
HELP
}

while (( $# )); do
  case "$1" in
    --check|--dry-run) MODE=check ;;
    --apply) MODE=apply ;;
    --restart-only) MODE=restart ;;
    --no-restart) RESTART=0 ;;
    -h|--help) usage; exit 0 ;;
    *) echo "Unknown option: $1" >&2; usage >&2; exit 2 ;;
  esac
  shift
done

(( EUID == 0 )) || { echo 'ERROR: Run as root (sudo).' >&2; exit 1; }

PANEL=Unknown
if [[ -f /usr/local/cpanel/cpanel || -f /var/cpanel/cpanel.config ]]; then
  PANEL=cPanel
elif [[ -f /usr/local/directadmin/conf/directadmin.conf || -x /usr/local/directadmin/directadmin ]]; then
  PANEL=DirectAdmin
elif [[ -f /usr/local/psa/version || -f /etc/psa/psa.conf ]]; then
  PANEL=Plesk
fi

CLOUDLINUX=No
if [[ -d /etc/cl.selector || -d /opt/alt ]]; then CLOUDLINUX=Yes; fi
printf 'Panel: %s | CloudLinux/ALT-PHP: %s | Mode: %s\n' "$PANEL" "$CLOUDLINUX" "$MODE"

FAILED=0
CHANGED=0
FOUND=0
BACKUP_DIR="/var/backups/php-upload-progress-$(date +%Y%m%d-%H%M%S)-$$"
declare -A SEEN=()

needs_change() {
  local file=$1
  [[ -f "$file" ]] || return 0
  awk -v goal="$DESIRED" '
    /^[[:space:]]*;?[[:space:]]*session\.upload_progress\.enabled[[:space:]]*=/ {
      seen=1
      if ($0 != goal) change=1
    }
    END { if (!seen || change) exit 0; exit 1 }
  ' "$file"
}

backup_file() {
  local file=$1
  mkdir -p -- "$BACKUP_DIR$(dirname -- "$file")"
  if [[ -f "$file" ]]; then
    cp -a -- "$file" "$BACKUP_DIR$file"
  else
    printf '%s\n' "$file" >> "$BACKUP_DIR/created-files.txt"
  fi
}

update_file() {
  local file=$1 original
  if [[ -e "$file" ]]; then
    original=$(readlink -f -- "$file") || return 1
    file=$original
  fi
  [[ -n "${SEEN[$file]:-}" ]] && return 0
  SEEN["$file"]=1
  ((FOUND+=1))

  if ! needs_change "$file"; then
    printf '[OK]       %s\n' "$file"
    return 0
  fi

  if [[ "$MODE" == check ]]; then
    printf '[DEĞİŞECEK] %s\n' "$file"
    ((CHANGED+=1))
    return 0
  fi

  if ! backup_file "$file"; then
    printf '[HATA] Yedek alınamadı: %s\n' "$file" >&2
    FAILED=1
    return 0
  fi
  if [[ -f "$file" ]]; then
    if grep -Eq "$PATTERN" "$file"; then
      sed -i -E 's/^[[:space:]]*;?[[:space:]]*session\.upload_progress\.enabled[[:space:]]*=.*/session.upload_progress.enabled = Off/' "$file"
    else
      printf '\n%s\n' "$DESIRED" >> "$file"
    fi
  else
    printf '[Global PHP Settings]\n%s\n' "$DESIRED" > "$file"
    chmod 0644 "$file"
  fi
  if needs_change "$file"; then
    printf '[HATA] Doğrulama başarısız: %s\n' "$file" >&2
    FAILED=1
  else
    printf '[GÜNCELLENDİ] %s\n' "$file"
    ((CHANGED+=1))
  fi
}

unit_running() {
  command -v systemctl >/dev/null 2>&1 && systemctl is-active --quiet "$1"
}

restart_services() {
  (( RESTART )) || { echo 'Service restart disabled (--no-restart).'; return 0; }
  if ! command -v systemctl >/dev/null 2>&1 || [[ ! -d /run/systemd/system ]]; then
    echo '[UYARI] systemd bulunamadı; servisleri elle yeniden başlatın.'
    return 0
  fi

  echo '--- Running PHP-FPM services ---'
  local unit script= have_ea=0
  local -a services=() ea_units=()
  mapfile -t services < <(systemctl list-units --type=service --state=running --no-legend --plain --no-pager 2>/dev/null | awk '$1 ~ /\.service$/ {print $1}')

  for unit in "${services[@]}"; do
    case "$unit" in
      *php*fpm*.service|*php*-fpm.service|php-fpm.service)
        if [[ "$PANEL" == cPanel && "$unit" == ea-php*-php-fpm.service ]]; then
          ea_units+=("$unit")
          have_ea=1
        else
          echo "Restarting $unit"
          systemctl restart "$unit" || { echo "[HATA] $unit" >&2; FAILED=1; }
        fi
        ;;
    esac
  done

  if (( have_ea )); then
    script=''
    if [[ -x /usr/local/cpanel/scripts/restartsrv_apache_php_fpm ]]; then
      script=/usr/local/cpanel/scripts/restartsrv_apache_php_fpm
    elif [[ -x /scripts/restartsrv_apache_php_fpm ]]; then
      script=/scripts/restartsrv_apache_php_fpm
    fi
    if [[ -n "$script" ]]; then
      echo "Restarting cPanel EA-PHP-FPM with $script"
      "$script" --restart || { echo '[HATA] cPanel PHP-FPM restart' >&2; FAILED=1; }
    else
      for unit in "${ea_units[@]}"; do
        echo "Restarting $unit"
        systemctl restart "$unit" || { echo "[HATA] $unit" >&2; FAILED=1; }
      done
    fi
  fi

  echo '--- Active web server ---'
  local lite_unit='' web_unit=''
  for unit in lsws.service lshttpd.service openlitespeed.service; do
    if unit_running "$unit"; then lite_unit=$unit; break; fi
  done
  if [[ -n "$lite_unit" ]]; then
    if [[ -d /usr/local/lsws/admin/tmp ]]; then
      touch /usr/local/lsws/admin/tmp/.lsphp_restart.txt
      echo 'LiteSpeed detached PHP workers marked for lazy restart.'
    fi
    echo "Gracefully restarting $lite_unit"
    systemctl restart "$lite_unit" || { echo "[HATA] $lite_unit" >&2; FAILED=1; }
  else
    for unit in httpd.service apache2.service; do
      if unit_running "$unit"; then web_unit=$unit; break; fi
    done
    if [[ -n "$web_unit" ]]; then
      if command -v apachectl >/dev/null 2>&1 && ! apachectl configtest >/dev/null 2>&1; then
        echo '[HATA] Apache configtest failed; Apache reload skipped.' >&2
        FAILED=1
      else
        echo "Reloading $web_unit"
        systemctl reload-or-restart "$web_unit" || { echo "[HATA] $web_unit" >&2; FAILED=1; }
      fi
    else
      echo 'Apache/LiteSpeed service not active; skipped.'
    fi
  fi
  if unit_running nginx.service; then
    if command -v nginx >/dev/null 2>&1 && ! nginx -t >/dev/null 2>&1; then
      echo '[HATA] nginx -t failed; nginx reload skipped.' >&2
      FAILED=1
    else
      echo 'Reloading nginx.service'
      systemctl reload-or-restart nginx.service || { echo '[HATA] nginx.service' >&2; FAILED=1; }
    fi
  fi
}

if [[ "$MODE" == restart ]]; then
  restart_services
  exit "$FAILED"
fi

# Widely-used, vendor-specific main php.ini paths. No blind recursive site-data scan.
for file in \
  /opt/cpanel/ea-php*/root/etc/php.ini \
  /opt/cloudlinux/alt-php*/root/etc/php.ini \
  /opt/alt/php*/etc/php.ini \
  /opt/plesk/php/*/etc/php.ini \
  /opt/remi/php*/root/etc/php.ini \
  /etc/opt/remi/php*/php.ini \
  /usr/local/php*/lib/php.ini \
  /usr/local/php*/etc/php.ini \
  /etc/php/*/*/php.ini \
  /etc/php/*/php.ini \
  /etc/php.ini \
  /usr/local/lib/php.ini
  do
    [[ -f "$file" ]] && update_file "$file"
  done

# CloudLinux PHP Selector persistent defaults for all current/future ALT-PHP versions.
if [[ -d /etc/cl.selector ]] && {
  [[ -f /etc/cl.selector/global_php.ini ]] ||
  command -v cagefsctl >/dev/null 2>&1 ||
  command -v selectorctl >/dev/null 2>&1;
}; then
  update_file /etc/cl.selector/global_php.ini
fi

printf '\nKontrol edilen: %d | %s: %d\n' "$FOUND" "$([[ "$MODE" == check ]] && echo 'Değişiklik gereken' || echo 'Güncellenen')" "$CHANGED"
if (( FOUND == 0 )); then
  echo '[UYARI] Bilinen konumlarda php.ini bulunamadı. PHP işleyicilerinin özel yollarını kontrol edin.'
  exit 2
fi

if [[ "$MODE" == apply && "$CHANGED" -gt 0 ]]; then
  echo "Yedek klasörü: $BACKUP_DIR"
  if [[ -d /etc/cl.selector ]] && command -v cagefsctl >/dev/null 2>&1; then
    echo 'CloudLinux PHP Selector ayarları uygulanıyor...'
    cagefsctl --setup-cl-selector || { echo '[HATA] cagefsctl --setup-cl-selector' >&2; FAILED=1; }
  elif [[ -d /etc/cl.selector ]] && command -v selectorctl >/dev/null 2>&1; then
    echo 'CloudLinux PHP Selector ayarları uygulanıyor...'
    selectorctl --apply-global-php-ini || { echo '[HATA] selectorctl --apply-global-php-ini' >&2; FAILED=1; }
  fi
  restart_services
elif [[ "$MODE" == apply ]]; then
  echo 'Hiçbir dosya değişmedi; servisler yeniden başlatılmadı.'
fi

echo 'NOT: Domain .user.ini / PHP-FPM php_admin_value / ek conf.d dosyaları bu genel ayarı geçersiz kılabilir.'
exit "$FAILED"
