#!/usr/bin/env bash
set -euo pipefail

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PACKAGE_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
source "$SCRIPT_DIR/lib/common.sh"

PROJECT_ENV=""
APPROVAL_FILE=""
APPLY=0
while [ "$#" -gt 0 ]; do
  case "$1" in
    --project-env) PROJECT_ENV="$2"; shift 2 ;;
    --approval-file) APPROVAL_FILE="$2"; shift 2 ;;
    --apply) APPLY=1; shift ;;
    *) die "unknown argument: $1" ;;
  esac
done

[ -n "$PROJECT_ENV" ] || die "--project-env is required"
load_env_file "$PROJECT_ENV"
assert_no_placeholders "$PROJECT_ENV"
[ "$PHP_REQUIRED_FUNCTIONS" = "exec,readlink,popen,proc_open,proc_get_status" ] ||
  die "PHP_REQUIRED_FUNCTIONS differs from the approved V1 baseline"

log "PLAN open only the approved functions for PHP 7.3 and PHP 7.4"
log "PLAN functions: $PHP_REQUIRED_FUNCTIONS"

[ "$APPLY" -eq 1 ] || {
  log "SHADOW_ONLY: php.ini files unchanged"
  exit 0
}

[ "$(id -u)" -eq 0 ] || die "PHP configuration requires root"
[ -n "$APPROVAL_FILE" ] || die "--approval-file is required with --apply"
require_apply_authorization "configure-php-required-functions" "$APPROVAL_FILE" "$TARGET_HOST_REF"
require_cmd python3

BACKUP_DIR="$BACKUP_ROOT/php-required-functions-$(date '+%Y%m%dT%H%M%S%z')"
PHP73_INI=/usr/local/php/etc/php.ini
PHP74_INI=/usr/local/php7.4/etc/php.ini
for ini in "$PHP73_INI" "$PHP74_INI"; do
  require_file "$ini"
  python3 "$PACKAGE_ROOT/tools/update_php_disable_functions.py" \
    --php-ini "$ini" \
    --required-functions "$PHP_REQUIRED_FUNCTIONS" \
    --backup "$BACKUP_DIR/$(basename "$(dirname "$(dirname "$ini")")")-php.ini.before"
done

restart_php_fpm() {
  local init_script="$1"
  local unit="$2"
  if [ -x "$init_script" ]; then
    "$init_script" restart
  elif systemctl list-unit-files "$unit.service" >/dev/null 2>&1; then
    systemctl restart "$unit"
  else
    return 1
  fi
}

set +e
restart_php_fpm /etc/init.d/php-fpm php-fpm
php73_restart_rc=$?
restart_php_fpm /etc/init.d/php-fpm7.4 php-fpm7.4
php74_restart_rc=$?
for php_bin in /usr/local/php/bin/php /usr/local/php7.4/bin/php; do
  "$php_bin" -r '
    foreach (explode(",", getenv("PHP_REQUIRED_FUNCTIONS")) as $function) {
        if (!function_exists($function)) { fwrite(STDERR, $function . " unavailable\n"); exit(1); }
    }
  '
  test_rc=$?
  [ "$test_rc" -eq 0 ] || break
done
set -e

if [ "$php73_restart_rc" -ne 0 ] || [ "$php74_restart_rc" -ne 0 ] || [ "${test_rc:-1}" -ne 0 ]; then
  cp -p "$BACKUP_DIR/php-php.ini.before" "$PHP73_INI"
  cp -p "$BACKUP_DIR/php7.4-php.ini.before" "$PHP74_INI"
  restart_php_fpm /etc/init.d/php-fpm php-fpm || true
  restart_php_fpm /etc/init.d/php-fpm7.4 php-fpm7.4 || true
  die "PHP function validation failed; previous php.ini files restored"
fi

log "PHP_REQUIRED_FUNCTIONS_APPLIED backup=$BACKUP_DIR"
