#!/usr/bin/env bash
# zendphpctl: a script for managing your ZendPHP and ZendHQ installations.
# This script is available via www.zend.com, and provided to allow a unified
# mechanism across different operating systems and versions for managing ZendPHP
# and ZendHQ installations.
#
# To report issues or support, refer to your Zend support contract.
#
# Copyright (c) Zend Technologies USA, Inc. (www.zend.com)

version_command() {
  echo "$version"
}

zendphpctl_usage() {
  printf "zendphpctl - Manage your ZendPHP installation\n\n"

  printf "%s\n" "$(bold "Usage:")"
  printf "  zendphpctl COMMAND\n"
  printf "  zendphpctl [COMMAND] --help | -h\n"
  printf "  zendphpctl --version | -v\n"
  echo

  printf "%s\n" "$(bold "Commands:")"
  printf "  %s   Generate bash autocompletions script\n" "$(green "completions")                "
  printf "  %s   Update the zendphpctl script itself.\n" "$(green "self-update")                "
  printf "  %s   Commands related to Apache integration\n" "$(green "apache")                     "
  printf "  %s   Commands related to PHP extension management\n" "$(green "ext")                        "
  printf "  %s   Commands related to FPM installation and management\n" "$(green "fpm")                        "
  printf "  %s   Commands related to PHP installation and configuration (use 'zendphpctl php --help' to list subcommands)\n" "$(green "php")                        "
  printf "  %s   Commands related to ZendPHP repository management\n" "$(green "repo")                       "
  printf "  %s   Commands related to ZendHQ management\n" "$(green "zendhq")                     "
  printf "  %s   Commands related to Z-Ray management\n" "$(green "zray")                       "
  echo

  if [[ -n "$long_usage" ]]; then
    printf "%s\n" "$(bold "Options:")"

    printf "  %s\n" "$(blue "--help, -h")"
    printf "    Show this help\n"
    echo
    printf "  %s\n" "$(blue "--version, -v")"
    printf "    Show version number\n"
    echo

    printf "Append --help or -h after any command name to get command-specific help.\n"
    echo

  fi
}

zendphpctl_completions_usage() {
  printf "zendphpctl completions - Generate bash autocompletions script\n\n"

  printf "%s\n" "$(bold "Usage:")"
  printf "  zendphpctl completions\n"
  printf "  zendphpctl completions --help | -h\n"
  echo

  if [[ -n "$long_usage" ]]; then
    printf "%s\n" "$(bold "Options:")"

    printf "  %s\n" "$(blue "--help, -h")"
    printf "    Show this help\n"
    echo

    printf "%s\n" "$(bold "Examples:")"
    printf "  eval \"\$(zendphpctl completions)\"\n"
    echo

  fi
}

zendphpctl_self_update_usage() {
  if [[ -n $long_usage ]]; then
    printf "zendphpctl self-update\n\n"
    printf "  Update the zendphpctl script itself.\n  \n  NOTE: Depending on where you have installed it and the permissions you\n  have assigned, this script MAY need to be run as root.\n\n"
  else
    printf "zendphpctl self-update - Update the zendphpctl script itself.\n\n"
  fi

  printf "%s\n" "$(bold "Usage:")"
  printf "  zendphpctl self-update\n"
  printf "  zendphpctl self-update --help | -h\n"
  echo

  if [[ -n "$long_usage" ]]; then
    printf "%s\n" "$(bold "Options:")"

    printf "  %s\n" "$(blue "--help, -h")"
    printf "    Show this help\n"
    echo

    printf "%s\n" "$(bold "Examples:")"
    printf "  zendphpctl self-update\n"
    echo

  fi
}

zendphpctl_apache_usage() {
  printf "zendphpctl apache - Commands related to Apache integration\n\n"

  printf "%s\n" "$(bold "Usage:")"
  printf "  zendphpctl apache COMMAND\n"
  printf "  zendphpctl apache [COMMAND] --help | -h\n"
  echo

  printf "%s\n" "$(bold "Commands:")"
  printf "  %s   Commands related to Apache mod_php integration\n" "$(green "mod_php")"
  echo

  if [[ -n "$long_usage" ]]; then
    printf "%s\n" "$(bold "Options:")"

    printf "  %s\n" "$(blue "--help, -h")"
    printf "    Show this help\n"
    echo

  fi
}

zendphpctl_apache_mod_php_usage() {
  printf "zendphpctl apache mod_php - Commands related to Apache mod_php integration\n\n"

  printf "%s\n" "$(bold "Usage:")"
  printf "  zendphpctl apache mod_php COMMAND\n"
  printf "  zendphpctl apache mod_php [COMMAND] --help | -h\n"
  echo

  printf "%s\n" "$(bold "Commands:")"
  printf "  %s   Install mod_php for an installed PHP version\n" "$(green "install")     "
  printf "  %s   Determine if mod_php is installed for the given PHP version\n" "$(green "is-installed")"
  printf "  %s   Uninstall mod_php support for an installed PHP version\n" "$(green "uninstall")   "
  echo

  if [[ -n "$long_usage" ]]; then
    printf "%s\n" "$(bold "Options:")"

    printf "  %s\n" "$(blue "--help, -h")"
    printf "    Show this help\n"
    echo

  fi
}

zendphpctl_apache_mod_php_install_usage() {
  printf "zendphpctl apache mod_php install - Install mod_php for an installed PHP version\n\n"

  printf "%s\n" "$(bold "Usage:")"
  printf "  zendphpctl apache mod_php install [PHP]\n"
  printf "  zendphpctl apache mod_php install --help | -h\n"
  echo

  if [[ -n "$long_usage" ]]; then
    printf "%s\n" "$(bold "Options:")"

    printf "  %s\n" "$(blue "--help, -h")"
    printf "    Show this help\n"
    echo

    printf "%s\n" "$(bold "Arguments:")"

    printf "  %s\n" "$(blue "PHP")"
    printf "    PHP minor version for which to install mod_php support; assumes default PHP\n    version (see php set-default) if not provided\n"
    echo

    printf "%s\n" "$(bold "Examples:")"
    printf "  zendphpctl apache mod_php install\n"
    printf "  zendphpctl apache mod_php install 8.1\n"
    printf "  zendphpctl apache mod_php install 7.4\n"
    echo

    printf "$(red This command must be run as root!)\n$(is_ibmi_compatible && red This command is not available on IBM i.)\n"
    echo

  fi
}

zendphpctl_apache_mod_php_is_installed_usage() {
  printf "zendphpctl apache mod_php is-installed - Determine if mod_php is installed for the given PHP version\n\n"

  printf "%s\n" "$(bold "Usage:")"
  printf "  zendphpctl apache mod_php is-installed [PHP]\n"
  printf "  zendphpctl apache mod_php is-installed --help | -h\n"
  echo

  if [[ -n "$long_usage" ]]; then
    printf "%s\n" "$(bold "Options:")"

    printf "  %s\n" "$(blue "--help, -h")"
    printf "    Show this help\n"
    echo

    printf "%s\n" "$(bold "Arguments:")"

    printf "  %s\n" "$(blue "PHP")"
    printf "    PHP minor version you are checking for mod_php support; assumes default PHP\n    version (see php set-default) if not provided\n"
    echo

    printf "%s\n" "$(bold "Examples:")"
    printf "  zendphpctl apache mod_php is-installed\n"
    printf "  zendphpctl apache mod_php is-installed 8.1\n"
    printf "  zendphpctl apache mod_php is-installed 7.4\n"
    echo

  fi
}

zendphpctl_apache_mod_php_uninstall_usage() {
  printf "zendphpctl apache mod_php uninstall - Uninstall mod_php support for an installed PHP version\n\n"

  printf "%s\n" "$(bold "Usage:")"
  printf "  zendphpctl apache mod_php uninstall [PHP]\n"
  printf "  zendphpctl apache mod_php uninstall --help | -h\n"
  echo

  if [[ -n "$long_usage" ]]; then
    printf "%s\n" "$(bold "Options:")"

    printf "  %s\n" "$(blue "--help, -h")"
    printf "    Show this help\n"
    echo

    printf "%s\n" "$(bold "Arguments:")"

    printf "  %s\n" "$(blue "PHP")"
    printf "    PHP minor version for which to uninstall mod_php support; assumes default\n    PHP version (see php set-default) if not provided.\n"
    echo

    printf "%s\n" "$(bold "Examples:")"
    printf "  zendphpctl apache mod_php uninstall\n"
    printf "  zendphpctl apache mod_php uninstall 8.1\n"
    printf "  zendphpctl apache mod_php uninstall 7.4\n"
    echo

    printf "$(red This command must be run as root!)\n$(is_ibmi_compatible && red This command is not available on IBM i.)\n"
    echo

  fi
}

zendphpctl_ext_usage() {
  printf "zendphpctl ext - Commands related to PHP extension management\n\n"

  printf "%s\n" "$(bold "Usage:")"
  printf "  zendphpctl ext COMMAND\n"
  printf "  zendphpctl ext [COMMAND] --help | -h\n"
  echo

  printf "%s\n" "$(bold "Commands:")"
  printf "  %s   Disable one or more PHP extensions\n" "$(green "disable")      "
  printf "  %s   Enable one or more PHP extensions\n" "$(green "enable")       "
  printf "  %s   Install one or more PHP extensions\n" "$(green "install")      "
  printf "  %s   Lists extensions currently enabled for the given PHP version\n" "$(green "list-enabled") "
  printf "  %s   Lists extensions installable via package manager for a given PHP version.\n" "$(green "list-packages")"
  echo

  if [[ -n "$long_usage" ]]; then
    printf "%s\n" "$(bold "Options:")"

    printf "  %s\n" "$(blue "--help, -h")"
    printf "    Show this help\n"
    echo

  fi
}

zendphpctl_ext_disable_usage() {
  printf "zendphpctl ext disable - Disable one or more PHP extensions\n\n"

  printf "%s\n" "$(bold "Usage:")"
  printf "  zendphpctl ext disable [OPTIONS] [--] EXTENSIONS...\n"
  printf "  zendphpctl ext disable --help | -h\n"
  echo

  if [[ -n "$long_usage" ]]; then
    printf "%s\n" "$(bold "Options:")"

    printf "  %s\n" "$(blue "--php PHP")"
    printf "    PHP minor version for which to disable extension(s); assumes default PHP\n    version (see php set-default) if not provided\n"
    echo

    printf "  %s\n" "$(blue "--sapi SAPI")"
    printf "    Disable an extension only for a given SAPI (e.g. cli, fpm) (DEB only)\n"
    printf "    %s\n" "Allowed: ALL, cli, fpm"
    printf "    %s\n" "Default: ALL"
    echo

    printf "  %s\n" "$(blue "--help, -h")"
    printf "    Show this help\n"
    echo

    printf "%s\n" "$(bold "Arguments:")"

    echo "  EXTENSIONS..."
    printf "    One or more extensions to disable\n"
    echo

    printf "%s\n" "$(bold "Examples:")"
    printf "  zendphpctl ext disable imap\n"
    printf "  zendphpctl ext disable --php 8.1 ldap mysqli redis\n"
    printf "  zendphpctl ext disable --php 7.4 --sapi fpm soap\n"
    echo

    printf "$(red This command must be run as root!)\n"
    echo

  fi
}

zendphpctl_ext_enable_usage() {
  printf "zendphpctl ext enable - Enable one or more PHP extensions\n\n"

  printf "%s\n" "$(bold "Usage:")"
  printf "  zendphpctl ext enable [OPTIONS] [--] EXTENSIONS...\n"
  printf "  zendphpctl ext enable --help | -h\n"
  echo

  if [[ -n "$long_usage" ]]; then
    printf "%s\n" "$(bold "Options:")"

    printf "  %s\n" "$(blue "--php PHP")"
    printf "    PHP minor version for which to enable extension(s); assumes default PHP\n    version (see php set-default) if not provided\n"
    echo

    printf "  %s\n" "$(blue "--sapi SAPI")"
    printf "    Enable an extension only for a given SAPI (e.g. cli, fpm) (DEB only)\n"
    printf "    %s\n" "Allowed: ALL, cli, fpm"
    printf "    %s\n" "Default: ALL"
    echo

    printf "  %s\n" "$(blue "--help, -h")"
    printf "    Show this help\n"
    echo

    printf "%s\n" "$(bold "Arguments:")"

    echo "  EXTENSIONS..."
    printf "    One or more extensions to enable\n"
    echo

    printf "%s\n" "$(bold "Examples:")"
    printf "  zendphpctl ext enable imap\n"
    printf "  zendphpctl ext enable --php 8.1 ldap mysqli redis\n"
    printf "  zendphpctl ext enable --php 7.4 --fpm soap\n"
    echo

    printf "$(red This command must be run as root!)\n"
    echo

  fi
}

zendphpctl_ext_install_usage() {
  if [[ -n $long_usage ]]; then
    printf "zendphpctl ext install\n\n"
    printf "  Install one or more PHP extensions\n  \n  The default behavior is to install existing ZendPHP extension packages if\n  they exist, and otherwise pull the extension from PECL, compile,\n  and install it.\n  \n  Please be aware that:\n  \n  - Some extensions will require additional dependencies in order to compile.\n    It is up to you to identify and install these dependencies.\n  - We do not specify any non-default configure flags. If you have specific\n  flags\n    you want to enable, you will need to manually compile the extension\n  yourself.\n\n"
  else
    printf "zendphpctl ext install - Install one or more PHP extensions\n\n"
  fi

  printf "%s\n" "$(bold "Usage:")"
  printf "  zendphpctl ext install [OPTIONS] [--] EXTENSIONS...\n"
  printf "  zendphpctl ext install --help | -h\n"
  echo

  if [[ -n "$long_usage" ]]; then
    printf "%s\n" "$(bold "Options:")"

    printf "  %s\n" "$(blue "--php PHP")"
    printf "    PHP minor version for which to install extension(s); assumes default PHP\n    version (see php set-default) if not provided\n"
    echo

    printf "  %s\n" "$(blue "--sapi SAPI")"
    printf "    Install an extension only for a given SAPI (e.g. cli, fpm) (DEB only)\n"
    printf "    %s\n" "Allowed: ALL, cli, fpm"
    printf "    %s\n" "Default: ALL"
    echo

    printf "  %s\n" "$(blue "--help, -h")"
    printf "    Show this help\n"
    echo

    printf "%s\n" "$(bold "Arguments:")"

    echo "  EXTENSIONS..."
    printf "    One or more extensions to install. Extensions should be specified\n    with the following format:\n    \n      {priority-}extension{-version}\n    \n    {priority-} is used to indicate loading priority; the default, if not\n    specified, is 20, but some extensions (e.g. Swoole, OpenSwoole) need\n    to be loaded after other extensions (e.g. JSON) and should specify a\n    higher priority number (higher loads later). {-version} can be used\n    to indicate a specific extension version to install. If either\n    {priority-} or {-version} are provided, the command will ALWAYS pull\n    and compile from PECL.\n"
    echo

    printf "%s\n" "$(bold "Examples:")"
    printf "  zendphpctl ext install imap\n"
    printf "  zendphpctl ext install --php 8.1 ldap mysqli redis\n"
    printf "  zendphpctl ext install --php 7.4 60-swoole-4.8.1\n"
    echo

    printf "$(red This command must be run as root!)\n"
    echo

  fi
}

zendphpctl_ext_list_enabled_usage() {
  if [[ -n $long_usage ]]; then
    printf "zendphpctl ext list-enabled\n\n"
    printf "  Lists extensions currently enabled for the given PHP version\n  \n  Extensions listed as enabled include both packaged extensions, and PECL\n  extensions that have been compiled, installed, and enabled for this\n  machine.\n\n"
  else
    printf "zendphpctl ext list-enabled - Lists extensions currently enabled for the given PHP version\n\n"
  fi

  printf "%s\n" "$(bold "Usage:")"
  printf "  zendphpctl ext list-enabled [PHP] [OPTIONS]\n"
  printf "  zendphpctl ext list-enabled --help | -h\n"
  echo

  if [[ -n "$long_usage" ]]; then
    printf "%s\n" "$(bold "Options:")"

    printf "  %s\n" "$(blue "--fpm")"
    printf "    List extensions enabled only for PHP-FPM (versus CLI) (DEB only)\n"
    echo

    printf "  %s\n" "$(blue "--help, -h")"
    printf "    Show this help\n"
    echo

    printf "%s\n" "$(bold "Arguments:")"

    printf "  %s\n" "$(blue "PHP")"
    printf "    PHP minor version for which to list enabled extensions; uses default (see\n    php set-default) if not provided.\n"
    echo

    printf "%s\n" "$(bold "Examples:")"
    printf "  zendphpctl ext list-enabled\n"
    printf "  zendphpctl ext list-enabled 7.4\n"
    printf "  zendphpctl ext list-enabled 7.4 --fpm\n"
    echo

  fi
}

zendphpctl_ext_list_packages_usage() {
  if [[ -n $long_usage ]]; then
    printf "zendphpctl ext list-packages\n\n"
    printf "  Lists extensions installable via package manager for a given PHP version.\n  \n  This command lists extensions that are included as part of the ZendPHP\n  repository that can be installed via your system package manager.\n\n"
  else
    printf "zendphpctl ext list-packages - Lists extensions installable via package manager for a given PHP version.\n\n"
  fi

  printf "%s\n" "$(bold "Usage:")"
  printf "  zendphpctl ext list-packages [PHP]\n"
  printf "  zendphpctl ext list-packages --help | -h\n"
  echo

  if [[ -n "$long_usage" ]]; then
    printf "%s\n" "$(bold "Options:")"

    printf "  %s\n" "$(blue "--help, -h")"
    printf "    Show this help\n"
    echo

    printf "%s\n" "$(bold "Arguments:")"

    printf "  %s\n" "$(blue "PHP")"
    printf "    PHP minor version for which to list available extension(s); uses default\n    (see php set-default) if not provided.\n"
    echo

    printf "%s\n" "$(bold "Examples:")"
    printf "  zendphpctl ext list-packages\n"
    printf "  zendphpctl ext list-packages 7.4\n"
    echo

    printf "$(red This command must be run as root!)\n"
    echo

  fi
}

zendphpctl_fpm_usage() {
  printf "zendphpctl fpm - Commands related to FPM installation and management\n\n"

  printf "%s\n" "$(bold "Usage:")"
  printf "  zendphpctl fpm COMMAND\n"
  printf "  zendphpctl fpm [COMMAND] --help | -h\n"
  echo

  printf "%s\n" "$(bold "Commands:")"
  printf "  %s   Configure PHP-FPM\n" "$(green "config")      "
  printf "  %s   Install FPM for an installed PHP version\n" "$(green "install")     "
  printf "  %s   Determine if FPM is installed for the given PHP version\n" "$(green "is-installed")"
  printf "  %s   Uninstall FPM for an installed PHP version\n" "$(green "uninstall")   "
  echo

  if [[ -n "$long_usage" ]]; then
    printf "%s\n" "$(bold "Options:")"

    printf "  %s\n" "$(blue "--help, -h")"
    printf "    Show this help\n"
    echo

  fi
}

zendphpctl_fpm_config_usage() {
  printf "zendphpctl fpm config - Configure PHP-FPM\n\n"

  printf "%s\n" "$(bold "Usage:")"
  printf "  zendphpctl fpm config [PHP]\n"
  printf "  zendphpctl fpm config --help | -h\n"
  echo

  if [[ -n "$long_usage" ]]; then
    printf "%s\n" "$(bold "Options:")"

    printf "  %s\n" "$(blue "--help, -h")"
    printf "    Show this help\n"
    echo

    printf "%s\n" "$(bold "Arguments:")"

    printf "  %s\n" "$(blue "PHP")"
    printf "    PHP minor version for which to configure FPM support; assumes default PHP\n    version (see php set-default) if not provided\n"
    echo

    printf "%s\n" "$(bold "Examples:")"
    printf "  zendphpctl fpm config\n"
    printf "  zendphpctl fpm config 8.1\n"
    printf "  zendphpctl fpm config 7.4\n"
    echo

    printf "$(red This command must be run as root!)\n$(is_ibmi_compatible && red This command is not available on IBM i.)\n"
    echo

  fi
}

zendphpctl_fpm_install_usage() {
  printf "zendphpctl fpm install - Install FPM for an installed PHP version\n\n"

  printf "%s\n" "$(bold "Usage:")"
  printf "  zendphpctl fpm install [PHP]\n"
  printf "  zendphpctl fpm install --help | -h\n"
  echo

  if [[ -n "$long_usage" ]]; then
    printf "%s\n" "$(bold "Options:")"

    printf "  %s\n" "$(blue "--help, -h")"
    printf "    Show this help\n"
    echo

    printf "%s\n" "$(bold "Arguments:")"

    printf "  %s\n" "$(blue "PHP")"
    printf "    PHP minor version for which to install FPM support; assumes default PHP\n    version (see php set-default) if not provided\n"
    echo

    printf "%s\n" "$(bold "Examples:")"
    printf "  zendphpctl fpm install\n"
    printf "  zendphpctl fpm install 8.1\n"
    printf "  zendphpctl fpm install 7.4\n"
    echo

    printf "$(red This command must be run as root!)\n$(is_ibmi_compatible && red This command is not available on IBM i.)\n"
    echo

  fi
}

zendphpctl_fpm_is_installed_usage() {
  printf "zendphpctl fpm is-installed - Determine if FPM is installed for the given PHP version\n\n"

  printf "%s\n" "$(bold "Usage:")"
  printf "  zendphpctl fpm is-installed [PHP]\n"
  printf "  zendphpctl fpm is-installed --help | -h\n"
  echo

  if [[ -n "$long_usage" ]]; then
    printf "%s\n" "$(bold "Options:")"

    printf "  %s\n" "$(blue "--help, -h")"
    printf "    Show this help\n"
    echo

    printf "%s\n" "$(bold "Arguments:")"

    printf "  %s\n" "$(blue "PHP")"
    printf "    PHP minor version you are checking for FPM support; assumes default PHP\n    version (see php set-default) if not provided\n"
    echo

    printf "%s\n" "$(bold "Examples:")"
    printf "  zendphpctl fpm is-installed\n"
    printf "  zendphpctl fpm is-installed 8.1\n"
    printf "  zendphpctl fpm is-installed 7.4\n"
    echo

  fi
}

zendphpctl_fpm_uninstall_usage() {
  printf "zendphpctl fpm uninstall - Uninstall FPM for an installed PHP version\n\n"

  printf "%s\n" "$(bold "Usage:")"
  printf "  zendphpctl fpm uninstall [PHP]\n"
  printf "  zendphpctl fpm uninstall --help | -h\n"
  echo

  if [[ -n "$long_usage" ]]; then
    printf "%s\n" "$(bold "Options:")"

    printf "  %s\n" "$(blue "--help, -h")"
    printf "    Show this help\n"
    echo

    printf "%s\n" "$(bold "Arguments:")"

    printf "  %s\n" "$(blue "PHP")"
    printf "    PHP minor version for which to uninstall FPM support; assumes default PHP\n    version (see php set-default) if not provided.\n"
    echo

    printf "%s\n" "$(bold "Examples:")"
    printf "  zendphpctl fpm uninstall\n"
    printf "  zendphpctl fpm uninstall 8.1\n"
    printf "  zendphpctl fpm uninstall 7.4\n"
    echo

    printf "$(red This command must be run as root!)\n$(is_ibmi_compatible && red This command is not available on IBM i.)\n"
    echo

  fi
}

zendphpctl_php_usage() {
  printf "zendphpctl php - Commands related to PHP installation and configuration (use 'zendphpctl php --help' to list subcommands)\n\n"

  printf "%s\n" "$(bold "Usage:")"
  printf "  zendphpctl php COMMAND\n"
  printf "  zendphpctl php [COMMAND] --help | -h\n"
  echo

  printf "%s\n" "$(bold "Commands:")"
  printf "  %s   Configure a PHP version\n" "$(green "config")        "
  printf "  %s   List installed PHP versions\n" "$(green "list-installed")"
  printf "  %s   List installed PHP SAPIs for a PHP version\n" "$(green "list-sapis")    "
  printf "  %s   Set an installed PHP version as the default to use when calling \"php\" on the command line.\n" "$(green "set-default")   "
  printf "  %s   Get the configured default PHP version.\n" "$(green "get-default")   "
  printf "  %s   List information for a PHP version\n" "$(green "info")          "
  printf "  %s   Install another PHP version\n" "$(green "install")       "
  printf "  %s   Uninstall a previously installed PHP version\n" "$(green "uninstall")     "
  printf "  %s   Execute the given PHP script(s) using a selected PHP binary\n" "$(green "exec")          "
  echo

  if [[ -n "$long_usage" ]]; then
    printf "%s\n" "$(bold "Options:")"

    printf "  %s\n" "$(blue "--help, -h")"
    printf "    Show this help\n"
    echo

  fi
}

zendphpctl_php_config_usage() {
  printf "zendphpctl php config - Configure a PHP version\n\n"

  printf "%s\n" "$(bold "Usage:")"
  printf "  zendphpctl php config [PHP] [OPTIONS]\n"
  printf "  zendphpctl php config --help | -h\n"
  echo

  if [[ -n "$long_usage" ]]; then
    printf "%s\n" "$(bold "Options:")"

    printf "  %s\n" "$(blue "--fpm")"
    printf "    Configure PHP for use with PHP-FPM (versus CLI)\n"
    echo

    printf "  %s\n" "$(blue "--help, -h")"
    printf "    Show this help\n"
    echo

    printf "%s\n" "$(bold "Arguments:")"

    printf "  %s\n" "$(blue "PHP")"
    printf "    PHP minor version to configure; uses default (see php set-default) if not\n    provided.\n"
    echo

    printf "%s\n" "$(bold "Examples:")"
    printf "  zendphpctl php config 8.1\n"
    printf "  zendphpctl php config 7.4\n"
    printf "  zendphpctl php config 7.3 --fpm\n"
    echo

    printf "$(red This command must be run as root!)\n"
    echo

  fi
}

zendphpctl_php_list_installed_usage() {
  printf "zendphpctl php list-installed - List installed PHP versions\n\n"

  printf "%s\n" "$(bold "Usage:")"
  printf "  zendphpctl php list-installed [OPTIONS]\n"
  printf "  zendphpctl php list-installed --help | -h\n"
  echo

  if [[ -n "$long_usage" ]]; then
    printf "%s\n" "$(bold "Options:")"

    printf "  %s\n" "$(blue "--verbose, -v")"
    printf "    Verbose output. When this flag is present, the list will also include\n    additional information such as the full PHP version, binary location,\n    location of configuration, and extension directory.\n"
    echo

    printf "  %s\n" "$(blue "--json, -j")"
    printf "    When this flag is present, the list will be presented as a JSON array.\n    When combined with --verbose, it will be an array of objects, one for\n    each version, detailing all information for that version. Requires jq.\n"
    echo

    printf "  %s\n" "$(blue "--help, -h")"
    printf "    Show this help\n"
    echo

    printf "%s\n" "$(bold "Examples:")"
    printf "  zendphpctl php list-installed\n"
    printf "  zendphpctl php list-installed -v\n"
    echo

  fi
}

zendphpctl_php_list_sapis_usage() {
  printf "zendphpctl php list-sapis - List installed PHP SAPIs for a PHP version\n\n"

  printf "%s\n" "$(bold "Usage:")"
  printf "  zendphpctl php list-sapis [PHP]\n"
  printf "  zendphpctl php list-sapis --help | -h\n"
  echo

  if [[ -n "$long_usage" ]]; then
    printf "%s\n" "$(bold "Options:")"

    printf "  %s\n" "$(blue "--help, -h")"
    printf "    Show this help\n"
    echo

    printf "%s\n" "$(bold "Arguments:")"

    printf "  %s\n" "$(blue "PHP")"
    printf "    PHP minor version for which to install SAPIs; assumes default PHP version\n    (see php set-default) if not provided\n"
    echo

    printf "%s\n" "$(bold "Examples:")"
    printf "  zendphpctl php list-sapis\n"
    printf "  zendphpctl php list-sapis 7.4\n"
    echo

  fi
}

zendphpctl_php_set_default_usage() {
  printf "zendphpctl php set-default - Set an installed PHP version as the default to use when calling \"php\" on the command line.\n\n"

  printf "%s\n" "$(bold "Usage:")"
  printf "  zendphpctl php set-default PHP\n"
  printf "  zendphpctl php set-default --help | -h\n"
  echo

  if [[ -n "$long_usage" ]]; then
    printf "%s\n" "$(bold "Options:")"

    printf "  %s\n" "$(blue "--help, -h")"
    printf "    Show this help\n"
    echo

    printf "%s\n" "$(bold "Arguments:")"

    printf "  %s\n" "$(blue "PHP")"
    printf "    PHP minor version to mark as the default\n"
    echo

    printf "%s\n" "$(bold "Examples:")"
    printf "  zendphpctl set-default 8.1\n"
    printf "  zendphpctl set-default 7.4\n"
    echo

    printf "$(red This command must be run as root!)\n"
    echo

  fi
}

zendphpctl_php_get_default_usage() {
  if [[ -n $long_usage ]]; then
    printf "zendphpctl php get-default\n\n"
    printf "  Get the configured default PHP version.\n  \n  Lists the resolved path to the configured default PHP version, and\n  provides the output of running \"php -v\".\n\n"
  else
    printf "zendphpctl php get-default - Get the configured default PHP version.\n\n"
  fi

  printf "%s\n" "$(bold "Usage:")"
  printf "  zendphpctl php get-default\n"
  printf "  zendphpctl php get-default --help | -h\n"
  echo

  if [[ -n "$long_usage" ]]; then
    printf "%s\n" "$(bold "Options:")"

    printf "  %s\n" "$(blue "--help, -h")"
    printf "    Show this help\n"
    echo

  fi
}

zendphpctl_php_info_usage() {
  printf "zendphpctl php info - List information for a PHP version\n\n"

  printf "%s\n" "$(bold "Usage:")"
  printf "  zendphpctl php info [OPTIONS]\n"
  printf "  zendphpctl php info --help | -h\n"
  echo

  if [[ -n "$long_usage" ]]; then
    printf "%s\n" "$(bold "Options:")"

    printf "  %s\n" "$(blue "--php PHP")"
    printf "    PHP minor version for which to fetch information; assumes default PHP\n    version (see php set-default) if not provided\n"
    echo

    printf "  %s\n" "$(blue "--json, -j")"
    printf "    When this flag is present, the information will be presented as a JSON\n    object.\n    Requires jq.\n"
    echo

    printf "  %s\n" "$(blue "--help, -h")"
    printf "    Show this help\n"
    echo

    printf "%s\n" "$(bold "Examples:")"
    printf "  zendphpctl php info\n"
    printf "  zendphpctl php info --json\n"
    printf "  zendphpctl php info --php 7.4\n"
    printf "  zendphpctl php info --php 7.4 --json\n"
    echo

  fi
}

zendphpctl_php_install_usage() {
  if [[ -n $long_usage ]]; then
    printf "zendphpctl php install\n\n"
    printf "  Install another PHP version\n  \n  This version will become the default PHP version following installation\n  unless the --not-default flag is provided.\n\n"
  else
    printf "zendphpctl php install - Install another PHP version\n\n"
  fi

  printf "%s\n" "$(bold "Usage:")"
  printf "  zendphpctl php install PHP [OPTIONS]\n"
  printf "  zendphpctl php install --help | -h\n"
  echo

  if [[ -n "$long_usage" ]]; then
    printf "%s\n" "$(bold "Options:")"

    printf "  %s\n" "$(blue "--not-default")"
    printf "    Do not make this version the default following installation\n"
    echo

    printf "  %s\n" "$(blue "--help, -h")"
    printf "    Show this help\n"
    echo

    printf "%s\n" "$(bold "Arguments:")"

    printf "  %s\n" "$(blue "PHP")"
    printf "    PHP minor version to install\n"
    printf "    %s\n" "Allowed: 5.6, 7.1, 7.2, 7.3, 7.4, 8.0, 8.1, 8.2, 8.3, 8.4, 8.5"
    echo

    printf "%s\n" "$(bold "Examples:")"
    printf "  zendphpctl php install 8.1\n"
    printf "  zendphpctl php install 7.4\n"
    echo

    printf "$(red This command must be run as root!)\n"
    echo

  fi
}

zendphpctl_php_uninstall_usage() {
  printf "zendphpctl php uninstall - Uninstall a previously installed PHP version\n\n"

  printf "%s\n" "$(bold "Usage:")"
  printf "  zendphpctl php uninstall PHP\n"
  printf "  zendphpctl php uninstall --help | -h\n"
  echo

  if [[ -n "$long_usage" ]]; then
    printf "%s\n" "$(bold "Options:")"

    printf "  %s\n" "$(blue "--help, -h")"
    printf "    Show this help\n"
    echo

    printf "%s\n" "$(bold "Arguments:")"

    printf "  %s\n" "$(blue "PHP")"
    printf "    PHP minor version to uninstall\n"
    echo

    printf "%s\n" "$(bold "Examples:")"
    printf "  zendphpctl php uninstall 8.1\n"
    printf "  zendphpctl php uninstall 7.4\n"
    echo

    printf "$(red This command must be run as root!)\n"
    echo

  fi
}

zendphpctl_php_exec_usage() {
  printf "zendphpctl php exec - Execute the given PHP script(s) using a selected PHP binary\n\n"

  printf "%s\n" "$(bold "Usage:")"
  printf "  zendphpctl php exec [OPTIONS] [--] ARGUMENTS...\n"
  printf "  zendphpctl php exec --help | -h\n"
  echo

  if [[ -n "$long_usage" ]]; then
    printf "%s\n" "$(bold "Options:")"

    printf "  %s\n" "$(blue "--php VERSION")"
    printf "    PHP minor version to use; assumes default PHP version (see php set-default)\n    if not provided\n"
    echo

    printf "  %s\n" "$(blue "--help, -h")"
    printf "    Show this help\n"
    echo

    printf "%s\n" "$(bold "Arguments:")"

    echo "  ARGUMENTS..."
    printf "    The script and/or arguments to execute using the selected PHP version\n"
    echo

    printf "%s\n" "$(bold "Examples:")"
    printf "  zendphpctl php exec script.php\n"
    printf "  zendphpctl php exec --php 8.1 test.php\n"
    printf "  zendphpctl php exec --php 7.4 command.php argument and --flags --to-use\n"
    echo

  fi
}

zendphpctl_repo_usage() {
  printf "zendphpctl repo - Commands related to ZendPHP repository management\n\n"

  printf "%s\n" "$(bold "Usage:")"
  printf "  zendphpctl repo COMMAND\n"
  printf "  zendphpctl repo [COMMAND] --help | -h\n"
  echo

  printf "%s\n" "$(bold "Commands:")"
  printf "  %s   Provide credentials for the ZendPHP package repository on your system, allowing access to LTS editions\n" "$(green "credentials")"
  printf "  %s   Install the ZendPHP package repository on your system\n" "$(green "install")    "
  printf "  %s   Uninstall the ZendPHP package repository from your system\n" "$(green "uninstall")  "
  echo

  if [[ -n "$long_usage" ]]; then
    printf "%s\n" "$(bold "Options:")"

    printf "  %s\n" "$(blue "--help, -h")"
    printf "    Show this help\n"
    echo

  fi
}

zendphpctl_repo_credentials_usage() {
  if [[ -n $long_usage ]]; then
    printf "zendphpctl repo credentials\n\n"
    printf "  Provide credentials for the ZendPHP package repository on your system,\n  allowing access to LTS editions\n  \n  Both the --account and --password values MUST be provided.\n  \n  $(red If credentials were present previously, this operation will overwrite\n  them!)\n\n"
  else
    printf "zendphpctl repo credentials - Provide credentials for the ZendPHP package repository on your system, allowing access to LTS editions\n\n"
  fi

  printf "%s\n" "$(bold "Usage:")"
  printf "  zendphpctl repo credentials [OPTIONS]\n"
  printf "  zendphpctl repo credentials --help | -h\n"
  echo

  if [[ -n "$long_usage" ]]; then
    printf "%s\n" "$(bold "Options:")"

    printf "  %s\n" "$(blue "--account ACCOUNT (required)")"
    printf "    Account or order identifier associated with your credentials\n"
    echo

    printf "  %s\n" "$(blue "--password PASSWORD (required)")"
    printf "    Password associated with your credentials\n"
    echo

    printf "  %s\n" "$(blue "--help, -h")"
    printf "    Show this help\n"
    echo

    printf "%s\n" "$(bold "Examples:")"
    printf "  zendphpctl repo credentials --account ORDER_ID --password PASSWORD\n"
    echo

    printf "$(red This command must be run as root!)\n"
    echo

  fi
}

zendphpctl_repo_install_usage() {
  if [[ -n $long_usage ]]; then
    printf "zendphpctl repo install\n\n"
    printf "  Install the ZendPHP package repository on your system\n  \n  You may optionally provide your credentials to allow immediate access to LTS\n  editions of ZendPHP. If you provide credentials you MUST provide both the\n  --account and --password flags.\n\n"
  else
    printf "zendphpctl repo install - Install the ZendPHP package repository on your system\n\n"
  fi

  printf "%s\n" "$(bold "Usage:")"
  printf "  zendphpctl repo install [OPTIONS]\n"
  printf "  zendphpctl repo install --help | -h\n"
  echo

  if [[ -n "$long_usage" ]]; then
    printf "%s\n" "$(bold "Options:")"

    printf "  %s\n" "$(blue "--account ACCOUNT")"
    printf "    (Optional) Account or order identifier associated with your credentials\n"
    echo

    printf "  %s\n" "$(blue "--password PASSWORD")"
    printf "    (Optional) Password associated with your credentials\n"
    echo

    printf "  %s\n" "$(blue "--uri URI (repeatable)")"
    printf "    (Optional) Base URI to use instead of https://repos.zend.com/zendphp for the\n    repository setup. Can be specified multiple times to add multiple repository\n    definitions.\n"
    echo

    printf "  %s\n" "$(blue "--help, -h")"
    printf "    Show this help\n"
    echo

    printf "%s\n" "$(bold "Examples:")"
    printf "  zendphpctl repo install\n"
    printf "  zendphpctl repo install --account ORDER_ID --password PASSWORD\n"
    printf "  zendphpctl repo install --uri https://mirror.zend.com/zendphp --uri\n  https://repos.zend.com/zendphp\n"
    echo

    printf "$(red This command must be run as root!)\n"
    echo

  fi
}

zendphpctl_repo_uninstall_usage() {
  if [[ -n $long_usage ]]; then
    printf "zendphpctl repo uninstall\n\n"
    printf "  Uninstall the ZendPHP package repository from your system\n  \n  NOTE: this action DOES NOT remove previously installed ZendPHP packages;\n  it only removes the package repository from your system, preventing\n  further updates and/or installations.\n\n"
  else
    printf "zendphpctl repo uninstall - Uninstall the ZendPHP package repository from your system\n\n"
  fi

  printf "%s\n" "$(bold "Usage:")"
  printf "  zendphpctl repo uninstall\n"
  printf "  zendphpctl repo uninstall --help | -h\n"
  echo

  if [[ -n "$long_usage" ]]; then
    printf "%s\n" "$(bold "Options:")"

    printf "  %s\n" "$(blue "--help, -h")"
    printf "    Show this help\n"
    echo

    printf "%s\n" "$(bold "Examples:")"
    printf "  zendphpctl repo uninstall\n"
    echo

    printf "$(red This command must be run as root!)\n"
    echo

  fi
}

zendphpctl_zendhq_usage() {
  printf "zendphpctl zendhq - Commands related to ZendHQ management\n\n"

  printf "%s\n" "$(bold "Usage:")"
  printf "  zendphpctl zendhq COMMAND\n"
  printf "  zendphpctl zendhq [COMMAND] --help | -h\n"
  echo

  printf "%s\n" "$(bold "Commands:")"
  printf "  %s   Reset the ZendHQ service token, used to authenticate websocket and GUI clients\n" "$(green "token")"
  echo

  if [[ -n "$long_usage" ]]; then
    printf "%s\n" "$(bold "Options:")"

    printf "  %s\n" "$(blue "--help, -h")"
    printf "    Show this help\n"
    echo

  fi
}

zendphpctl_zendhq_token_usage() {
  if [[ -n $long_usage ]]; then
    printf "zendphpctl zendhq token\n\n"
    printf "  Reset the ZendHQ service token, used to authenticate websocket and GUI clients\n  with ZendHQ.\n\n"
  else
    printf "zendphpctl zendhq token - Reset the ZendHQ service token, used to authenticate websocket and GUI clients\n\n"
  fi

  printf "%s\n" "$(bold "Usage:")"
  printf "  zendphpctl zendhq token TOKEN [OPTIONS]\n"
  printf "  zendphpctl zendhq token --help | -h\n"
  echo

  if [[ -n "$long_usage" ]]; then
    printf "%s\n" "$(bold "Options:")"

    printf "  %s\n" "$(blue "--no-restart")"
    printf "    Do not restart ZendHQ following token update\n"
    echo

    printf "  %s\n" "$(blue "--help, -h")"
    printf "    Show this help\n"
    echo

    printf "%s\n" "$(bold "Arguments:")"

    printf "  %s\n" "$(blue "TOKEN")"
    printf "    New token to use\n"
    echo

    printf "%s\n" "$(bold "Examples:")"
    printf "  zendphpctl zendhq token foobar\n"
    echo

    printf "$(red This command must be run as root!)\n$(is_ibmi_compatible && red This command is not available on IBM i.)\n"
    echo

  fi
}

zendphpctl_zray_usage() {
  printf "zendphpctl zray - Commands related to Z-Ray management\n\n"

  printf "%s\n" "$(bold "Usage:")"
  printf "  zendphpctl zray COMMAND\n"
  printf "  zendphpctl zray [COMMAND] --help | -h\n"
  echo

  printf "%s\n" "$(bold "Commands:")"
  printf "  %s   Commands related to Z-Ray plugin management\n" "$(green "plugin")"
  echo

  if [[ -n "$long_usage" ]]; then
    printf "%s\n" "$(bold "Options:")"

    printf "  %s\n" "$(blue "--help, -h")"
    printf "    Show this help\n"
    echo

  fi
}

zendphpctl_zray_plugin_usage() {
  printf "zendphpctl zray plugin - Commands related to Z-Ray plugin management\n\n"

  printf "%s\n" "$(bold "Usage:")"
  printf "  zendphpctl zray plugin COMMAND\n"
  printf "  zendphpctl zray plugin [COMMAND] --help | -h\n"
  echo

  printf "%s\n" "$(bold "Commands:")"
  printf "  %s   Install the Z-Ray plugins package, containing Zend-maintained plugins to\n" "$(green "install")"
  printf "  %s   List installed Z-Ray plugins, optionally detailing only those enabled.\n" "$(green "list")   "
  printf "  %s   Disable one or more Z-Ray plugins.\n" "$(green "disable")"
  printf "  %s   Enable one or more Z-Ray plugins.\n" "$(green "enable") "
  echo

  if [[ -n "$long_usage" ]]; then
    printf "%s\n" "$(bold "Options:")"

    printf "  %s\n" "$(blue "--help, -h")"
    printf "    Show this help\n"
    echo

  fi
}

zendphpctl_zray_plugin_install_usage() {
  if [[ -n $long_usage ]]; then
    printf "zendphpctl zray plugin install\n\n"
    printf "  Install the Z-Ray plugins package, containing Zend-maintained plugins to\n  the Z-Ray application insight tool.\n\n"
  else
    printf "zendphpctl zray plugin install - Install the Z-Ray plugins package, containing Zend-maintained plugins to\n\n"
  fi

  printf "%s\n" "$(bold "Usage:")"
  printf "  zendphpctl zray plugin install [OPTIONS]\n"
  printf "  zendphpctl zray plugin install --help | -h\n"
  echo

  if [[ -n "$long_usage" ]]; then
    printf "%s\n" "$(bold "Options:")"

    printf "  %s\n" "$(blue "--php PHP")"
    printf "    PHP minor version for which to disable extension(s); assumes default PHP\n    version (see php set-default) if not provided\n"
    echo

    printf "  %s\n" "$(blue "--help, -h")"
    printf "    Show this help\n"
    echo

    printf "$(red This command must be run as root!)\n$(is_ibmi_compatible && red This command is not available on IBM i.)\n"
    echo

  fi
}

zendphpctl_zray_plugin_list_usage() {
  if [[ -n $long_usage ]]; then
    printf "zendphpctl zray plugin list\n\n"
    printf "  List installed Z-Ray plugins, optionally detailing only those enabled.\n\n"
  else
    printf "zendphpctl zray plugin list - List installed Z-Ray plugins, optionally detailing only those enabled.\n\n"
  fi

  printf "%s\n" "$(bold "Usage:")"
  printf "  zendphpctl zray plugin list [OPTIONS]\n"
  printf "  zendphpctl zray plugin list --help | -h\n"
  echo

  if [[ -n "$long_usage" ]]; then
    printf "%s\n" "$(bold "Options:")"

    printf "  %s\n" "$(blue "--enabled")"
    printf "    List only enabled plugins\n"
    echo

    printf "  %s\n" "$(blue "--help, -h")"
    printf "    Show this help\n"
    echo

    printf "%s\n" "$(bold "Examples:")"
    printf "  zendphpctl zray plugin list\n"
    printf "  zendphpctl zray plugin list --enabled\n"
    echo

    printf "$(red This command must be run as root!)\n$(is_ibmi_compatible && red This command is not available on IBM i.)\n"
    echo

  fi
}

zendphpctl_zray_plugin_disable_usage() {
  printf "zendphpctl zray plugin disable - Disable one or more Z-Ray plugins.\n\n"

  printf "%s\n" "$(bold "Usage:")"
  printf "  zendphpctl zray plugin disable [--] PLUGINS...\n"
  printf "  zendphpctl zray plugin disable --help | -h\n"
  echo

  if [[ -n "$long_usage" ]]; then
    printf "%s\n" "$(bold "Options:")"

    printf "  %s\n" "$(blue "--help, -h")"
    printf "    Show this help\n"
    echo

    printf "%s\n" "$(bold "Arguments:")"

    echo "  PLUGINS..."
    printf "    One or more plugins to disable\n"
    echo

    printf "%s\n" "$(bold "Examples:")"
    printf "  zendphpctl zray plugin disable composer\n"
    printf "  zendphpctl zray plugin disable composer symfony\n"
    echo

    printf "$(red This command must be run as root!)\n$(is_ibmi_compatible && red This command is not available on IBM i.)\n"
    echo

  fi
}

zendphpctl_zray_plugin_enable_usage() {
  printf "zendphpctl zray plugin enable - Enable one or more Z-Ray plugins.\n\n"

  printf "%s\n" "$(bold "Usage:")"
  printf "  zendphpctl zray plugin enable [--] PLUGINS...\n"
  printf "  zendphpctl zray plugin enable --help | -h\n"
  echo

  if [[ -n "$long_usage" ]]; then
    printf "%s\n" "$(bold "Options:")"

    printf "  %s\n" "$(blue "--help, -h")"
    printf "    Show this help\n"
    echo

    printf "%s\n" "$(bold "Arguments:")"

    echo "  PLUGINS..."
    printf "    One or more plugins to enable\n"
    echo

    printf "%s\n" "$(bold "Examples:")"
    printf "  zendphpctl zray plugin enable composer\n"
    printf "  zendphpctl zray plugin enable composer symfony\n"
    echo

    printf "$(red This command must be run as root!)\n$(is_ibmi_compatible && red This command is not available on IBM i.)\n"
    echo

  fi
}

php_config_usage() {
  printf "zendphpctl php-config - Configure a PHP version\n\n"

  printf "%s\n" "$(bold "Usage:")"
  printf "  zendphpctl php-config [PHP] [OPTIONS]\n"
  printf "  zendphpctl php-config --help | -h\n"
  echo

  if [[ -n "$long_usage" ]]; then
    printf "%s\n" "$(bold "Options:")"

    printf "  %s\n" "$(blue "--fpm")"
    printf "    Configure PHP for use with PHP-FPM (versus CLI)\n"
    echo

    printf "  %s\n" "$(blue "--help, -h")"
    printf "    Show this help\n"
    echo

    printf "%s\n" "$(bold "Arguments:")"

    printf "  %s\n" "$(blue "PHP")"
    printf "    PHP minor version to configure; uses default (see php set-default) if not\n    provided.\n"
    echo

    printf "%s\n" "$(bold "Examples:")"
    printf "  zendphpctl php config 8.1\n"
    printf "  zendphpctl php config 7.4\n"
    printf "  zendphpctl php config 7.3 --fpm\n"
    echo

    printf "$(red This command must be run as root!)\n\n$(red DEPRECATED use \"zendphpctl php config\" instead)\n"
    echo

  fi
}

php_list_installed_usage() {
  printf "zendphpctl php-list-installed - List installed PHP versions\n\n"

  printf "%s\n" "$(bold "Usage:")"
  printf "  zendphpctl php-list-installed [OPTIONS]\n"
  printf "  zendphpctl php-list-installed --help | -h\n"
  echo

  if [[ -n "$long_usage" ]]; then
    printf "%s\n" "$(bold "Options:")"

    printf "  %s\n" "$(blue "--verbose, -v")"
    printf "    Verbose output. When this flag is present, the list will also include\n    additional information such as the full PHP version, binary location,\n    location of configuration, and extension directory.\n"
    echo

    printf "  %s\n" "$(blue "--json, -j")"
    printf "    When this flag is present, the list will be presented as a JSON array.\n    When combined with --verbose, it will be an array of objects, one for\n    each version, detailing all information for that version. Requires jq.\n"
    echo

    printf "  %s\n" "$(blue "--help, -h")"
    printf "    Show this help\n"
    echo

    printf "%s\n" "$(bold "Examples:")"
    printf "  zendphpctl php list-installed\n"
    printf "  zendphpctl php list-installed -v\n"
    echo

    printf "$(red DEPRECATED use \"zendphpctl php list-installed\" instead)\n"
    echo

  fi
}

php_set_default_usage() {
  printf "zendphpctl php-set-default - Set an installed PHP version as the default to use when calling \"php\" on the command line.\n\n"

  printf "%s\n" "$(bold "Usage:")"
  printf "  zendphpctl php-set-default PHP\n"
  printf "  zendphpctl php-set-default --help | -h\n"
  echo

  if [[ -n "$long_usage" ]]; then
    printf "%s\n" "$(bold "Options:")"

    printf "  %s\n" "$(blue "--help, -h")"
    printf "    Show this help\n"
    echo

    printf "%s\n" "$(bold "Arguments:")"

    printf "  %s\n" "$(blue "PHP")"
    printf "    PHP minor version to mark as the default\n"
    echo

    printf "%s\n" "$(bold "Examples:")"
    printf "  zendphpctl set-default 8.1\n"
    printf "  zendphpctl set-default 7.4\n"
    echo

    printf "$(red This command must be run as root!)\n\n$(red DEPRECATED use \"zendphpctl php set-default\" instead)\n"
    echo

  fi
}

php_install_usage() {
  if [[ -n $long_usage ]]; then
    printf "zendphpctl php-install\n\n"
    printf "  Install another PHP version\n  \n  This version will become the default PHP version following installation\n  unless the --not-default flag is provided.\n\n"
  else
    printf "zendphpctl php-install - Install another PHP version\n\n"
  fi

  printf "%s\n" "$(bold "Usage:")"
  printf "  zendphpctl php-install PHP [OPTIONS]\n"
  printf "  zendphpctl php-install --help | -h\n"
  echo

  if [[ -n "$long_usage" ]]; then
    printf "%s\n" "$(bold "Options:")"

    printf "  %s\n" "$(blue "--not-default")"
    printf "    Do not make this version the default following installation\n"
    echo

    printf "  %s\n" "$(blue "--help, -h")"
    printf "    Show this help\n"
    echo

    printf "%s\n" "$(bold "Arguments:")"

    printf "  %s\n" "$(blue "PHP")"
    printf "    PHP minor version to install\n"
    printf "    %s\n" "Allowed: 5.6, 7.1, 7.2, 7.3, 7.4, 8.0, 8.1, 8.2, 8.3, 8.4, 8.5"
    echo

    printf "%s\n" "$(bold "Examples:")"
    printf "  zendphpctl php install 8.1\n"
    printf "  zendphpctl php install 7.4\n"
    echo

    printf "$(red This command must be run as root!)\n\n$(red DEPRECATED use \"zendphpctl php install\" instead)\n"
    echo

  fi
}

php_uninstall_usage() {
  printf "zendphpctl php-uninstall - Uninstall a previously installed PHP version\n\n"

  printf "%s\n" "$(bold "Usage:")"
  printf "  zendphpctl php-uninstall PHP\n"
  printf "  zendphpctl php-uninstall --help | -h\n"
  echo

  if [[ -n "$long_usage" ]]; then
    printf "%s\n" "$(bold "Options:")"

    printf "  %s\n" "$(blue "--help, -h")"
    printf "    Show this help\n"
    echo

    printf "%s\n" "$(bold "Arguments:")"

    printf "  %s\n" "$(blue "PHP")"
    printf "    PHP minor version to uninstall\n"
    echo

    printf "%s\n" "$(bold "Examples:")"
    printf "  zendphpctl php uninstall 8.1\n"
    printf "  zendphpctl php uninstall 7.4\n"
    echo

    printf "$(red This command must be run as root!)\n\n$(red DEPRECATED use \"zendphpctl php uninstall\" instead)\n"
    echo

  fi
}

php_exec_usage() {
  printf "zendphpctl exec - Execute the given PHP script(s) using a selected PHP binary\n\n"

  printf "%s\n" "$(bold "Usage:")"
  printf "  zendphpctl exec [OPTIONS] [--] ARGUMENTS...\n"
  printf "  zendphpctl exec --help | -h\n"
  echo

  if [[ -n "$long_usage" ]]; then
    printf "%s\n" "$(bold "Options:")"

    printf "  %s\n" "$(blue "--php VERSION")"
    printf "    PHP minor version to use; assumes default PHP version (see php set-default)\n    if not provided\n"
    echo

    printf "  %s\n" "$(blue "--help, -h")"
    printf "    Show this help\n"
    echo

    printf "%s\n" "$(bold "Arguments:")"

    echo "  ARGUMENTS..."
    printf "    The script and/or arguments to execute using the selected PHP version\n"
    echo

    printf "%s\n" "$(bold "Examples:")"
    printf "  zendphpctl php exec script.php\n"
    printf "  zendphpctl php exec --php 8.1 test.php\n"
    printf "  zendphpctl php exec --php 7.4 command.php argument and --flags --to-use\n"
    echo

    printf "$(red DEPRECATED use \"zendphpctl php exec\" instead)\n"
    echo

  fi
}

apache_mod_php_install_usage() {
  printf "zendphpctl apache-mod-php-install - Install mod_php for an installed PHP version\n\n"

  printf "%s\n" "$(bold "Usage:")"
  printf "  zendphpctl apache-mod-php-install [PHP]\n"
  printf "  zendphpctl apache-mod-php-install --help | -h\n"
  echo

  if [[ -n "$long_usage" ]]; then
    printf "%s\n" "$(bold "Options:")"

    printf "  %s\n" "$(blue "--help, -h")"
    printf "    Show this help\n"
    echo

    printf "%s\n" "$(bold "Arguments:")"

    printf "  %s\n" "$(blue "PHP")"
    printf "    PHP minor version for which to install mod_php support; assumes default PHP\n    version (see php set-default) if not provided\n"
    echo

    printf "%s\n" "$(bold "Examples:")"
    printf "  zendphpctl apache mod_php install\n"
    printf "  zendphpctl apache mod_php install 8.1\n"
    printf "  zendphpctl apache mod_php install 7.4\n"
    echo

    printf "$(red This command must be run as root!)\n\n$(red DEPRECATED use \"zendphpctl apache mod_php install\" instead)\n"
    echo

  fi
}

apache_mod_php_is_installed_usage() {
  printf "zendphpctl apache-mod-php-is-installed - Determine if mod_php is installed for the given PHP version\n\n"

  printf "%s\n" "$(bold "Usage:")"
  printf "  zendphpctl apache-mod-php-is-installed [PHP]\n"
  printf "  zendphpctl apache-mod-php-is-installed --help | -h\n"
  echo

  if [[ -n "$long_usage" ]]; then
    printf "%s\n" "$(bold "Options:")"

    printf "  %s\n" "$(blue "--help, -h")"
    printf "    Show this help\n"
    echo

    printf "%s\n" "$(bold "Arguments:")"

    printf "  %s\n" "$(blue "PHP")"
    printf "    PHP minor version you are checking for mod_php support; assumes default PHP\n    version (see php set-default) if not provided\n"
    echo

    printf "%s\n" "$(bold "Examples:")"
    printf "  zendphpctl apache mod_php is-installed\n"
    printf "  zendphpctl apache mod_php is-installed 8.1\n"
    printf "  zendphpctl apache mod_php is-installed 7.4\n"
    echo

    printf "$(red DEPRECATED use \"zendphpctl apache mod_php is-installed\" instead)\n"
    echo

  fi
}

apache_mod_php_uninstall_usage() {
  printf "zendphpctl apache-mod-php-uninstall - Uninstall mod_php support for an installed PHP version\n\n"

  printf "%s\n" "$(bold "Usage:")"
  printf "  zendphpctl apache-mod-php-uninstall [PHP]\n"
  printf "  zendphpctl apache-mod-php-uninstall --help | -h\n"
  echo

  if [[ -n "$long_usage" ]]; then
    printf "%s\n" "$(bold "Options:")"

    printf "  %s\n" "$(blue "--help, -h")"
    printf "    Show this help\n"
    echo

    printf "%s\n" "$(bold "Arguments:")"

    printf "  %s\n" "$(blue "PHP")"
    printf "    PHP minor version for which to uninstall mod_php support; assumes default\n    PHP version (see php set-default) if not provided.\n"
    echo

    printf "%s\n" "$(bold "Examples:")"
    printf "  zendphpctl apache mod_php uninstall\n"
    printf "  zendphpctl apache mod_php uninstall 8.1\n"
    printf "  zendphpctl apache mod_php uninstall 7.4\n"
    echo

    printf "$(red This command must be run as root!)\n\n$(red DEPRECATED use \"zendphpctl apache mod_php uninstall\" instead)\n"
    echo

  fi
}

ext_disable_usage() {
  printf "zendphpctl ext-disable - Disable one or more PHP extensions\n\n"

  printf "%s\n" "$(bold "Usage:")"
  printf "  zendphpctl ext-disable [OPTIONS] [--] EXTENSIONS...\n"
  printf "  zendphpctl ext-disable --help | -h\n"
  echo

  if [[ -n "$long_usage" ]]; then
    printf "%s\n" "$(bold "Options:")"

    printf "  %s\n" "$(blue "--php PHP")"
    printf "    PHP minor version for which to disable extension(s); assumes default PHP\n    version (see php set-default) if not provided\n"
    echo

    printf "  %s\n" "$(blue "--sapi SAPI")"
    printf "    Disable an extension only for a given SAPI (e.g. cli, fpm) (DEB only)\n"
    printf "    %s\n" "Allowed: ALL, cli, fpm"
    printf "    %s\n" "Default: ALL"
    echo

    printf "  %s\n" "$(blue "--help, -h")"
    printf "    Show this help\n"
    echo

    printf "%s\n" "$(bold "Arguments:")"

    echo "  EXTENSIONS..."
    printf "    One or more extensions to disable\n"
    echo

    printf "%s\n" "$(bold "Examples:")"
    printf "  zendphpctl ext disable imap\n"
    printf "  zendphpctl ext disable --php 8.1 ldap mysqli redis\n"
    printf "  zendphpctl ext disable --php 7.4 --sapi fpm soap\n"
    echo

    printf "$(red This command must be run as root!)\n\n$(red DEPRECATED use \"zendphpctl ext disable\" instead)\n"
    echo

  fi
}

ext_enable_usage() {
  printf "zendphpctl ext-enable - Enable one or more PHP extensions\n\n"

  printf "%s\n" "$(bold "Usage:")"
  printf "  zendphpctl ext-enable [OPTIONS] [--] EXTENSIONS...\n"
  printf "  zendphpctl ext-enable --help | -h\n"
  echo

  if [[ -n "$long_usage" ]]; then
    printf "%s\n" "$(bold "Options:")"

    printf "  %s\n" "$(blue "--php PHP")"
    printf "    PHP minor version for which to enable extension(s); assumes default PHP\n    version (see php set-default) if not provided\n"
    echo

    printf "  %s\n" "$(blue "--sapi SAPI")"
    printf "    Enable an extension only for a given SAPI (e.g. cli, fpm) (DEB only)\n"
    printf "    %s\n" "Allowed: ALL, cli, fpm"
    printf "    %s\n" "Default: ALL"
    echo

    printf "  %s\n" "$(blue "--help, -h")"
    printf "    Show this help\n"
    echo

    printf "%s\n" "$(bold "Arguments:")"

    echo "  EXTENSIONS..."
    printf "    One or more extensions to enable\n"
    echo

    printf "%s\n" "$(bold "Examples:")"
    printf "  zendphpctl ext enable imap\n"
    printf "  zendphpctl ext enable --php 8.1 ldap mysqli redis\n"
    printf "  zendphpctl ext enable --php 7.4 --fpm soap\n"
    echo

    printf "$(red This command must be run as root!)\n\n$(red DEPRECATED use \"zendphpctl ext enable\" instead)\n"
    echo

  fi
}

ext_install_usage() {
  if [[ -n $long_usage ]]; then
    printf "zendphpctl ext-install\n\n"
    printf "  Install one or more PHP extensions\n  \n  The default behavior is to install existing ZendPHP extension packages if\n  they exist, and otherwise pull the extension from PECL, compile,\n  and install it.\n  \n  Please be aware that:\n  \n  - Some extensions will require additional dependencies in order to compile.\n    It is up to you to identify and install these dependencies.\n  - We do not specify any non-default configure flags. If you have specific\n  flags\n    you want to enable, you will need to manually compile the extension\n  yourself.\n\n"
  else
    printf "zendphpctl ext-install - Install one or more PHP extensions\n\n"
  fi

  printf "%s\n" "$(bold "Usage:")"
  printf "  zendphpctl ext-install [OPTIONS] [--] EXTENSIONS...\n"
  printf "  zendphpctl ext-install --help | -h\n"
  echo

  if [[ -n "$long_usage" ]]; then
    printf "%s\n" "$(bold "Options:")"

    printf "  %s\n" "$(blue "--php PHP")"
    printf "    PHP minor version for which to install extension(s); assumes default PHP\n    version (see php set-default) if not provided\n"
    echo

    printf "  %s\n" "$(blue "--sapi SAPI")"
    printf "    Install an extension only for a given SAPI (e.g. cli, fpm) (DEB only)\n"
    printf "    %s\n" "Allowed: ALL, cli, fpm"
    printf "    %s\n" "Default: ALL"
    echo

    printf "  %s\n" "$(blue "--help, -h")"
    printf "    Show this help\n"
    echo

    printf "%s\n" "$(bold "Arguments:")"

    echo "  EXTENSIONS..."
    printf "    One or more extensions to install. Extensions should be specified\n    with the following format:\n    \n      {priority-}extension{-version}\n    \n    {priority-} is used to indicate loading priority; the default, if not\n    specified, is 20, but some extensions (e.g. Swoole, OpenSwoole) need\n    to be loaded after other extensions (e.g. JSON) and should specify a\n    higher priority number (higher loads later). {-version} can be used\n    to indicate a specific extension version to install. If either\n    {priority-} or {-version} are provided, the command will ALWAYS pull\n    and compile from PECL.\n"
    echo

    printf "%s\n" "$(bold "Examples:")"
    printf "  zendphpctl ext install imap\n"
    printf "  zendphpctl ext install --php 8.1 ldap mysqli redis\n"
    printf "  zendphpctl ext install --php 7.4 60-swoole-4.8.1\n"
    echo

    printf "$(red This command must be run as root!)\n\n$(red DEPRECATED use \"zendphpctl ext install\" instead)\n"
    echo

  fi
}

ext_list_enabled_usage() {
  if [[ -n $long_usage ]]; then
    printf "zendphpctl ext-list-enabled\n\n"
    printf "  Lists extensions currently enabled for the given PHP version\n  \n  Extensions listed as enabled include both packaged extensions, and PECL\n  extensions that have been compiled, installed, and enabled for this\n  machine.\n\n"
  else
    printf "zendphpctl ext-list-enabled - Lists extensions currently enabled for the given PHP version\n\n"
  fi

  printf "%s\n" "$(bold "Usage:")"
  printf "  zendphpctl ext-list-enabled [PHP] [OPTIONS]\n"
  printf "  zendphpctl ext-list-enabled --help | -h\n"
  echo

  if [[ -n "$long_usage" ]]; then
    printf "%s\n" "$(bold "Options:")"

    printf "  %s\n" "$(blue "--fpm")"
    printf "    List extensions enabled only for PHP-FPM (versus CLI) (DEB only)\n"
    echo

    printf "  %s\n" "$(blue "--help, -h")"
    printf "    Show this help\n"
    echo

    printf "%s\n" "$(bold "Arguments:")"

    printf "  %s\n" "$(blue "PHP")"
    printf "    PHP minor version for which to list enabled extensions; uses default (see\n    php set-default) if not provided.\n"
    echo

    printf "%s\n" "$(bold "Examples:")"
    printf "  zendphpctl ext list-enabled\n"
    printf "  zendphpctl ext list-enabled 7.4\n"
    printf "  zendphpctl ext list-enabled 7.4 --fpm\n"
    echo

    printf "$(red DEPRECATED use \"zendphpctl ext list-enabled\" instead)\n"
    echo

  fi
}

ext_list_packages_usage() {
  printf "zendphpctl ext-list-packages\n\n"

  printf "%s\n" "$(bold "Usage:")"
  printf "  zendphpctl ext-list-packages\n"
  printf "  zendphpctl ext-list-packages --help | -h\n"
  echo

  if [[ -n "$long_usage" ]]; then
    printf "%s\n" "$(bold "Options:")"

    printf "  %s\n" "$(blue "--help, -h")"
    printf "    Show this help\n"
    echo

    printf "$(red This command must be run as root!)\n\n$(red DEPRECATED use \"zendphpctl ext list-packages\" instead)\n"
    echo

  fi
}

fpm_config_usage() {
  printf "zendphpctl fpm-config - Configure PHP-FPM\n\n"

  printf "%s\n" "$(bold "Usage:")"
  printf "  zendphpctl fpm-config [PHP]\n"
  printf "  zendphpctl fpm-config --help | -h\n"
  echo

  if [[ -n "$long_usage" ]]; then
    printf "%s\n" "$(bold "Options:")"

    printf "  %s\n" "$(blue "--help, -h")"
    printf "    Show this help\n"
    echo

    printf "%s\n" "$(bold "Arguments:")"

    printf "  %s\n" "$(blue "PHP")"
    printf "    PHP minor version for which to configure FPM support; assumes default PHP\n    version (see php set-default) if not provided\n"
    echo

    printf "%s\n" "$(bold "Examples:")"
    printf "  zendphpctl fpm config\n"
    printf "  zendphpctl fpm config 8.1\n"
    printf "  zendphpctl fpm config 7.4\n"
    echo

    printf "$(red This command must be run as root!)\n\n$(red DEPRECATED use \"zendphpctl fpm config\" instead)\n"
    echo

  fi
}

fpm_install_usage() {
  printf "zendphpctl fpm-install - Install FPM for an installed PHP version\n\n"

  printf "%s\n" "$(bold "Usage:")"
  printf "  zendphpctl fpm-install [PHP]\n"
  printf "  zendphpctl fpm-install --help | -h\n"
  echo

  if [[ -n "$long_usage" ]]; then
    printf "%s\n" "$(bold "Options:")"

    printf "  %s\n" "$(blue "--help, -h")"
    printf "    Show this help\n"
    echo

    printf "%s\n" "$(bold "Arguments:")"

    printf "  %s\n" "$(blue "PHP")"
    printf "    PHP minor version for which to install FPM support; assumes default PHP\n    version (see php set-default) if not provided\n"
    echo

    printf "%s\n" "$(bold "Examples:")"
    printf "  zendphpctl fpm install\n"
    printf "  zendphpctl fpm install 8.1\n"
    printf "  zendphpctl fpm install 7.4\n"
    echo

    printf "$(red This command must be run as root!)\n\n$(red DEPRECATED use \"zendphpctl fpm install\" instead)\n"
    echo

  fi
}

fpm_is_installed_usage() {
  printf "zendphpctl fpm-is-installed - Determine if FPM is installed for the given PHP version\n\n"

  printf "%s\n" "$(bold "Usage:")"
  printf "  zendphpctl fpm-is-installed [PHP]\n"
  printf "  zendphpctl fpm-is-installed --help | -h\n"
  echo

  if [[ -n "$long_usage" ]]; then
    printf "%s\n" "$(bold "Options:")"

    printf "  %s\n" "$(blue "--help, -h")"
    printf "    Show this help\n"
    echo

    printf "%s\n" "$(bold "Arguments:")"

    printf "  %s\n" "$(blue "PHP")"
    printf "    PHP minor version you are checking for FPM support; assumes default PHP\n    version (see php set-default) if not provided\n"
    echo

    printf "%s\n" "$(bold "Examples:")"
    printf "  zendphpctl fpm is-installed\n"
    printf "  zendphpctl fpm is-installed 8.1\n"
    printf "  zendphpctl fpm is-installed 7.4\n"
    echo

    printf "$(red DEPRECATED use \"zendphpctl fpm is-installed\" instead)\n"
    echo

  fi
}

fpm_uninstall_usage() {
  printf "zendphpctl fpm-uninstall - Uninstall FPM for an installed PHP version\n\n"

  printf "%s\n" "$(bold "Usage:")"
  printf "  zendphpctl fpm-uninstall [PHP]\n"
  printf "  zendphpctl fpm-uninstall --help | -h\n"
  echo

  if [[ -n "$long_usage" ]]; then
    printf "%s\n" "$(bold "Options:")"

    printf "  %s\n" "$(blue "--help, -h")"
    printf "    Show this help\n"
    echo

    printf "%s\n" "$(bold "Arguments:")"

    printf "  %s\n" "$(blue "PHP")"
    printf "    PHP minor version for which to uninstall FPM support; assumes default PHP\n    version (see php set-default) if not provided.\n"
    echo

    printf "%s\n" "$(bold "Examples:")"
    printf "  zendphpctl fpm uninstall\n"
    printf "  zendphpctl fpm uninstall 8.1\n"
    printf "  zendphpctl fpm uninstall 7.4\n"
    echo

    printf "$(red This command must be run as root!)\n\n$(red DEPRECATED use \"zendphpctl fpm uninstall\" instead)\n"
    echo

  fi
}

repo_credentials_usage() {
  if [[ -n $long_usage ]]; then
    printf "zendphpctl repo-credentials\n\n"
    printf "  Provide credentials for the ZendPHP package repository on your system,\n  allowing access to LTS editions\n  \n  Both the --account and --password values MUST be provided.\n  \n  $(red If credentials were present previously, this operation will overwrite\n  them!)\n\n"
  else
    printf "zendphpctl repo-credentials - Provide credentials for the ZendPHP package repository on your system, allowing access to LTS editions\n\n"
  fi

  printf "%s\n" "$(bold "Usage:")"
  printf "  zendphpctl repo-credentials [OPTIONS]\n"
  printf "  zendphpctl repo-credentials --help | -h\n"
  echo

  if [[ -n "$long_usage" ]]; then
    printf "%s\n" "$(bold "Options:")"

    printf "  %s\n" "$(blue "--account ACCOUNT (required)")"
    printf "    Account or order identifier associated with your credentials\n"
    echo

    printf "  %s\n" "$(blue "--password PASSWORD (required)")"
    printf "    Password associated with your credentials\n"
    echo

    printf "  %s\n" "$(blue "--help, -h")"
    printf "    Show this help\n"
    echo

    printf "%s\n" "$(bold "Examples:")"
    printf "  zendphpctl repo credentials --account ORDER_ID --password PASSWORD\n"
    echo

    printf "$(red This command must be run as root!)\n\n$(red DEPRECATED use \"zendphpctl repo credentials\" instead)\n"
    echo

  fi
}

repo_install_usage() {
  if [[ -n $long_usage ]]; then
    printf "zendphpctl repo-install\n\n"
    printf "  Install the ZendPHP package repository on your system\n  \n  You may optionally provide your credentials to allow immediate access to LTS\n  editions of ZendPHP. If you provide credentials you MUST provide both the\n  --account and --password flags.\n\n"
  else
    printf "zendphpctl repo-install - Install the ZendPHP package repository on your system\n\n"
  fi

  printf "%s\n" "$(bold "Usage:")"
  printf "  zendphpctl repo-install [OPTIONS]\n"
  printf "  zendphpctl repo-install --help | -h\n"
  echo

  if [[ -n "$long_usage" ]]; then
    printf "%s\n" "$(bold "Options:")"

    printf "  %s\n" "$(blue "--account ACCOUNT")"
    printf "    (Optional) Account or order identifier associated with your credentials\n"
    echo

    printf "  %s\n" "$(blue "--password PASSWORD")"
    printf "    (Optional) Password associated with your credentials\n"
    echo

    printf "  %s\n" "$(blue "--uri URI (repeatable)")"
    printf "    (Optional) Base URI to use instead of https://repos.zend.com/zendphp for the\n    repository setup. Can be specified multiple times to add multiple repository\n    definitions.\n"
    echo

    printf "  %s\n" "$(blue "--help, -h")"
    printf "    Show this help\n"
    echo

    printf "%s\n" "$(bold "Examples:")"
    printf "  zendphpctl repo install\n"
    printf "  zendphpctl repo install --account ORDER_ID --password PASSWORD\n"
    printf "  zendphpctl repo install --uri https://mirror.zend.com/zendphp --uri\n  https://repos.zend.com/zendphp\n"
    echo

    printf "$(red This command must be run as root!)\n\n$(red DEPRECATED use \"zendphpctl repo install\" instead)\n"
    echo

  fi
}

repo_uninstall_usage() {
  if [[ -n $long_usage ]]; then
    printf "zendphpctl repo-uninstall\n\n"
    printf "  Uninstall the ZendPHP package repository from your system\n  \n  NOTE: this action DOES NOT remove previously installed ZendPHP packages;\n  it only removes the package repository from your system, preventing\n  further updates and/or installations.\n\n"
  else
    printf "zendphpctl repo-uninstall - Uninstall the ZendPHP package repository from your system\n\n"
  fi

  printf "%s\n" "$(bold "Usage:")"
  printf "  zendphpctl repo-uninstall\n"
  printf "  zendphpctl repo-uninstall --help | -h\n"
  echo

  if [[ -n "$long_usage" ]]; then
    printf "%s\n" "$(bold "Options:")"

    printf "  %s\n" "$(blue "--help, -h")"
    printf "    Show this help\n"
    echo

    printf "%s\n" "$(bold "Examples:")"
    printf "  zendphpctl repo uninstall\n"
    echo

    printf "$(red This command must be run as root!)\n\n$(red DEPRECATED use \"zendphpctl repo uninstall\" instead)\n"
    echo

  fi
}

zendhq_token_usage() {
  if [[ -n $long_usage ]]; then
    printf "zendphpctl zendhq-token\n\n"
    printf "  Reset the ZendHQ service token, used to authenticate websocket and GUI clients\n  with ZendHQ.\n\n"
  else
    printf "zendphpctl zendhq-token - Reset the ZendHQ service token, used to authenticate websocket and GUI clients\n\n"
  fi

  printf "%s\n" "$(bold "Usage:")"
  printf "  zendphpctl zendhq-token TOKEN [OPTIONS]\n"
  printf "  zendphpctl zendhq-token --help | -h\n"
  echo

  if [[ -n "$long_usage" ]]; then
    printf "%s\n" "$(bold "Options:")"

    printf "  %s\n" "$(blue "--no-restart")"
    printf "    Do not restart ZendHQ following token update\n"
    echo

    printf "  %s\n" "$(blue "--help, -h")"
    printf "    Show this help\n"
    echo

    printf "%s\n" "$(bold "Arguments:")"

    printf "  %s\n" "$(blue "TOKEN")"
    printf "    New token to use\n"
    echo

    printf "%s\n" "$(bold "Examples:")"
    printf "  zendphpctl zendhq token foobar\n"
    echo

    printf "$(red This command must be run as root!)\n\n$(red DEPRECATED use \"zendphpctl zendhq token\" instead)\n"
    echo

  fi
}

zray_plugin_install_usage() {
  if [[ -n $long_usage ]]; then
    printf "zendphpctl zray-plugins-install\n\n"
    printf "  Install the Z-Ray plugins package, containing Zend-maintained plugins to\n  the Z-Ray application insight tool.\n\n"
  else
    printf "zendphpctl zray-plugins-install - Install the Z-Ray plugins package, containing Zend-maintained plugins to\n\n"
  fi

  printf "%s\n" "$(bold "Usage:")"
  printf "  zendphpctl zray-plugins-install [OPTIONS]\n"
  printf "  zendphpctl zray-plugins-install --help | -h\n"
  echo

  if [[ -n "$long_usage" ]]; then
    printf "%s\n" "$(bold "Options:")"

    printf "  %s\n" "$(blue "--php PHP")"
    printf "    PHP minor version for which to disable extension(s); assumes default PHP\n    version (see php set-default) if not provided\n"
    echo

    printf "  %s\n" "$(blue "--help, -h")"
    printf "    Show this help\n"
    echo

    printf "$(red This command must be run as root!)\n\n$(red DEPRECATED use \"zendphpctl zray plugin install\" instead)\n"
    echo

  fi
}

zray_plugin_list_usage() {
  if [[ -n $long_usage ]]; then
    printf "zendphpctl zray-plugins-list\n\n"
    printf "  List installed Z-Ray plugins, optionally detailing only those enabled.\n\n"
  else
    printf "zendphpctl zray-plugins-list - List installed Z-Ray plugins, optionally detailing only those enabled.\n\n"
  fi

  printf "%s\n" "$(bold "Usage:")"
  printf "  zendphpctl zray-plugins-list [OPTIONS]\n"
  printf "  zendphpctl zray-plugins-list --help | -h\n"
  echo

  if [[ -n "$long_usage" ]]; then
    printf "%s\n" "$(bold "Options:")"

    printf "  %s\n" "$(blue "--enabled")"
    printf "    List only enabled plugins\n"
    echo

    printf "  %s\n" "$(blue "--help, -h")"
    printf "    Show this help\n"
    echo

    printf "%s\n" "$(bold "Examples:")"
    printf "  zendphpctl zray plugin list\n"
    printf "  zendphpctl zray plugin list --enabled\n"
    echo

    printf "$(red DEPRECATED use \"zendphpctl zray plugin list\" instead)\n"
    echo

  fi
}

zray_plugin_disable_usage() {
  printf "zendphpctl zray-plugin-disable - Disable one or more Z-Ray plugins.\n\n"

  printf "%s\n" "$(bold "Usage:")"
  printf "  zendphpctl zray-plugin-disable [--] PLUGINS...\n"
  printf "  zendphpctl zray-plugin-disable --help | -h\n"
  echo

  if [[ -n "$long_usage" ]]; then
    printf "%s\n" "$(bold "Options:")"

    printf "  %s\n" "$(blue "--help, -h")"
    printf "    Show this help\n"
    echo

    printf "%s\n" "$(bold "Arguments:")"

    echo "  PLUGINS..."
    printf "    One or more plugins to disable\n"
    echo

    printf "%s\n" "$(bold "Examples:")"
    printf "  zendphpctl zray plugin disable composer\n"
    printf "  zendphpctl zray plugin disable composer symfony\n"
    echo

    printf "$(red This command must be run as root!)\n\n$(red DEPRECATED use \"zendphpctl zray plugin disable\" instead)\n"
    echo

  fi
}

zray_plugin_enable_usage() {
  printf "zendphpctl zray-plugin-enable - Enable one or more Z-Ray plugins.\n\n"

  printf "%s\n" "$(bold "Usage:")"
  printf "  zendphpctl zray-plugin-enable [--] PLUGINS...\n"
  printf "  zendphpctl zray-plugin-enable --help | -h\n"
  echo

  if [[ -n "$long_usage" ]]; then
    printf "%s\n" "$(bold "Options:")"

    printf "  %s\n" "$(blue "--help, -h")"
    printf "    Show this help\n"
    echo

    printf "%s\n" "$(bold "Arguments:")"

    echo "  PLUGINS..."
    printf "    One or more plugins to enable\n"
    echo

    printf "%s\n" "$(bold "Examples:")"
    printf "  zendphpctl zray plugin enable composer\n"
    printf "  zendphpctl zray plugin enable composer symfony\n"
    echo

    printf "$(red This command must be run as root!)\n\n$(red DEPRECATED use \"zendphpctl zray plugin enable\" instead)\n"
    echo

  fi
}

normalize_input() {
  local arg passthru flags
  passthru=false

  while [[ $# -gt 0 ]]; do
    arg="$1"
    if [[ $passthru == true ]]; then
      input+=("$arg")
    elif [[ $arg =~ ^(--[a-zA-Z0-9_\-]+)=(.+)$ ]]; then
      input+=("${BASH_REMATCH[1]}")
      input+=("${BASH_REMATCH[2]}")
    elif [[ $arg =~ ^(-[a-zA-Z0-9])=(.+)$ ]]; then
      input+=("${BASH_REMATCH[1]}")
      input+=("${BASH_REMATCH[2]}")
    elif [[ $arg =~ ^-([a-zA-Z0-9][a-zA-Z0-9]+)$ ]]; then
      flags="${BASH_REMATCH[1]}"
      for ((i = 0; i < ${#flags}; i++)); do
        input+=("-${flags:i:1}")
      done
    elif [[ "$arg" == "--" ]]; then
      passthru=true
      input+=("$arg")
    else
      input+=("$arg")
    fi

    shift
  done
}

apk_init_credentials() {
    if [[ -f /etc/apk/zendrepo.rc ]]; then
        # shellcheck disable=SC1091
        source "/etc/apk/zendrepo.rc"
        if [[ -n "${HTTP_AUTH}" ]]; then
            export HTTP_AUTH
        fi
    fi
}

apk_is_default_php_version() {
    local php_version=$1
    local binary

    binary="$(basename "$(which "$(readlink "$(command -v php)")")")"
    pattern="^php${php_version//[![:digit:]]/}zend\$"
    if [[ "${binary}" =~ $pattern ]]; then
        return 0
    fi

    return 1
}


enable_auto_colors() {
  if [[ -z ${NO_COLOR+x} && ! -t 1 ]]; then
    NO_COLOR=1
  fi
}

print_in_color() {
  local color="$1"
  shift
  if [[ "${NO_COLOR:-}" == "" ]]; then
    printf "$color%b\e[0m\n" "$*"
  else
    printf "%b\n" "$*"
  fi
}

red() { print_in_color "\e[31m" "$*"; }
green() { print_in_color "\e[32m" "$*"; }
yellow() { print_in_color "\e[33m" "$*"; }
blue() { print_in_color "\e[34m" "$*"; }
magenta() { print_in_color "\e[35m" "$*"; }
cyan() { print_in_color "\e[36m" "$*"; }
black() { print_in_color "\e[30m" "$*"; }
white() { print_in_color "\e[37m" "$*"; }

bold() { print_in_color "\e[1m" "$*"; }
underlined() { print_in_color "\e[4m" "$*"; }

red_bold() { print_in_color "\e[1;31m" "$*"; }
green_bold() { print_in_color "\e[1;32m" "$*"; }
yellow_bold() { print_in_color "\e[1;33m" "$*"; }
blue_bold() { print_in_color "\e[1;34m" "$*"; }
magenta_bold() { print_in_color "\e[1;35m" "$*"; }
cyan_bold() { print_in_color "\e[1;36m" "$*"; }
black_bold() { print_in_color "\e[1;30m" "$*"; }
white_bold() { print_in_color "\e[1;37m" "$*"; }

red_underlined() { print_in_color "\e[4;31m" "$*"; }
green_underlined() { print_in_color "\e[4;32m" "$*"; }
yellow_underlined() { print_in_color "\e[4;33m" "$*"; }
blue_underlined() { print_in_color "\e[4;34m" "$*"; }
magenta_underlined() { print_in_color "\e[4;35m" "$*"; }
cyan_underlined() { print_in_color "\e[4;36m" "$*"; }
black_underlined() { print_in_color "\e[4;30m" "$*"; }
white_underlined() { print_in_color "\e[4;37m" "$*"; }


create_installable_extension_list() {
    local version=$1

    if is_rhel_compatible || is_ibmi_compatible; then
        create_installable_extension_list_for_rpm "${version}"
    elif is_deb_compatible; then
        create_installable_extension_list_for_deb "${version}"
    elif is_apk_compatible; then
        create_installable_extension_list_for_apk "${version}"
    fi
}


function create_installable_extension_list_for_apk() {
    local php_version=$1
    local basematch="php${php_version//[![:digit:]]/}zend"

    apk update > /dev/null 2>&1

    apk list -a "${basematch}-*" 2>&1 | \
        grep -v -E "\-apache2-|-cgi-|-common-|-dev-|-doc-|-fpm-|-pear-" | \
        cut -d' ' -f1 | \
        sed "s/${basematch}-//g" | \
        sed -E "s/-\d+\.\d+\.\d+.*//g" | \
        sed 's/pecl-//g' | \
        sort
}


function create_installable_extension_list_for_deb() {
    local php_version=$1
    apt-get update -y > /dev/null 2>&1
    apt-cache search --names-only "^php${php_version}-zend-"| \
        cut -d' ' -f1 | \
        grep -vE 'zend-(dev|fpm|cgi|cli|common)$' | \
        grep -vE '^lib(apache|php)' | \
        grep -vE '\-dbgsym$' | \
        sed "s/php${php_version}-zend-//g" | \
        sort
}


create_installable_extension_list_for_rpm() {
    local version=${1//[![:digit:]]/}
    repoquery -q --qf="%{name}" "php${version}zend-php-"* | \
        grep -v "debuginfo" | \
        grep -v "devel" | \
        grep -v "dbg" | \
        grep -vE 'zend-php-(embedded|fpm|cgi|cli|common|opcache)$' | \
        grep -v 'zend-php$' | \
        sed "s/php${version}zend-php-//g" | \
        sed 's/pecl-//g' | \
        sort
}


detect_current_php_version() {
    local php=$1

    if [[ -z "${php}" ]]; then
        echo ""
    else
        "${php}" -r 'echo PHP_MAJOR_VERSION . "." . PHP_MINOR_VERSION;'
    fi
}


display_version_details_as_json() {
    local version=$1
    local full_version=$2
    local extension_dir=$3
    local configs=()
    local sapis=()
    local sapiJson="{}"
    local binary
    local configJson
    local logfile
    local sapi

    binary="$(get_php_binary "${version}")"
    mapfile -t sapis < <(get_installed_sapis "${version}")

    for sapi in "${sapis[@]}"; do
        binary=""
        configs=()
        configJson="[]"
        phpIni=""

        case $sapi in
            cli)
                binary="$(get_php_binary "${version}")"
                ;;
            fpm)
                binary="$(get_fpm_binary "${version}")"
                ;;
        esac

        logfile="$(get_error_log_setting "${sapi}" "${phpIni}")"
        if [[ "${sapi}" == "fpm" && $(is_rhel_compatible) ]]; then
            logfile="/opt/zend/php${version//[![:digit:]]/}zend/root${logfile}"
        fi

        configs=()
        for config in $(get_ini_location "${version}" "${sapi}"); do
            configs+=( "${config}" )
            if [[ "${config}" =~ \.ini$ ]]; then
                phpIni="${config}"
            fi
        done
        configJson="$(echo "${configJson}" | jq -nR --argjson config "$(echo "${configs[*]}" | jq -nR '[ inputs | split(" ") | . ] | add')" ". |= .+ \$config")"

        if [[ -n $binary ]]; then
            if [[ -n $logfile ]]; then
                # shellcheck disable=SC2016
                sapiJson="$(echo "${sapiJson}" | jq --arg binary "${binary}" --arg logfile "${logfile}" --argjson config "${configJson}" "$(printf '. += {"%s": {"binary": $binary, "logs": $logfile, "config": $config}}' "${sapi}")")"
            else
                # shellcheck disable=SC2016
                sapiJson="$(echo "${sapiJson}" | jq --arg binary "${binary}" --argjson config "${configJson}" "$(printf '. += {"%s": {"binary": $binary, "config": $config}}' "${sapi}")")"
            fi
        else
            if [[ -n $logfile ]]; then
                # shellcheck disable=SC2016
                sapiJson="$(echo "${sapiJson}" | jq --arg logfile "${logfile}" --argjson config "${configJson}" "$(printf '. += {"%s": {"logs": $logfile, "config": $config}}' "${sapi}")")"
            else
                # shellcheck disable=SC2016
                sapiJson="$(echo "${sapiJson}" | jq --argjson config "${configJson}" "$(printf '. += {"%s": {"config": $config}}' "${sapi}")")"
            fi
        fi
    done

    jq --null-input --arg php "${version}" --arg installed "${full_version}" --arg extension_dir "${extension_dir}" --argjson sapis "${sapiJson}" '{"php": $php, "installed_version": $installed, "extension_dir": $extension_dir, "sapis": $sapis}'
}


display_version_details_as_text() {
    local version=$1
    local full_version=$2
    local extension_dir=$3
    local sapis=()
    local config
    local logfile
    local phpIni
    local sapi

    mapfile -t sapis < <(get_installed_sapis "${version}")

    green "${version}:"
    echo "- $(blue Installed version): ${full_version}"
    echo "- $(blue Extension directory): ${extension_dir}"

    for sapi in "${sapis[@]}"; do
        phpIni=""
        echo "- $(blue "${sapi} (SAPI):")"

        case $sapi in
            cli)
                echo "  - $(blue Binary): $(get_php_binary "${version}")"
                ;;
            fpm)
                echo "  - $(blue Binary): $(get_fpm_binary "${version}")"
                ;;
        esac

        logfile="$(get_error_log_setting "${sapi}" "${phpIni}")"
        if [[ "${sapi}" == "fpm" ]]; then
            if is_rhel_compatible; then
                logfile="/opt/zend/php${version//[![:digit:]]/}zend/root${logfile}"
            elif is_ibmi_compatible; then
                logfile="/QOpenSys/var/log/php-fpm.log"
            fi
        fi

        if [[ -n "${logfile}" ]]; then
            echo "  - $(blue "Error log(s):") ${logfile}"
        fi

        echo "  - $(blue Configuration):"
        for config in $(get_ini_location "${version}" "${sapi}"); do
            echo "    - ${config}"
            if [[ "${config}" =~ \.ini$ ]]; then
                phpIni="${config}"
            fi
        done
    done
}

ensure_zray_plugin_tree() {
    local base_tree="/opt/zend/zendphp/plugins"
    local paths=( "available" "enabled" )
    local path

    for path in "${paths[@]}"; do
        if [[ ! -d "${base_tree}/${path}" ]]; then
            mkdir -p "${base_tree}/${path}"
        fi
    done
}

filter_is_not_ibm_i() {
    if is_ibmi_compatible; then
        red "This command cannot be run on IBM i."
    fi
}

filter_is_root() {
    if is_ibmi_compatible; then
        # IBM i is an odd one with authorities, and the best way to check is if ProdData exists
        test -w /QOpenSys/QIBM/ProdData || echo "This command must be run with *ALLOBJ authority!"
    else
        [ "${EUID:-$(id -u)}" -eq 0 ] || echo "This command must be run as root!"
    fi
}

filter_is_valid_os() {
    # shellcheck disable=SC2078
    if [[ ! is_rhel_compatible && ! is_deb_compatible && ! is_apk_compatible && ! is_ibmi_compatible ]]; then
        red "This does not appear to be a supported ZendPHP system; please visit https://help.zend.com/zendphp/current/content/introduction/supported_platforms.htm"
    fi
}


get_error_log_setting() {
    local sapi=$1
    local phpIni=$2
    local logfile=""

    if [[ -n "${phpIni}" ]]; then
        set +e
        logfile="$(grep -P '^\s*error_log' "${phpIni}")"
        set -e
    fi

    if [[ -n "${logfile}" ]]; then
        echo "${logfile}" | awk -F '=' '{ print $2 }' | awk '{ gsub(/^[ ]+|[ ]+$/, ""); print }'
    else
        case $sapi in
            cli)
                echo "STDERR"
                ;;
            apache)
                echo "Apache error log"
                ;;
            fpm)
                echo "/var/log/php-fpm.log"
                ;;
            *)
                echo ""
                ;;
        esac
    fi
}


get_ext_load_directive() {
    case "$1" in
    xdebug|opcache|zendhq) echo "zend_extension" ;;
    *) echo "extension" ;;
    esac
}

get_fpm_binary() {
    local version=$1

    set +e

    if is_rhel_compatible; then
        echo "/opt/zend/php${version//[![:digit:]]/}zend/root/usr/sbin/php-fpm"
    elif is_ibmi_compatible; then
        echo "/QOpenSys/pkgs/sbin/php-fpm-${version//[![:digit:]]/}zend"
    elif is_deb_compatible; then
        echo "/usr/sbin/php-fpm${version}-zend"
    elif is_apk_compatible; then
        echo "/usr/bin/php-fpm${version//[![:digit:]]/}zend"
    fi

    set -e
}

get_ibmi_repo_template() {
    local base_uri="${1:-https://repos.zend.com/zendphp}"
    local name_suffix="${2:-}"
    local os_version="$3"
    local auth_block="$4"

    echo "[zendphp${name_suffix}]
name=ZendPHP PHP Runtimes for IBM i (${os_version}; ppc64)
baseurl=${base_uri}/rpm_ibmi/ppc64/
enabled=1
gpgcheck=0
sslverify=0"
    [ -n "${auth_block}" ] && echo "${auth_block}" || true
    echo ''
}

get_ibmi_version() {
    uname -a | awk '{print $4 "." $3}'
}


get_ini_location() {
    local version=$1
    local sapi=$2
    local binary

    case $sapi in
        cli)
            binary="$(get_php_binary "${version}")"
            "${binary}" --ini | grep "Loaded Configuration File" | sed -E 's/Loaded Configuration File:\s+//'
            ;;

        fpm)
            if is_rhel_compatible; then
                binary="$(get_php_binary "${version}")"

                "${binary}" --ini | grep "Loaded Configuration File" | sed -E 's/Loaded Configuration File:\s+//'
                echo "/etc/opt/zend/php${version//[![:digit:]]/}zend/php-fpm.conf"
            elif is_ibmi_compatible; then
                echo "/QOpenSys/etc/php/${version//[![:digit:]]/}zend/php-fpm.conf"
            elif is_deb_compatible; then
                echo "/etc/php/${version}-zend/fpm/php.ini"
                echo "/etc/php/${version}-zend/fpm/php-fpm.conf"
            elif is_apk_compatible; then
                echo "/etc/php/${version//[![:digit:]]/}zend/php-fpm.conf"
            fi
            ;;
        apache)
            if is_rhel_compatible; then
                echo "/etc/opt/zend/php${version//[![:digit:]]/}zend/php.ini"
            elif is_ibmi_compatible; then
                echo "/QOpenSys/etc/php/${version//[![:digit:]]/}zend/php.ini"
            elif is_deb_compatible; then
                echo "/etc/php/${version}-zend/apache2/php.ini"
            elif is_apk_compatible; then
                echo "/etc/php/${version//[![:digit:]]/}zend/php.ini"
            fi
            ;;
    esac
}


get_installed_sapis() {
    local version=$1

    if is_mod_php_installed "${version}"; then
        echo "apache"
    fi

    if is_cli_installed "${version}"; then
        echo "cli"
    fi

    if is_fpm_installed "${version}"; then
        echo "fpm"
    fi
}

get_installed_versions() {
    if is_rhel_compatible; then
        yum list installed 2>&1 | grep -P 'php\d+zend-php-common\.' | awk '{print $2}' | sed -rn 's/^([0-9]+\.[0-9]+).*$/\1/gp' | tr "\n" " " | sed -r 's/ *$//'
    elif is_ibmi_compatible; then
        yum list installed 2>&1 | perl -nl -e'print if m{php\d+zend-php-common\.}' | awk '{print $2}' | sed -rn 's/^([0-9]+\.[0-9]+).*$/\1/gp' | tr "\n" " " | sed -r 's/ *$//'
    elif is_deb_compatible; then
        dpkg-query -f '${Package}\n' -W | grep -P 'php\d+\.\d+-zend-common' | sed -rn 's/php([0-9]+\.[0-9]+)-zend-common/\1/gp' | tr "\n" " " | sed -r 's/ *$//'
    elif is_apk_compatible; then
        apk list -I 2>&1 | grep -v "^WARNING" | grep -E "php[[:digit:]]+zend-[[:digit:]]+.[[:digit:]]+" | awk '{print $1}' | sed -rn 's/^php[0-9]+zend-([0-9]+\.[0-9]+).*$/\1/gp'
    fi
}

get_php_binary() {
    set +e

    if [[ $# -eq 0 ]]; then
        command -v php
    else
        local version=$1
        if is_rhel_compatible; then
            echo "/opt/zend/php${version//[![:digit:]]/}zend/root/usr/bin/php"
        elif is_ibmi_compatible; then
            echo "/QOpenSys/pkgs/bin/php-${version//[![:digit:]]/}zend"
        elif is_deb_compatible; then
            echo "/usr/bin/php${version}-zend"
        elif is_apk_compatible; then
            echo "/usr/bin/php${version//[![:digit:]]/}zend"
        else
            command -v php
        fi
    fi

    set -e
}

get_rhel_os_name() {
    if [[ -f /etc/os-release ]];then
        local os_name
        os_name=$(grep "^NAME" /etc/os-release | cut -f2 -d'=' | sed -E -e 's/"//g' | cut -f1 -d' ')
        if [[ "${os_name}" == "Red" ]];then
            os_name="RHEL"
        fi
        echo "${os_name}"
    else
        echo "CentOS"
    fi
}

get_rhel_repo_template() {
    local arch
    arch="$(uname -m)"
    local repokey="$1"
    local base_uri="${2:-https://repos.zend.com/zendphp}"
    local name_suffix="${3:-}"
    local os_version="$4"
    local auth_block="$5"

    echo "[zendphp${name_suffix}]
name=ZendPHP PHP Runtimes${name_suffix} for Linux (CentOS/RHEL ${os_version}; ${arch})
baseurl=${base_uri}/rpm_centos${os_version}/${arch}/
enabled=1
gpgcheck=1
gpgkey=https://repos.zend.com/${repokey}"
    [ -n "${auth_block}" ] && echo "${auth_block}" || true
    # We used to have an extra noarch repository. This is not needed anymore as main repo
    # now contains all packages in single index
    echo ""
}

get_rhel_version() {
    if [[ -f /etc/os-release ]];then
        local release_info
        release_info=$(grep "VERSION_ID" /etc/os-release | sed -E 's/[^0-9.]//g' | cut -f1 -d'.')
        echo "${release_info//}"
    else
        echo "6"
    fi
}

install_build_tools_for_apk() {
    local php_version=${1//[![:digit:]]/}
    if [[ ! -f "/usr/include/php${php_version}zend" ]]; then
        green "Installing php dev tools..."
        apk_init_credentials
        apk add "php${php_version}zend-dev" "make" "build-base"
    fi
}

install_build_tools_for_deb() {
    local installed
    local php_version=$1

    installed=$(command -v "phpize${php_version}-zend" || true)
    if [[ -z "${installed}" ]]; then
        green "Installing php dev tools..."
        apt-get install -y "php${php_version}-zend-dev" > /dev/null 2>&1
    fi
}

install_build_tools_for_ibmi() {
    local php_version=${1//[![:digit:]]/}
    if [[ ! -f "/QOpenSys/pkgs/bin/phpize-${php_version}zend" ]]; then
        green "Installing php dev tools..."
        yum install -y "php${php_version}zend-php-devel" "make"
    fi
}

install_build_tools_for_rhel() {
    local php_version=${1//[![:digit:]]/}
    if [[ ! -f "/opt/zend/php${php_version}zend/root/usr/include/php/${php_version}zend" ]]; then
        local installer
        installer=$(rhel_installer)

        green "Installing php dev tools..."
        "${installer}" install -y "php${php_version}zend-php-devel" "make"
    fi
}

install_epel() {
    local os
    local os_version
    local installer

    os="$(get_rhel_os_name)"
    os_version="$(get_rhel_version)"
    installer=$(rhel_installer)

    if [[ "${os_version}" -gt 7 ]];then
        case $os in
        "CentOS")
            find /etc/yum.repos.d/ -type f -iname '*PowerTools*' -exec sed -i -e 's/^enabled=0/enabled=1/' '{}' \;
            "${installer}" -y install epel-release
            ;;
        "Oracle")
            find /etc/yum.repos.d/ -type f -iname '*PowerTools*' -exec sed -i -e 's/^enabled=0/enabled=1/' '{}' \;
            "${installer}" -y install "oracle-epel-release-el${os_version}"
            ;;
        "RHEL")
            "${installer}" install -y "https://dl.fedoraproject.org/pub/epel/epel-release-latest-${os_version}.noarch.rpm"
            "${installer}" -y install epel-release
            ;;
        *)
            "${installer}" -y install epel-release
	    ;;
        esac

    else
        case $os in
        "Amazon")
            amazon-linux-extras install epel -y
            ;;
        "CentOS")
            "${installer}" -y install epel-release
            ;;
        "Oracle")
            "${installer}" -y install oracle-epel-release-el7 scl-utils
            ;;
        "RHEL")
            "${installer}" install -y https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm
            "${installer}" -y install epel-release
            ;;
        esac
    fi
}

install_extension() {
    local phpize=$1
    local php_config=$2
    local name=$3
    local ext_version=$4
    local working_dir="${PWD}"
    local build_dir="/tmp/${name}"

    local url="https://pecl.php.net/get/${name}"
    if [[ "${ext_version}" != "-" ]]; then
        url="${url}-${ext_version}.tgz"
    fi

    green "Preparing build directory"
    mkdir -p "${build_dir}"
    cd "${build_dir}" || return 1

    green "Downloading ${name} from PECL via ${url}"
    curl -L -s -o "${name}.tgz" "${url}"

    tar xzf "${name}.tgz" --strip-components=1 --no-same-owner || {
        red "Invalid package archive; cannot continue. Please check ${build_dir}" >&2
        return 2
    }

    green "Compiling and installing ${name}"

    blue "- Running phpize"
    "${phpize}" || { red "phpize failed; see logs for details" >&2 ; return 3 ; }

    blue "- Running configure"
    ./configure --with-php-config="${php_config}" || {
        red "configure failed; see logs for details" >&2
        return 3
    }

    blue "- Running make"
    make || {
        red "make failed; see logs for details" >&2
        return 3
    }

    blue "- Installing"
    make install || {
        red "Installation failed; see logs for details" >&2
        return 3
    }

    cd "${working_dir}" || {
        red "Unable to return to working directory" >&2
        return 1
    }

    blue "- Removing build dir"
    rm -rf "${build_dir}" || {
        red "Unable to remove build directory" >&2
    }
}

install_extension_for_apk() {
    local php_version=$1
    local name=$2
    local priority=$3
    local ext_version=$4
    local suffix="${php_version//[![:digit:]]/}zend"

    install_build_tools_for_apk "${php_version}"

    if install_extension "/usr/bin/phpize${suffix}" "/usr/bin/php-config${suffix}" "${name}" "${ext_version}"; then
        green "Creating module configuration file"
        echo "$(get_ext_load_directive ${name})=${name}.so" > "/etc/php/${suffix}/conf.d/${priority}_${name}.ini"
        green "Extension ${name} installed"
    fi
}

install_extension_for_deb() {
    local php_version=$1
    local name=$2
    local priority=$3
    local ext_version=$4

    install_build_tools_for_deb "${php_version}"

    if install_extension "phpize${php_version}-zend" "/usr/bin/php-config${php_version}-zend" "${name}" "${ext_version}"; then
        green "Creating module configuration file"
        echo "; priority=${priority}" > "/etc/php/${php_version}-zend/mods-available/${name}.ini"
        echo "$(get_ext_load_directive ${name})=${name}.so" >> "/etc/php/${php_version}-zend/mods-available/${name}.ini"
        green "Extension ${name} installed; call zendphpctl ext-enable to enable it for one or more SAPIs"
    fi
}

install_extension_for_ibmi() {
    local php_version=$1
    local name=$2
    local priority=$3
    local ext_version=$4

    install_build_tools_for_ibmi "${php_version}"
    export CFLAGS="-O3 -maix64 -pthread"
    export CXXFLAGS="-O3 -maix64 -pthread"
    export LDFLAGS="-Wl,-bbigtoc -Wl,-brtl -Wl,-blibpath:/QOpenSys/pkgs/lib:/usr/lib:/lib -Wl,-b64 -lm -maix64 -pthread"

    if install_extension "/QOpenSys/pkgs/bin/phpize-${php_version//[![:digit:]]/}zend" "/QOpenSys/pkgs/bin/php-config-${php_version//[![:digit:]]/}zend" "${name}" "${ext_version}"; then
        green "Creating module configuration file"
        echo "$(get_ext_load_directive ${name})=${name}.so" > "/QOpenSys/etc/php/${php_version//[![:digit:]]/}zend/conf.d/${priority}-${name}.ini"
        green "Extension ${name} installed"
    fi
}

install_extension_for_rhel() {
    local php_version=$1
    local name=$2
    local priority=$3
    local ext_version=$4

    install_build_tools_for_rhel "${php_version}"

    if install_extension "/opt/zend/php${php_version//[![:digit:]]/}zend/root/bin/phpize" "/opt/zend/php${php_version//[![:digit:]]/}zend/root/bin/php-config" "${name}" "${ext_version}"; then
        green "Creating module configuration file"
        echo "$(get_ext_load_directive ${name})=${name}.so" > "/etc/opt/zend/php${php_version//[![:digit:]]}zend/php.d/${priority}-${name}.ini"
        green "Extension ${name} installed"
    fi
}

is_apk_compatible() {
    if [ -f /etc/os-release ];then
        local release_info

        release_info=$(cat /etc/os-release)
        if [[ "${release_info}" =~ NAME\=\"(?!Alpine) ]]; then
            return 1
        fi

        if [[ "${release_info}" =~ VERSION_ID=3\.(16|18|20|22|24) ]]; then
            return 0
        else
            # Versions other than 3.16, 3.18, 3.20, 3.22 and 3.24 are not currently supported
            return 1
        fi
    else
        return 1
    fi
}


is_cli_installed() {
    local php_version=$1
    local installer
    local packages
    local pattern

    if is_rhel_compatible || is_ibmi_compatible; then
        if is_ibmi_compatible; then
            installer=yum
        else
            installer="$(rhel_installer)"
        fi

        pattern="php${php_version//[![:digit:]]/}zend-php-cli"

        packages=$("${installer}" list installed 2>&1)
        if [[ "${packages}" =~ $pattern ]]; then
            return 0
        fi
    elif is_deb_compatible; then
        pattern="ii[[:space:]]+php${php_version}-zend-cli"

        packages=$(dpkg-query -l '*-zend-cli' 2>&1)
        if [[ "${packages}" =~ $pattern ]]; then
            return 0
        fi
    elif is_apk_compatible; then
        pattern="php${php_version//[![:digit:]]/}zend-[[:digit:]]+.[[:digit:]]+"
        packages=$(apk list -I 2>&1)
        if [[ "${packages}" =~ $pattern ]]; then
            return 0
        fi
    fi

    return 1
}

is_deb_compatible() {
    if [ -f /etc/os-release ];then
        local release_info

        release_info=$(cat /etc/os-release)
        [[ "${release_info}" =~ NAME\=\"(Debian|Ubuntu) ]] && return 0 || return 1
    else
        return 1
    fi
}

is_epel_enabled() {
    local installer

    installer=$(rhel_installer)

    if "${installer}" repolist | grep -q -E '^epel'; then
        return 0
    else
        return 1
    fi
}


is_fpm_installed() {
    local php_version=$1
    local installer
    local packages
    local pattern

    if is_rhel_compatible || is_ibmi_compatible; then
        if is_ibmi_compatible; then
            installer=yum
        else
            installer="$(rhel_installer)"
        fi

        pattern="php${php_version//[![:digit:]]/}zend-php-fpm"

        packages=$("${installer}" list installed 2>&1)
        if [[ "${packages}" =~ $pattern ]]; then
            return 0
        fi
    elif is_deb_compatible; then
        pattern="ii[[:space:]]+php${php_version}-zend-fpm"

        packages=$(dpkg-query -l '*-zend-fpm' 2>&1)
        if [[ "${packages}" =~ $pattern ]]; then
            return 0
        fi
    elif is_apk_compatible; then
        pattern="php${php_version//[![:digit:]]/}zend-fpm"
        packages=$(apk list -I 2>&1)
        if [[ "${packages}" =~ $pattern ]]; then
            return 0
        fi
    fi

    return 1
}

is_ibmi_compatible() {
    [[ "$(uname)" == "OS400" ]] && return 0 || return 1
}

is_installable_apk_package() {
    local php_version=$1
    local ext=$2
    local basematch="php${php_version//[![:digit:]]/}zend"

    apk update > /dev/null 2>&1

    apk list -a "${basematch}-*" 2>&1 | \
        grep -v -E "\-apache2-|-cgi-|-common-|-dev-|-doc-|-fpm-|-pear-" | \
        cut -d' ' -f1 | \
        sed -E "s/-\d+\.\d+\.\d+.*//g" | \
        grep "${ext}"
}

is_installable_rpm_package() {
    local php_version=${1//[![:digit:]]/}
    local ext=$2

    repoquery -q --qf="%{name}" "php${php_version}zend-php-"* | \
        grep -v "debuginfo" | \
        grep -v "devel" | \
        grep -v "dbg" |

        grep "${ext}"
}


is_mod_php_installed() {
    local php_version=$1
    local installer
    local packages
    local pattern

    if is_rhel_compatible || is_ibmi_compatible; then
        if is_ibmi_compatible; then
            installer=yum
        else
            installer="$(rhel_installer)"
        fi

        pattern="php${php_version//[![:digit:]]/}zend-php\."

        packages=$("${installer}" list installed 2>&1)
        if [[ "${packages}" =~ $pattern ]]; then
            return 0
        fi
    elif is_deb_compatible; then
        pattern="ii[[:space:]]+libapache2-mod-php${php_version}-zend"

        packages=$(dpkg-query -l 'libapache2-mod-php*' 2>&1)
        if [[ "${packages}" =~ $pattern ]]; then
            return 0
        fi
    elif is_apk_compatible; then
        pattern="php${php_version//[![:digit:]]/}zend-apache2"
        packages=$(apk list -I 2>&1)
        if [[ "${packages}" =~ $pattern ]]; then
            return 0
        fi
    fi

    return 1
}

is_rhel_compatible() {
    if [[ -f /etc/os-release ]]; then
        local release_info
        release_info=$(cat /etc/os-release)
        [[ "${release_info}" =~ NAME\=\"(AlmaLinux|Amazon|CentOS|Oracle|Red Hat|Rocky) ]] && return 0 || return 1
    elif [[ -f /etc/redhat-release ]]; then
        # CentOS 6
        local release_info
        release_info=$(cat /etc/redhat-release)
        [[ "${release_info}" =~ CentOS\ release\ 6 ]] && return 0 || return 1
    else
        return 1
    fi
}

list_enabled_extensions_for_apk() {
    local php_version=$1
    local conf_files
    local conf_file
    local test

    conf_files="$(find "/etc/php/${php_version//[![:digit:]]/}zend/conf.d" -name '*.ini')"

    for conf_file in $conf_files; do
        test="$(grep -E ";\s*(zend_)?extension=" "${conf_file}" || true)"
        if [[ -z "${test}" ]]; then
            basename "${conf_file}" | sed -E 's/([[:digit:]]+[_-])?([^.]+)\.ini/\2/'
        fi
    done
}

list_enabled_extensions_for_rhel() {
    local php_version=$1
    local conf_files
    local conf_file
    local test

    conf_files="$(find "/etc/opt/zend/php${php_version//[![:digit:]]/}zend/php.d" -name '*.ini' | \
        grep -vE '/[^0-9][^/]*\.ini$')"

    for conf_file in $conf_files; do
        test="$(grep -E ";\s*(zend_)?extension=" "${conf_file}" || true)"
        if [[ -z "${test}" ]]; then
            basename "${conf_file}" | sed -E 's/[[:digit:]]+\-([^.]+)\.ini/\1/'
        fi
    done
}

oracle7_install_base_repos() {
    cat <<- 'EOF' > /etc/yum.repos.d/epel.repo
		[ol7_developer_EPEL]
		name=Oracle Linux $releasever Development Packages ($basearch)
		baseurl=https://yum.oracle.com/repo/OracleLinux/OL7/developer_EPEL/$basearch/
		gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-oracle
		gpgcheck=1
		enabled=1
	EOF

    cat <<- 'EOF' > /etc/yum.repos.d/scl.repo
		[ol7_software_collections]
		name=Software Collection Library release 3.0 packages for Oracle Linux 7 (x86_64)
		baseurl=https://yum.oracle.com/repo/OracleLinux/OL7/SoftwareCollections/x86_64/
		gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-oracle
		gpgcheck=1
		enabled=1
	EOF
}

rhel_installer() {
    local installer
    installer=$(command -v dnf || true)
    if [[ -z "${installer}" ]]; then
        command -v yum
    else
        echo "${installer}"
    fi
}

send_completions() {
  echo $'# zendphpctl completion                                    -*- shell-script -*-'
  echo $''
  echo $'# This bash completions script was generated by'
  echo $'# completely (https://github.com/dannyben/completely)'
  echo $'# Modifying it manually is not recommended'
  echo $''
  echo $'_zendphpctl_completions_filter() {'
  echo $'  local words="$1"'
  echo $'  local cur=${COMP_WORDS[COMP_CWORD]}'
  echo $'  local result=()'
  echo $''
  echo $'  if [[ "${cur:0:1}" == "-" ]]; then'
  echo $'    echo "$words"'
  echo $''
  echo $'  else'
  echo $'    for word in $words; do'
  echo $'      [[ "${word:0:1}" != "-" ]] && result+=("$word")'
  echo $'    done'
  echo $''
  echo $'    echo "${result[*]}"'
  echo $''
  echo $'  fi'
  echo $'}'
  echo $''
  echo $'_zendphpctl_completions() {'
  echo $'  local cur=${COMP_WORDS[COMP_CWORD]}'
  echo $'  local compwords=("${COMP_WORDS[@]:1:$COMP_CWORD-1}")'
  echo $'  local compline="${compwords[*]}"'
  echo $''
  echo $'  case "$compline" in'
  echo $'    \'apache mod_php is-installed\'*)'
  echo $'      while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_zendphpctl_completions_filter "--help -h")" -- "$cur")'
  echo $'      ;;'
  echo $''
  echo $'    \'apache mod_php uninstall\'*)'
  echo $'      while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_zendphpctl_completions_filter "--help -h")" -- "$cur")'
  echo $'      ;;'
  echo $''
  echo $'    \'apache mod_php install\'*)'
  echo $'      while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_zendphpctl_completions_filter "--help -h")" -- "$cur")'
  echo $'      ;;'
  echo $''
  echo $'    \'zray plugin install\'*)'
  echo $'      while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_zendphpctl_completions_filter "--help --php -h")" -- "$cur")'
  echo $'      ;;'
  echo $''
  echo $'    \'zray plugin disable\'*)'
  echo $'      while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_zendphpctl_completions_filter "--help -h")" -- "$cur")'
  echo $'      ;;'
  echo $''
  echo $'    \'zray plugin enable\'*)'
  echo $'      while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_zendphpctl_completions_filter "--help -h")" -- "$cur")'
  echo $'      ;;'
  echo $''
  echo $'    \'php list-installed\'*)'
  echo $'      while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_zendphpctl_completions_filter "--help --json --verbose -h -j -v")" -- "$cur")'
  echo $'      ;;'
  echo $''
  echo $'    \'ext disable\'*\'--sapi\')'
  echo $'      while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_zendphpctl_completions_filter "ALL cli fpm")" -- "$cur")'
  echo $'      ;;'
  echo $''
  echo $'    \'ext install\'*\'--sapi\')'
  echo $'      while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_zendphpctl_completions_filter "ALL cli fpm")" -- "$cur")'
  echo $'      ;;'
  echo $''
  echo $'    \'ext list-packages\'*)'
  echo $'      while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_zendphpctl_completions_filter "--help -h")" -- "$cur")'
  echo $'      ;;'
  echo $''
  echo $'    \'ext enable\'*\'--sapi\')'
  echo $'      while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_zendphpctl_completions_filter "ALL cli fpm")" -- "$cur")'
  echo $'      ;;'
  echo $''
  echo $'    \'repo credentials\'*)'
  echo $'      while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_zendphpctl_completions_filter "--account --help --password -h")" -- "$cur")'
  echo $'      ;;'
  echo $''
  echo $'    \'fpm is-installed\'*)'
  echo $'      while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_zendphpctl_completions_filter "--help -h")" -- "$cur")'
  echo $'      ;;'
  echo $''
  echo $'    \'zray plugin list\'*)'
  echo $'      while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_zendphpctl_completions_filter "--enabled --help -h")" -- "$cur")'
  echo $'      ;;'
  echo $''
  echo $'    \'ext list-enabled\'*)'
  echo $'      while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_zendphpctl_completions_filter "--fpm --help -h")" -- "$cur")'
  echo $'      ;;'
  echo $''
  echo $'    \'php get-default\'*)'
  echo $'      while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_zendphpctl_completions_filter "--help -h")" -- "$cur")'
  echo $'      ;;'
  echo $''
  echo $'    \'php set-default\'*)'
  echo $'      while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_zendphpctl_completions_filter "--help -h")" -- "$cur")'
  echo $'      ;;'
  echo $''
  echo $'    \'repo uninstall\'*)'
  echo $'      while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_zendphpctl_completions_filter "--help -h")" -- "$cur")'
  echo $'      ;;'
  echo $''
  echo $'    \'apache mod_php\'*)'
  echo $'      while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_zendphpctl_completions_filter "--help -h install is-installed uninstall")" -- "$cur")'
  echo $'      ;;'
  echo $''
  echo $'    \'php list-sapis\'*)'
  echo $'      while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_zendphpctl_completions_filter "--help -h")" -- "$cur")'
  echo $'      ;;'
  echo $''
  echo $'    \'fpm uninstall\'*)'
  echo $'      while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_zendphpctl_completions_filter "--help -h")" -- "$cur")'
  echo $'      ;;'
  echo $''
  echo $'    \'php uninstall\'*)'
  echo $'      while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_zendphpctl_completions_filter "--help -h")" -- "$cur")'
  echo $'      ;;'
  echo $''
  echo $'    \'zendhq token\'*)'
  echo $'      while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_zendphpctl_completions_filter "--help --no-restart -h")" -- "$cur")'
  echo $'      ;;'
  echo $''
  echo $'    \'repo install\'*)'
  echo $'      while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_zendphpctl_completions_filter "--account --help --password --uri -h")" -- "$cur")'
  echo $'      ;;'
  echo $''
  echo $'    \'zray plugin\'*)'
  echo $'      while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_zendphpctl_completions_filter "--help -h disable enable install list")" -- "$cur")'
  echo $'      ;;'
  echo $''
  echo $'    \'completions\'*)'
  echo $'      while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_zendphpctl_completions_filter "--help -h")" -- "$cur")'
  echo $'      ;;'
  echo $''
  echo $'    \'php install\'*)'
  echo $'      while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_zendphpctl_completions_filter "--help --not-default -h 5.6 7.1 7.2 7.3 7.4 8.0 8.1 8.2 8.3 8.4 8.5")" -- "$cur")'
  echo $'      ;;'
  echo $''
  echo $'    \'self-update\'*)'
  echo $'      while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_zendphpctl_completions_filter "--help -h")" -- "$cur")'
  echo $'      ;;'
  echo $''
  echo $'    \'fpm install\'*)'
  echo $'      while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_zendphpctl_completions_filter "--help -h")" -- "$cur")'
  echo $'      ;;'
  echo $''
  echo $'    \'ext disable\'*)'
  echo $'      while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_zendphpctl_completions_filter "--help --php --sapi -h")" -- "$cur")'
  echo $'      ;;'
  echo $''
  echo $'    \'ext install\'*)'
  echo $'      while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_zendphpctl_completions_filter "--help --php --sapi -h")" -- "$cur")'
  echo $'      ;;'
  echo $''
  echo $'    \'php config\'*)'
  echo $'      while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_zendphpctl_completions_filter "--fpm --help -h")" -- "$cur")'
  echo $'      ;;'
  echo $''
  echo $'    \'fpm config\'*)'
  echo $'      while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_zendphpctl_completions_filter "--help -h")" -- "$cur")'
  echo $'      ;;'
  echo $''
  echo $'    \'ext enable\'*)'
  echo $'      while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_zendphpctl_completions_filter "--help --php --sapi -h")" -- "$cur")'
  echo $'      ;;'
  echo $''
  echo $'    \'php info\'*)'
  echo $'      while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_zendphpctl_completions_filter "--help --json --php -h -j")" -- "$cur")'
  echo $'      ;;'
  echo $''
  echo $'    \'php exec\'*)'
  echo $'      while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_zendphpctl_completions_filter "--help --php -h")" -- "$cur")'
  echo $'      ;;'
  echo $''
  echo $'    \'apache\'*)'
  echo $'      while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_zendphpctl_completions_filter "--help -h mod_php")" -- "$cur")'
  echo $'      ;;'
  echo $''
  echo $'    \'zendhq\'*)'
  echo $'      while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_zendphpctl_completions_filter "--help -h token")" -- "$cur")'
  echo $'      ;;'
  echo $''
  echo $'    \'repo\'*)'
  echo $'      while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_zendphpctl_completions_filter "--help -h credentials install uninstall")" -- "$cur")'
  echo $'      ;;'
  echo $''
  echo $'    \'zray\'*)'
  echo $'      while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_zendphpctl_completions_filter "--help -h plugin")" -- "$cur")'
  echo $'      ;;'
  echo $''
  echo $'    \'php\'*)'
  echo $'      while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_zendphpctl_completions_filter "--help -h config exec get-default info install list-installed list-sapis set-default uninstall")" -- "$cur")'
  echo $'      ;;'
  echo $''
  echo $'    \'fpm\'*)'
  echo $'      while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_zendphpctl_completions_filter "--help -h config install is-installed uninstall")" -- "$cur")'
  echo $'      ;;'
  echo $''
  echo $'    \'ext\'*)'
  echo $'      while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_zendphpctl_completions_filter "--help -h disable enable install list-enabled list-packages")" -- "$cur")'
  echo $'      ;;'
  echo $''
  echo $'    *)'
  echo $'      while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_zendphpctl_completions_filter "--help --version -h -v apache completions ext fpm php repo self-update zendhq zray")" -- "$cur")'
  echo $'      ;;'
  echo $''
  echo $'  esac'
  echo $'} &&'
  echo $'  complete -F _zendphpctl_completions zendphpctl'
  echo $''
  echo $'# ex: filetype=sh'
}

set_default_apk() {
    local php_version="${1}"
    local version_suffix="${php_version//[^[:digit:]]/}zend"

    green "Setting default PHP version to ${php_version}"

    ln -fs "/usr/bin/php${version_suffix}" /usr/bin/php
    ln -fs "/usr/bin/phar.phar${version_suffix}" /usr/bin/phar
    ln -fs "/usr/bin/phar.phar${version_suffix}" /usr/bin/phar.phar

    if [[ -f "/usr/sbin/php-fpm${version_suffix}" ]]; then
        ln -fs "/usr/sbin/php-fpm${version_suffix}" "/usr/sbin/php-fpm"
    fi
}

set_default_deb() {
    local php_version="${1}"

    green "Setting default PHP version to ${php_version}"
    update-alternatives --set php "/usr/bin/php${php_version}-zend"
}

set_default_ibmi() {
    local php_version="${1}"
    local version_suffix="${php_version//[^[:digit:]]/}zend"

    green "Setting default PHP version to ${php_version}"

    ln -fs "/QOpenSys/pkgs/bin/php-${version_suffix}" /QOpenSys/pkgs/bin/php
    ln -fs "/QOpenSys/pkgs/bin/phar-${version_suffix}" /QOpenSys/pkgs/bin/phar
    ln -fs "/QOpenSys/pkgs/bin/phar-${version_suffix}.phar" /QOpenSys/pkgs/bin/phar.phar

    if [[ -f "/QOpenSys/pkgs/sbin/php-fpm-${version_suffix}" ]]; then
        ln -fs "/QOpenSys/pkgs/sbin/php-fpm-${version_suffix}" "/QOpenSys/pkgs/sbin/php-fpm"
    fi

    if [[ -f "/QOpenSys/pkgs/bin/php-cgi-${version_suffix}" ]]; then
        ln -fs "/QOpenSys/pkgs/bin/php-cgi-${version_suffix}" "/QOpenSys/pkgs/bin/php-cgi"
        green "PHP-CGI version has been changed to ${php_version}. Please restart the web server."
    fi
}

set_default_rhel() {
    local php_version="${1}"
    local installer
    local current_default

    green "Setting default PHP version to ${php_version}"

    installer="$(rhel_installer)"
    current_default=$("${installer}" list installed | grep zend | grep syspaths | awk '{print $1}')
    if [[ -n "${current_default}" ]]; then
        green "Unmarking current default (${current_default})"
        "${installer}" remove -y "${current_default}"
    fi
    "${installer}" install -y "php${php_version//[^[:digit:]]/}zend-syspaths"
}

validate_extension_name() {
    local extension=$1
    local pattern

    pattern='^[0-9]+-'
    if [[ "${extension}" =~ $pattern ]]; then
        red "Extension names provided to ext-enable and ext-disable MUST NOT include a priority prefix"
    else
        pattern='-[0-9]+[^-]*$'
        if [[ "${extension}" =~ $pattern ]]; then
            red "Extension names provided to ext-enable and ext-disable MUST NOT include a version suffix"
        fi
    fi
}

validate_php_version() {
    local version=$1
    local versions_string

    versions_string="$(get_installed_versions)"

    if [[ ! "${versions_string}" =~ [1-9][0-9]*.[0-9]+ ]]; then
        echo "${versions_string}"
    else
        [[ ! "${versions_string}" =~ $version ]] && red "Unrecognized PHP version (${version}); must be one of (${versions_string//\n/ })" || true
    fi
}

validate_zray_plugin_name() {
    local plugin=$1
    local path=/opt/zend/zendphp/plugins/available

    if [[ $plugin =~ [^a-zA-Z0-9_-] ]]; then
        red "Z-Ray plugin names must consist of alphanumeric characters, underscores, and dashes only; received ${plugin}"
    fi

    if [[ $# -lt 2 ]]; then
        if [[ ! -e "${path}/${plugin}" ]]; then
            red "Z-Ray plugin ${plugin} does not exist in ${path}"
        fi
    fi
}

zendphpctl_completions_command() {

  send_completions

}

zendphpctl_self_update_command() {

  local workingdir="${PWD}"
  local source_script
  local tempdir

  source_script=$(realpath "${BASH_SOURCE[0]}")

  green "Creating temporary directory..."
  tempdir=$(mktemp -d --tmpdir zendphpXXXX)

  green "Downloading latest version..."
  if cd "${tempdir}" &&
      curl https://repos.zend.com/zendphp/zendphpctl > zendphpctl &&
      curl https://repos.zend.com/zendphp/zendphpctl.sig > zendphpctl.sig &&
      ( echo "$(cat zendphpctl.sig) zendphpctl" | sha256sum --check --status ); then
      green "Setting script owner and permissions..."
      chown --reference="${source_script}" -- "${tempdir}/zendphpctl"
      chmod --reference="${source_script}" -- "${tempdir}/zendphpctl"

      cd "${workingdir}" || exit 2

      green "Overwriting existing script..."
      # shellcheck disable=SC2128
      mv -- "${tempdir}/zendphpctl" "${source_script}"

      green "Removing temporary directory..."
      rm -rf "${tempdir}"
      green "Update complete!"
  else
      rm -rf "${tempdir}"
      red "Unable to download new version of zendphpctl and/or could not verify signature" >&2
      exit 1
  fi

}

zendphpctl_apache_mod_php_install_command() {

  local php_version="${args[php]}"
  if [[ -z "${php_version}" ]]; then
      php_version=$(detect_current_php_version "$(get_php_binary)")
  fi

  green "Installing mod_php for PHP version ${php_version}"

  if is_rhel_compatible; then
      local installer
      installer="$(rhel_installer)"

      if [[ "$(get_rhel_os_name)" == "CentOS" && "$(get_rhel_version)" == "7" ]]; then
          install_epel
      fi

      "${installer}" install -y "php${php_version//[![:digit:]]/}zend-php"
  elif is_ibmi_compatible; then
      yum install -y phpzend-apache-conf
  elif is_deb_compatible; then
      apt-get update
      apt-get install -y "libapache2-mod-php${php_version}-zend"
  elif is_apk_compatible; then
      apk_init_credentials
      apk update
      apk add "php${php_version//[![:digit:]]/}zend-apache2"
  fi

}

zendphpctl_apache_mod_php_is_installed_command() {

  local php_version="${args[php]}"
  if [[ -z "${php_version}" ]]; then
      php_version=$(detect_current_php_version "$(get_php_binary)")
  fi

  green "Checking if mod_php is installed for PHP ${php_version}..."

  if is_ibmi_compatible; then
      red "mod_php IS NOT installed for version ${php_version}"
  elif is_mod_php_installed "${php_version}"; then
      green "mod_php IS installed for version ${php_version}"
  else
      red "mod_php IS NOT installed for version ${php_version}"
  fi

}

zendphpctl_apache_mod_php_uninstall_command() {

  local php_version="${args[php]}"
  if [[ -z "${php_version}" ]]; then
      php_version=$(detect_current_php_version "$(get_php_binary)")
  fi

  green "Uninstalling mod_php for PHP version ${php_version}"

  if is_rhel_compatible; then
      local installer

      installer="$(rhel_installer)"
      "${installer}" remove -y "php${php_version//[![:digit:]]/}zend-php"
  elif is_ibmi_compatible; then
      yum remove -y phpzend-apache-conf
  elif is_deb_compatible; then
      apt-get remove -y "libapache2-mod-php${php_version}-zend"
  elif is_apk_compatible; then
      apk del "php${php_version//[![:digit:]]/}zend-apache2"
  fi

}

zendphpctl_ext_disable_command() {

  local php_version="${args[--php]}"
  if [[ -z "${php_version}" ]]; then
      php_version=$(detect_current_php_version "$(get_php_binary)")
  fi

  local invalid=0
  # shellcheck disable=2154
  for ext in "${other_args[@]}"; do
      local is_valid
      is_valid=$(validate_extension_name "${ext}")
      if [[ -n "${is_valid}" ]]; then
          invalid=1
          echo "${is_valid}" >&2
          continue
      fi
  done

  if [[ $invalid == 1 ]]; then
      red "One or more extension names were invalid" >&2
      exit 1
  fi

  if is_rhel_compatible; then
      local ext
      local installer

      installer=$(rhel_installer)

      for ext in "${other_args[@]}"; do
          local package
          local ext_package_name

          ext_package_name="$(echo "${ext}" | sed 's/_/-/g')"

          # Determine if it was installed via a package
          package="$( \
              yum list installed 2>&1 | \
              grep "php${php_version//[^[:digit:]]/}zend-php-" | \
              awk '{print $1}' | \
              grep -E "${ext_package_name}\." || \
              true)"

          if [[ -n "${package}" ]]; then
              green "Removing extension ${ext} via package manager"
              package="$(echo "${package}" | sed -E -e 's/\..*$//')"
              "${installer}" remove -y "${package}"
          fi
          # - not package? or conf file still present? comment out config file
          local conf_file

          conf_file=$(find "/etc/opt/zend/php${php_version//[![:digit:]]/}zend/php.d" -name '*.ini' -printf '%f\n' | \
              grep -E "^[0-9]+[-_]${ext}.ini" || true)

          if [[ -n "${conf_file}" ]]; then
              green "Disabling the extension ${ext}"
              sed --in-place -E -e "s/^($(get_ext_load_directive ${ext})=${ext}.so)/;\1/" "/etc/opt/zend/php${php_version//[![:digit:]]/}zend/php.d/${conf_file}"
          elif [[ -z "${package}" ]]; then
              green "Extension ${ext} not found; doing nothing"
          fi
      done
  elif is_ibmi_compatible; then
      local ext

      for ext in "${other_args[@]}"; do
          local ext_package_name
          local package

          ext_package_name="$(echo "${ext}" | sed 's/_/-/g')"

          # Determine if it was installed via a package
          package="$( \
              yum list installed 2>&1 | \
              grep "php${php_version//[^[:digit:]]/}zend-php-" | \
              awk '{print $1}' | \
              grep -E "${ext_package_name}\." || \
              true)"

          if [[ -n "${package}" ]]; then
              green "Removing extension ${ext} via package manager"
              package="$(echo "${package}" | sed -E -e 's/\..*$//')"
              yum remove -y "${package}"
          fi
          # - not package? or conf file still present? comment out config file
          local conf_file

          conf_file=$(find "/QOpenSys/etc/php/${php_version//[![:digit:]]/}zend/conf.d" -name '*.ini' -printf '%f\n' | \
              grep -E "^[0-9]+[-_]${ext}.ini" || true)

          if [[ -n "${conf_file}" ]]; then
              green "Disabling the extension ${ext}"
              sed --in-place -E -e "s/^($(get_ext_load_directive ${ext})=${ext}.so)/;\1/" "/QOpenSys/etc/php/${php_version//[![:digit:]]/}zend/conf.d/${conf_file}"
          elif [[ -z "${package}" ]]; then
              green "Extension ${ext} not found; doing nothing"
          fi
      done

      blue "Please restart Apache for these changes to take effect."
      blue "See 'STRTCPSVR SERVER(*HTTP) RESTART(*HTTP)' CL command for more details."
  elif is_deb_compatible; then
      local sapi="${args[--sapi]}"
      green "Disabling the following modules for ${sapi}: ${other_args[*]}"
      phpdismod -v "${php_version}-zend" -s "${sapi}" "${other_args[*]}"
  elif is_apk_compatible; then
      local ext

      for ext in "${other_args[@]}"; do
          local package

          # Determine if it was installed via a package
          package="$( \
              apk list -I "php${php_version//[^[:digit:]]/}zend-"* 2>&1 | \
              awk '{print $1}' | \
              grep -E "${ext}-" || \
              true)"

          if [[ -n "${package}" ]]; then
              green "Removing extension ${ext} via package manager"
              package="$(echo "${package}" | sed -E -e 's/-\d+\.\d+\.\d+.*$//')"
              apk del "${package}"
              # Please note that the configuration file may still remain in place.
          fi
          # - not package? or conf file still present? comment out config file
          local conf_file

          conf_file=$(find "/etc/php/${php_version//[![:digit:]]/}zend/conf.d" -name '*.ini' -printf '%f\n' | \
              grep -E "^[0-9]+[-_]${ext}.ini" || true)

          if [[ -n "${conf_file}" ]]; then
              green "Disabling the extension ${ext}"
              sed --in-place -E -e "s/^($(get_ext_load_directive ${ext})=${ext}.so)/;\1/" "/etc/php/${php_version//[![:digit:]]/}zend/conf.d/${conf_file}"
          elif [[ -z "${package}" ]]; then
              green "Extension ${ext} not found; doing nothing"
          fi
      done
  fi

}

zendphpctl_ext_enable_command() {

  local php_version="${args[--php]}"
  if [[ -z "${php_version}" ]]; then
      php_version=$(detect_current_php_version "$(get_php_binary)")
  fi

  local invalid=0
  for ext in "${other_args[@]}"; do
      local is_valid
      is_valid=$(validate_extension_name "${ext}")
      if [[ -n "${is_valid}" ]]; then
          invalid=1
          echo "${is_valid}" >&2
          continue
      fi
  done

  if [[ $invalid == 1 ]]; then
      red "One or more extension names were invalid" >&2
      exit 1
  fi

  if is_rhel_compatible; then
      local ext

      for ext in "${other_args[@]}"; do
          # First check to see if there is a configuration file present
          local conf_file
          local ext_package_name

          ext_package_name="${ext//_/-}"

          conf_file=$(find "/etc/opt/zend/php${php_version//[![:digit:]]/}zend/php.d" -name '*.ini' -printf '%f\n' | \
              grep -E "^[0-9]+[-_]${ext}.ini" || true)

          if [[ -z "${conf_file}" ]]; then
              # Time to install
              local installable
              local installer
              local package

              installable=$(create_installable_extension_list_for_rpm "${php_version}")

              if [[ "${installable}" =~ $ext_package_name ]]; then
                  installer=$(rhel_installer)
                  package="$(is_installable_rpm_package "${php_version}" "${ext_package_name}")"
                  green "Installing ${ext} via package manager"
                  "${installer}" install -y "${package}"
              else
                  green "Installing ${ext} from source"
                  install_extension_for_rhel "${php_version}" "${ext}" "20" "-"
              fi
          else
              # Enable the module
              green "Enabling the extension ${ext}"
              sed --in-place -E -e "s/^;+($(get_ext_load_directive ${ext})=${ext}.so)/\1/" "/etc/opt/zend/php${php_version//[![:digit:]]/}zend/php.d/${conf_file}"
          fi
      done
  elif is_ibmi_compatible; then
      local ext

      for ext in "${other_args[@]}"; do
          # First check to see if there is a configuration file present
          local conf_file
          local ext_package_name

          ext_package_name="${ext//_/-}"

          conf_file=$(find "/QOpenSys/etc/php/${php_version//[![:digit:]]/}zend/conf.d" -name '*.ini' -printf '%f\n' | \
              grep -E "^[0-9]+[-_]${ext}.ini" || true)

          if [[ -z "${conf_file}" ]]; then
              # Time to install
              local installable
              local package

              installable=$(create_installable_extension_list_for_rpm "${php_version}")

              if [[ "${installable}" =~ $ext_package_name ]]; then
                  package="$(is_installable_rpm_package "${php_version}" "${ext_package_name}")"
                  green "Installing ${ext} via package manager"
                  yum install -y "${package}"
              else
                  green "Installing ${ext} from source"
                  install_extension_for_ibmi "${php_version}" "${ext}" "20" "-"
              fi
          else
              # Enable the module
              green "Enabling the extension ${ext}"
              sed --in-place -E -e "s/^;+($(get_ext_load_directive ${ext})=${ext}.so)/\1/" "/QOpenSys/etc/php/${php_version//[![:digit:]]/}zend/conf.d/${conf_file}"
          fi
      done

      blue "Please restart Apache for these changes to take effect."
      blue "See 'STRTCPSVR SERVER(*HTTP) RESTART(*HTTP)' CL command for more details."
  elif is_deb_compatible; then
      local sapi="${args[--sapi]}"
      green "Enabling the following modules for ${sapi}: ${other_args[*]}"
      phpenmod -v "${php_version}-zend" -s "${sapi}" "${other_args[*]}"
  elif is_apk_compatible; then
      local ext

      for ext in "${other_args[@]}"; do
          # First check to see if there is a configuration file present
          local conf_file

          conf_file=$(find "/etc/php/${php_version//[![:digit:]]/}zend/conf.d" -name '*.ini' -printf '%f\n' | \
              grep -E "^([0-9]+[-_])?${ext}.ini" || true)

          if [[ -z "${conf_file}" ]]; then
              # Time to install
              local installable
              local packages=()

              installable=$(create_installable_extension_list_for_apk "${php_version}")

              if [[ "${installable}" =~ $ext ]]; then
                  mapfile -t packages < <(is_installable_apk_package "${php_version}" "${ext}")

                  green "Installing ${ext} via package manager"
                  apk_init_credentials
                  apk add "${packages[@]}"
                  # Not all extensions have been enabled by default, therefore we force-enable it below
                  conf_file=$(find "/etc/php/${php_version//[![:digit:]]/}zend/conf.d" -name '*.ini' -printf '%f\n' | \
                      grep -E "^([0-9]+[-_])?${ext}.ini" || true)
              else
                  green "Installing ${ext} from source"
                  apk_init_credentials
                  install_extension_for_apk "${php_version}" "${ext}" "20" "-"
                  continue
              fi
          fi
          # Enable the module
          green "Enabling the extension ${ext}"
          sed --in-place -E -e "s/^;+($(get_ext_load_directive ${ext})=${ext}.so)/\1/" "/etc/php/${php_version//[![:digit:]]/}zend/conf.d/${conf_file}"
      done
  fi

}

zendphpctl_ext_install_command() {

  # shellcheck enable=SC1010,SC1009,SC1054,SC1083,SC1073,SC1072,SC1036
  local php_version="${args[--php]}"
  if [[ -z "${php_version}" ]]; then
      php_version=$(detect_current_php_version "$(get_php_binary)")
  fi

  if is_rhel_compatible; then
      local installer
      local installable
      local module

      declare -A package_map=(
          ["bz2"]="common"
          ["calendar"]="common"
          ["curl"]="common"
          ["ctype"]="common"
          ["date"]="common"
          ["dom"]="xml"
          ["exif"]="common"
          ["fileinfo"]="common"
          ["filter"]="common"
          ["ftp"]="common"
          ["gettext"]="common"
          ["hash"]="common"
          ["iconv"]="common"
          ["json"]="common"
          ["libxml"]="common"
          ["mysqli"]="mysqlnd"
          ["oci8"]="oci8"
          ["opcache"]="opcache"
          ["openssl"]="common"
          ["pcntl"]="common"
          ["pcre"]="common"
          ["pdo-dblib"]="pdo-dblib"
          ["pdo_dblib"]="pdo-dblib"
          ["pdo-oci"]="pdo-oci"
          ["pdo_oci"]="pdo-oci"
          ["phar"]="common"
          ["phpdbg"]="dbg"
          ["posix"]="process"
          ["readline"]="common"
          ["redis"]="pecl-redis"
          ["redis5"]="pecl-redis5"
          ["redis6"]="pecl-redis6"
          ["reflection"]="common"
          ["session"]="common"
          ["shmop"]="process"
          ["simplexml"]="xml"
          ["sockets"]="common"
          ["spl"]="common"
          ["sqlite3"]="pdo"
          ["sysvmsg"]="process"
          ["sysvsem"]="process"
          ["sysvshm"]="process"
          ["tokenizer"]="common"
          ["xml"]="xml"
          ["xmlreader"]="xml"
          ["xmlrpc"]="xml"
          ["xmlwriter"]="xml"
          ["xsl"]="xml"
          ["zlib"]="common"
      )

      local epel_packages=(
          "imagick"
          "imap"
          "memcached"
          "mongodb"
          "pdo_dblib"
          "pdo-dblib"
          "redis"
          "redis5"
          "redis6"
          "sodium"
          "tidy"
      )

      green "Installing the following extensions: ${other_args[*]}"
      installer="$(rhel_installer)"
      installable=$(create_installable_extension_list_for_rpm "${php_version}")

      for module in "${other_args[@]}"; do
          local ext_version="-"
          local name
          local package
          local pattern
          local priority=''

          name=$(echo -n "${module}" | sed -E 's/^([0-9]+-){0,1}(.*)/\2/' | sed -E 's/(.*)(-[^-]+)$/\1/')

          pattern='^([0-9]+)-'
          if [[ "${module}" =~ $pattern ]]; then
              priority="${BASH_REMATCH[1]}"
          fi

          pattern="${name}-([^-]+)$"
          if [[ "${module}" =~ $pattern ]]; then
              ext_version="${BASH_REMATCH[1]}"
          fi

          green "Installing extension '${name}'"
          green "- Detected priority: '${priority}'"
          green "- Detected version: '${ext_version}'"

          if [[ -z "${priority}" && "${ext_version}" == "-" && -n "${package_map[$name]+abc}" ]]; then
              # Installable package from map
              if [[ "${package_map[$name]}" == "common" ]]; then
                  green  "The package ${name} is part of the common package; skipping"
              else
                  if [[ "${epel_packages[@]}" =~ $name ]]; then
                      if ! is_epel_enabled; then
                          green "Enabling EPEL repository"
                          install_epel
                      fi
                  fi

                  package="php${php_version//./}zend-php-${package_map[$name]}"

                  green "Installing extension ${module} via package manager"
                  "${installer}" install -y "${package}"
              fi
          elif [[ -z "${priority}" && "${ext_version}" == "-" && "${installable}" =~ $name ]]; then
              if [[ "${epel_packages[@]}" =~ $name ]]; then
                  if ! is_epel_enabled; then
                      green "Enabling EPEL repository"
                      install_epel
                  fi
              fi

              # Installable package
              package="$(is_installable_rpm_package "${php_version}" "${module}")"

              green "Installing extension ${module} via package manager"
              "${installer}" install -y "${package}"
          else
              # PECL
              if [[ -z "${priority}" ]]; then
                  priority=20
              fi

              green "Installing extension ${module} from source"
              install_extension_for_rhel "${php_version}" "${name}" "${priority}" "${ext_version}"
          fi
      done
  elif is_ibmi_compatible; then
      local installable
      local module

      declare -A package_map=(
          ["bz2"]="common"
          ["calendar"]="common"
          ["curl"]="common"
          ["ctype"]="common"
          ["date"]="common"
          ["dom"]="xml"
          ["exif"]="common"
          ["fileinfo"]="common"
          ["filter"]="common"
          ["ftp"]="common"
          ["gd"]="gd"
          ["gettext"]="common"
          ["gmp"]="gmp"
          ["hash"]="common"
          ["ibm_db2"]="pecl-ibm-db2"
          ["iconv"]="common"
          ["igbinary"]="pecl-igbinary"
          ["imagick"]="pecl-imagick"
          ["imap"]="imap"
          ["intl"]="intl"
          ["json"]="common"
          ["ldap"]="ldap"
          ["libxml"]="common"
          ["mbstring"]="mbstring"
          ["mongodb"]="mongodb"
          ["mysqli"]="mysqlnd"
          ["oauth"]="pecl-oauth"
          ["oci8"]="oci8"
          ["odbc"]="odbc"
          ["opcache"]="opcache"
          ["openssl"]="common"
          ["pcntl"]="common"
          ["pcre"]="common"
          ["pdo"]="common"
          ["pdo_dblib"]="pdo-dblib"
          ["pdo_odbc"]="pdo-odbc"
          ["pdo_pgsql"]="pdo-pgsql"
          ["pdo_sqlite"]="common"
          ["pgsl"]="pgsql"
          ["phar"]="common"
          ["posix"]="process"
          ["pspell"]="pspell"
          ["readline"]="common"
          ["redis"]="pecl-redis"
          ["reflection"]="common"
          ["session"]="common"
          ["shmop"]="process"
          ["simplexml"]="xml"
          ["soap"]="soap"
          ["sockets"]="common"
          ["sodium"]="common"
          ["spl"]="common"
          ["sqlite3"]="common"
          ["ssh2"]="pecl-ssh2"
          ["sysvmsg"]="process"
          ["sysvsem"]="process"
          ["sysvshm"]="process"
          ["tidy"]="tidy"
          ["tokenizer"]="common"
          ["xdebug"]="pecl-xdebug"
          ["xml"]="xml"
          ["xmlreader"]="xml"
          ["xmlrpc"]="xml"
          ["xmlwriter"]="xml"
          ["xsl"]="xml"
          ["zip"]="zip"
          ["zlib"]="common"
          ["zmail"]="common"
      )

      green "Installing the following extensions: ${other_args[*]}"
      installable=$(create_installable_extension_list_for_rpm "${php_version}")

      for module in "${other_args[@]}"; do
          local ext_version="-"
          local name
          local package
          local pattern
          local priority=''

          name=$(echo -n "${module}" | sed -E 's/^([0-9]+-){0,1}(.*)/\2/' | sed -E 's/(.*)(-[^-]+)$/\1/')

          pattern='^([0-9]+)-'
          if [[ "${module}" =~ $pattern ]]; then
              priority="${BASH_REMATCH[1]}"
          fi

          pattern="${name}-([^-]+)$"
          if [[ "${module}" =~ $pattern ]]; then
              ext_version="${BASH_REMATCH[1]}"
          fi

          green "Installing extension '${name}'"
          green "- Detected priority: '${priority}'"
          green "- Detected version: '${ext_version}'"

          if [[ -z "${priority}" && "${ext_version}" == "-" && -n "${package_map[$name]+abc}" ]]; then
              # Installable package from map
              if [[ "${package_map[$name]}" == "common" ]]; then
                  green  "The package ${name} is part of the common package; skipping"
              else
                  package="php${php_version//./}zend-php-${package_map[$name]}"

                  green "Installing extension ${module} via package manager"
                  yum install -y "${package}"
              fi
          elif [[ -z "${priority}" && "${ext_version}" == "-" && "${installable}" =~ $name ]]; then
              # Installable package
              package="$(is_installable_rpm_package "${php_version}" "${module}")"

              green "Installing extension ${module} via package manager"
              yum install -y "${package}"
          else
              # PECL
              if [[ -z "${priority}" ]]; then
                  priority=20
              fi

              green "Installing extension ${module} from source"
              install_extension_for_ibmi "${php_version}" "${name}" "${priority}" "${ext_version}"
          fi
      done

      blue "Please restart Apache for these changes to take effect."
      blue "See 'STRTCPSVR SERVER(*HTTP) RESTART(*HTTP)' CL command for more details."
  elif is_deb_compatible; then
      local installable
      local module
      local sapi="${args[--sapi]}"

      declare -A package_map=(
          ["calendar"]="common"
          ["ctype"]="common"
          ["date"]="common"
          ["dom"]="xml"
          ["exif"]="common"
          ["ffi"]="common"
          ["fileinfo"]="common"
          ["filter"]="common"
          ["ftp"]="common"
          ["gettext"]="common"
          ["hash"]="common"
          ["iconv"]="common"
          ["json"]="common"
          ["libxml"]="common"
          ["mysqli"]="mysql"
          ["mysqlnd"]="mysql"
          ["oci8"]="oci8"
          ["openssl"]="common"
          ["pcntl"]="common"
          ["pcre"]="common"
          ["pdo"]="common"
          ["pdo_oci"]="pdo-oci"
          ["pdo-oci"]="pdo-oci"
          ["phar"]="common"
          ["posix"]="common"
          ["reflection"]="common"
          ["shmop"]="common"
          ["simplexml"]="xml"
          ["sockets"]="common"
          ["sodium"]="common"
          ["spl"]="common"
          ["sysvmsg"]="common"
          ["sysvsem"]="common"
          ["sysvshm"]="common"
          ["xml"]="xml"
          ["xmlreader"]="xml"
          ["xmlrpc"]="xml"
          ["xmlwriter"]="xml"
          ["zlib"]="common"
      )

      green "Installing the following extensions for ${sapi}: ${other_args[*]}"
      installable=$(create_installable_extension_list_for_deb "${php_version}")

      apt-get update > /dev/null 2>&1
      for module in "${other_args[@]}"; do
          local ext_version="-"
          local name
          local package
          local pattern
          local priority=''

          name=$(echo -n "${module}" | sed -E 's/^([0-9]+-){0,1}(.*)/\2/' | sed -E 's/(.*)(-[^-]+)$/\1/')

          pattern='^([0-9]+)-'
          if [[ "${module}" =~ $pattern ]]; then
              priority="${BASH_REMATCH[1]}"
          fi

          pattern="${name}-([^-]+)$"
          if [[ "${module}" =~ $pattern ]]; then
              ext_version="${BASH_REMATCH[1]}"
          fi

          green "Installing extension '${name}'"
          green "- Detected priority: '${priority}'"
          green "- Detected version: '${ext_version}'"

          if [[ -z "${priority}" && "${ext_version}" == "-" && -n "${package_map[$name]+abc}" ]]; then
              if [[ "${package_map[$name]}" == "common" ]]; then
                  green  "The package ${name} is part of the common package; skipping"
              else
                  # Installable package from map
                  package="php${php_version}-zend-${package_map[$name]}"

                  green "Installing ${package}..."
                  apt-get install -y "${package}"
              fi
          elif [[ -z "${priority}" && "${ext_version}" == "-" && "${installable}" =~ $name ]]; then
              # Installable package at default priority and version provided
              green "Checking for availability via package manager"
              package=$(apt-cache search --names-only "php${php_version}-zend" | \
                  cut -d' ' -f1 | \
                  grep -E "\-${name}$" | \
                  tr "\n" " " | \
                  sed 's/ *$//g')
              if [[ -z "${package}" || "${package}" =~ [[:space:]] ]]; then
                  red "No package found, or more than one package found (found '${package}'); cannot proceed" >&2
                  exit 1
              else
                  green "Installing ${package}..."
                  apt-get install -y "${package}"
              fi
          else
              if [[ -z "${priority}" ]]; then
                  priority=20
              fi

              green "Installing from source"
              install_extension_for_deb "${php_version}" "${name}" "${priority}" "${ext_version}"

              green "Enabling extension"
              phpenmod -v "${php_version}-zend" -s "${sapi}" "${name}"
          fi
      done
  elif is_apk_compatible; then
      local installable
      local module

      declare -A package_map=(
          ["apcu"]="pecl-apcu"
          ["ctype"]="common"
          ["date"]="common"
          ["dblib"]="pdo_dblib"
          ["filter"]="common"
          ["igbinary"]="pecl-igbinary"
          ["imagick"]="pecl-imagick"
          ["json"]="common"
          ["libxml"]="xml"
          ["memcached"]="pecl-memcached"
          ["mongo"]="pecl-mongodb"
          ["mongodb"]="pecl-mongodb"
          ["msgpack"]="pecl-msgpack"
          ["oauth"]="pecl-oauth"
          ["pcre"]="common"
          ["phar"]="common"
          ["readline"]="common"
          ["redis"]="pecl-redis"
          ["reflection"]="common"
          ["spl"]="common"
          ["ssh2"]="pecl-ssh2"
          ["xdebug"]="pecl-xdebug"
          ["zlib"]="common"
      )

      green "Installing the following extensions: ${other_args[*]}"
      installable=$(create_installable_extension_list_for_apk "${php_version}")

      for module in "${other_args[@]}"; do
          local ext_version="-"
          local name
          local package
          local pattern
          local priority=''

          name=$(echo -n "${module}" | sed -E 's/^([0-9]+-){0,1}(.*)/\2/' | sed -E 's/(.*)(-[^-]+)$/\1/')

          pattern='^([0-9]+)-'
          if [[ "${module}" =~ $pattern ]]; then
              priority="${BASH_REMATCH[1]}"
          fi

          pattern="${name}-([^-]+)$"
          if [[ "${module}" =~ $pattern ]]; then
              ext_version="${BASH_REMATCH[1]}"
          fi

          green "Installing extension '${name}'"
          green "- Detected priority: '${priority}'"
          green "- Detected version: '${ext_version}'"

          if [[ -z "${priority}" && "${ext_version}" == "-" && -n "${package_map[$name]+abc}" ]]; then
              # Installable package from map
              if [[ "${package_map[$name]}" == "common" ]]; then
                  green  "The package ${name} is part of the common package; skipping"
              else
                  package="php${php_version//./}zend-${package_map[$name]}"

                  green "Installing extension ${module} via package manager"
                  apk_init_credentials
                  apk add "${package}"
              fi
          elif [[ -z "${priority}" && "${ext_version}" == "-" && "${installable}" =~ $name ]]; then
              local packages=()

              # Installable package(s)
              mapfile -t packages < <(is_installable_apk_package "${php_version}" "${module}")

              green "Installing extension ${module} via package manager"
              apk_init_credentials
              apk add "${packages[@]}"
          else
              # PECL
              if [[ -z "${priority}" ]]; then
                  priority=20
              fi

              green "Installing extension ${module} from source"
              install_extension_for_apk "${php_version}" "${name}" "${priority}" "${ext_version}"
          fi
      done
  fi

}

zendphpctl_ext_list_enabled_command() {

  local sapi
  local php_version="${args[php]}"
  if [[ -z "${php_version}" ]]; then
      php_version=$(detect_current_php_version "$(get_php_binary)")
  fi
  local fpm=${args[--fpm]}

  if is_rhel_compatible; then
      # RHEL does not differentiate between CLI and PHP versions for purposes of
      # extension enablement
      list_enabled_extensions_for_rhel "${php_version}" | sort
  elif is_ibmi_compatible; then
      find "/QOpenSys/etc/php/${php_version//[![:digit:]]/}zend/conf.d" -name '*.ini' -exec basename {} \; | \
          grep -vE '^[^0-9]' | \
          sed -E 's/[[:digit:]]+\-([^.]+)\.ini/\1/' | \
          sort
  elif is_deb_compatible; then
      if [[ $fpm ]]; then
          sapi=fpm
      else
          sapi=cli
      fi

      find "/etc/php/${php_version}-zend/${sapi}/conf.d" -name '*.ini' -printf '%f\n' | \
          grep -vE '^[^0-9]' | \
          sed -E 's/[[:digit:]]+\-([^.]+)\.ini/\1/' | \
          sort
  elif is_apk_compatible; then
      # APK does not differentiate between CLI and PHP versions for purposes of
      # extension enablement
      list_enabled_extensions_for_apk "${php_version}" | sort
  fi

}

zendphpctl_ext_list_packages_command() {

  local php_version="${args[php]}"
  if [[ -z "${php_version}" ]]; then
      php_version=$(detect_current_php_version "$(get_php_binary)")
  fi

  create_installable_extension_list "${php_version}"

}

zendphpctl_fpm_config_command() {

  local php_version="${args[php]}"
  if [[ -z "${php_version}" ]]; then
      php_version=$(detect_current_php_version "$(get_php_binary)")
  fi

  green "Using PHP version ${php_version}"

  if is_rhel_compatible; then
      # CLI and FPM share same php.ini on RHEL systems
      # shellcheck disable=SC2153
      if [[ -z "${EDITOR}" ]]; then
          red "No editor configured; please install nano, vim, or your favorite command line editor, and set export the EDITOR env variable" >&2
          exit 1
      else
          # CLI and FPM share same php.ini on RHEL systems
          exec "${EDITOR}" "/etc/opt/zend/php${php_version//[![:digit:]]/}zend/php-fpm.conf"
      fi
  elif is_ibmi_compatible; then
      if [[ -z "${EDITOR}" ]]; then
          red "No editor configured; please install nano, vim, or your favorite command line editor, and set export the EDITOR env variable" >&2
          exit 1
      else
          exec "${EDITOR}" "/QOpenSys/etc/php/${php_version//[![:digit:]]/}zend/php-fpm.conf"
      fi
  elif is_deb_compatible; then
      local editor

      editor=$(command -v editor)
      if [[ -z "${editor}" ]]; then
          red "No editor configured; please install nano, vim, or your favorite command line editor" >&2
          exit 1
      else
          exec "${editor}" "/etc/php/${php_version}-zend/fpm/php-fpm.conf"
      fi
  elif is_apk_compatible; then
      # shellcheck disable=SC2153
      if [[ -z "${EDITOR}" ]]; then
          red "No editor configured; please install nano, vim, or your favorite command line editor, and set export the EDITOR env variable" >&2
          exit 1
      else
          # CLI and FPM share same php.ini on RHEL systems
          exec "${EDITOR}" "/etc//php/${php_version//[![:digit:]]/}zend/php-fpm.conf"
      fi
  fi

}

zendphpctl_fpm_install_command() {

  local php_version="${args[php]}"
  if [[ -z "${php_version}" ]]; then
      php_version=$(detect_current_php_version "$(get_php_binary)")
  fi

  green "Installing FPM for PHP version ${php_version}"

  if is_rhel_compatible; then
      local installer
      installer="$(rhel_installer)"
      install_epel
      "${installer}" install -y fcgi "php${php_version//[![:digit:]]/}zend-php-fpm"
  elif is_ibmi_compatible; then
      yum install -y "php${php_version//[![:digit:]]/}zend-php-fpm"
  elif is_deb_compatible; then
      apt-get update
      apt-get install -y "php${php_version}-zend-fpm"
  elif is_apk_compatible; then
      apk_init_credentials
      apk update
      apk add "php${php_version//[![:digit:]]/}zend-fpm"

      if apk_is_default_php_version "${php_version}"; then
          ln -fs "/usr/sbin/php-fpm${php_version//[![:digit:]]/}zend" "/usr/sbin/php-fpm"
      fi
  fi

}

zendphpctl_fpm_is_installed_command() {

  local php_version="${args[php]}"
  if [[ -z "${php_version}" ]]; then
      php_version=$(detect_current_php_version "$(get_php_binary)")
  fi

  green "Checking if FPM is installed for PHP ${php_version}..."

  if is_fpm_installed "${php_version}"; then
      green "FPM IS installed for version ${php_version}"
  else
      red "FPM IS NOT installed for version ${php_version}"
  fi

}

zendphpctl_fpm_uninstall_command() {

  local php_version="${args[php]}"
  if [[ -z "${php_version}" ]]; then
      php_version=$(detect_current_php_version "$(get_php_binary)")
  fi

  green "Uninstalling FPM for PHP version ${php_version}"

  if is_rhel_compatible; then
      local installer

      installer="$(rhel_installer)"
      "${installer}" remove -y "php${php_version//[![:digit:]]/}zend-php-fpm"
  elif is_ibmi_compatible; then
      yum remove -y "php${php_version//[![:digit:]]/}zend-php-fpm"
  elif is_deb_compatible; then
      apt-get remove -y "php${php_version}-zend-fpm"
  elif is_apk_compatible; then
      apk del "php${php_version//[![:digit:]]/}zend-fpm"
  fi

}

zendphpctl_php_config_command() {

  local php_version="${args[php]}"
  # shellcheck disable=2154
  local fpm=${args[--fpm]}

  if [[ -z "${php_version}" ]]; then
      php_version=$(detect_current_php_version "$(get_php_binary)")
  fi

  green "Using PHP version ${php_version}"

  if is_rhel_compatible; then
      # CLI and FPM share same php.ini on RHEL systems
      # shellcheck disable=SC2153
      if [[ -z "${EDITOR}" ]]; then
          red "No editor configured; please install nano, vim, or your favorite command line editor, and export the EDITOR env variable" >&2
          exit 1
      else
          # CLI and FPM share same php.ini on RHEL systems
          exec "${EDITOR}" "/etc/opt/zend/php${php_version//[![:digit:]]/}zend/php.ini"
      fi
  elif is_ibmi_compatible; then
      # CLI and FPM share same php.ini on IBM i systems
      if [[ -z "${EDITOR}" ]]; then
          red "No editor configured; please install nano, vim, or your favorite command line editor, and export the EDITOR env variable" >&2
          exit 1
      else
          # CLI and FPM share same php.ini on IBM i systems
          exec "${EDITOR}" "/QOpenSys/etc/php/${php_version//[![:digit:]]/}zend/php.ini"
      fi
  elif is_deb_compatible; then
      local editor

      editor=$(command -v editor || true)
      if [[ -z "${editor}" ]]; then
          red "No editor configured; please install nano, vim, or your favorite command line editor" >&2
          exit 1
      else
          local conf_path="/etc/php/${php_version}-zend"
          if [[ $fpm ]]; then
              conf_path="${conf_path}/fpm/php.ini"
          else
              conf_path="${conf_path}/cli/php.ini"
          fi
          exec "${editor}" "${conf_path}"
      fi
  elif is_apk_compatible; then
      # shellcheck disable=SC2153
      if [[ -z "${EDITOR}" ]]; then
          red "No editor configured; please install nano, vim, or your favorite command line editor, and set export the EDITOR env variable" >&2
          exit 1
      else
          # CLI and FPM share same php.ini on RHEL systems
          exec "${EDITOR}" "/etc//php/${php_version//[![:digit:]]/}zend/php.ini"
      fi
  fi

}

zendphpctl_php_list_installed_command() {

  local json=${args[--json]}
  local verbose=${args[--verbose]}
  local details=()
  local binary
  local extension_dir
  local full_version
  local is_jq_installed
  local version
  local versions

  set +e
  is_jq_installed="$(type jq 2> /dev/null)"
  set -e

  if [[ $json && -z $is_jq_installed ]]; then
      red "Usage of the --json option requires the binary 'jq' in your path"
      exit 1
  fi
  set -e

  if [[ $verbose ]]; then
      if [[ $json ]]; then
          for version in $(get_installed_versions); do
              binary="$(get_php_binary "${version}")"
              full_version="$(${binary} -v | head -n1 | cut -d' ' -f2)"
              extension_dir="$("${binary}" -r 'echo ini_get("extension_dir");')"
              details+=( "$(display_version_details_as_json "${version}" "${full_version}" "${extension_dir}")" )
          done
          echo "${details[*]}" | jq --slurp .
      else
          for version in $(get_installed_versions); do
              binary="$(get_php_binary "${version}")"
              full_version="$(${binary} -v | head -n1 | cut -d' ' -f2)"
              extension_dir="$("${binary}" -r 'echo ini_get("extension_dir");')"
              display_version_details_as_text "${version}" "${full_version}" "${extension_dir}"
          done
      fi
  else
      versions=$(get_installed_versions)
      if [[ $json ]]; then
          echo "${versions}" | jq -nR '[ inputs | split(" ") | . ] | add'
      else
          echo "${versions}" | tr " " "\n"
      fi
  fi

}

zendphpctl_php_list_sapis_command() {

  local php_version="${args[php]}"
  local sapi
  local sapis

  if [[ -z "${php_version}" ]]; then
      php_version=$(detect_current_php_version "$(get_php_binary)")
  fi

  green "Installed SAPIs for PHP ${php_version}:"
  mapfile -t sapis < <(get_installed_sapis "${php_version}")
  for sapi in "${sapis[@]}"; do
      echo "- ${sapi}"
  done

}

zendphpctl_php_set_default_command() {

  local php_version="${args[php]}"

  if is_rhel_compatible; then
      set_default_rhel "${php_version}"
  elif is_ibmi_compatible; then
      set_default_ibmi "${php_version}"
  elif is_deb_compatible; then
      set_default_deb "${php_version}"
  elif is_apk_compatible; then
      set_default_apk "${php_version}"
  fi

}

zendphpctl_php_get_default_command() {

  local binary

  if is_rhel_compatible || is_ibmi_compatible; then
      binary="$(readlink "$(command -v php)")"
  elif is_deb_compatible; then
      binary="$(update-alternatives --query php | grep -E '^Value:' | cut -d' ' -f2)"
  elif is_apk_compatible; then
      binary="$(which "$(readlink "$(command -v php)")")"
  fi

  echo "${binary}"
  "${binary}" -v

}

zendphpctl_php_info_command() {

  local json=${args[--json]}
  local php_version="${args[--php]}"
  local binary
  local extension_dir
  local full_version
  local is_jq_installed

  if [[ -z "${php_version}" ]]; then
      php_version=$(detect_current_php_version "$(get_php_binary)")

      if [[ -z "${php_version}" ]]; then
          red "Please pass a version with --php or set a default by running: zendphpctl php set-default <PHP_VERSION>"
          return 1
      fi
  fi

  set +e
  is_jq_installed="$(type jq 2> /dev/null)"
  set -e

  if [[ $json && -z $is_jq_installed ]]; then
      red "Usage of the --json option requires the binary 'jq' in your path"
      exit 1
  fi
  set -e

  binary="$(get_php_binary "${php_version}")"
  full_version="$(${binary} -v | head -n1 | cut -d' ' -f2)"
  extension_dir="$("${binary}" -r 'echo ini_get("extension_dir");')"

  if [[ $json ]]; then
      display_version_details_as_json "${php_version}" "${full_version}" "${extension_dir}"
  else
      display_version_details_as_text "${php_version}" "${full_version}" "${extension_dir}"
  fi

}

zendphpctl_php_install_command() {

  local php_version="${args[php]}"
  local do_not_make_default=${args[--not-default]}

  if is_rhel_compatible; then
      local installer

      installer="$(rhel_installer)"

      if [[ "${php_version}" =~ ^(5\.6|7\.(1|2|3)) ]]; then
          install_epel
      fi

      green "Installing for RHEL system"
      "${installer}" install -y "php${php_version//[![:digit:]]/}zend" "php${php_version//[![:digit:]]/}zend-php-opcache"

      if [[ ! $do_not_make_default ]]; then

          set_default_rhel "${php_version}"
      fi
  elif is_ibmi_compatible; then
      green "Installing for IBM i system"
      yum install -y "php${php_version//[![:digit:]]/}zend" "php${php_version//[![:digit:]]/}zend-php-pecl-ibm-db2" phpzend-xmltoolkit

      if [[ ! $do_not_make_default ]]; then

          set_default_ibmi "${php_version}"
      fi
  elif is_deb_compatible; then
      green "Installing for DEB system"
      apt-get update
      apt-get install -y "php${php_version}-zend-cli"
      if [[ ! $do_not_make_default ]]; then

          set_default_deb "${php_version}"
      fi
  elif is_apk_compatible; then
      local package_base="php${php_version//[![:digit:]]/}zend"
      local packages=(
          "${package_base}"
          "${package_base}-calendar"

          "${package_base}-ctype"

          "${package_base}-exif"

          "${package_base}-fileinfo"

          "${package_base}-ftp"

          "${package_base}-gettext"

          "${package_base}-iconv"

          "${package_base}-opcache"

          "${package_base}-openssl"

          "${package_base}-pcntl"

          "${package_base}-pdo"

          "${package_base}-phar"

          "${package_base}-posix"

          "${package_base}-session"

          "${package_base}-shmop"

          "${package_base}-sockets"

          "${package_base}-sodium"

          "${package_base}-sysvmsg"

          "${package_base}-sysvsem"

          "${package_base}-sysvshm"

          "${package_base}-tokenizer"

          "${package_base}-tokenizer"
      )

      if [[ "${php_version}" =~ ^(7\.4|8\.) ]]; then
          packages+=("${package_base}-ffi")
      fi

      green "Installing for APK system"

      apk_init_credentials
      apk update
      apk add "${packages[@]}"
      if [[ ! $do_not_make_default ]]; then

          set_default_apk "${php_version}"
      fi
  fi

}

zendphpctl_php_uninstall_command() {

  local php_version="${args[php]}"

  if is_rhel_compatible || is_ibmi_compatible; then
      local installer
      local target_os

      if is_ibmi_compatible; then
          installer=yum
          target_os="IBM i"
      else
          installer="$(rhel_installer)"
          target_os=RHEL
      fi

      green "Uninstalling PHP ${php_version} for ${target_os} system"
      "${installer}" remove -y "php${php_version//[![:digit:]]/}zend*"
  elif is_deb_compatible; then
      green "Uninstalling PHP ${php_version} for DEB system"
      # shellcheck disable=SC2046
      apt-get remove -y $(dpkg-query -f '${Package}\n' -W | grep "php${php_version}-zend")
  elif is_apk_compatible; then
      local version="${php_version//[![:digit:]]/}"

      green "Uninstalling PHP ${php_version} for APK system"

      # shellcheck disable=SC2046
      apk del $(apk list -I 2>&1 | grep "php${version}zend" | awk '{print $1}' | sed -E -e "s/^(php${version}zend.*?)(-${php_version}\..*)$/\1/g" | tr "\n" " ")
  fi

}

zendphpctl_php_exec_command() {

  local php

  if [[ "${args[--php]+abc}" ]]; then
      php=$(get_php_binary "${args[--php]}")
  else
      php=$(get_php_binary)
  fi

  if [[ -z "${php}" ]]; then
      red "No PHP binary found" >&2
      exit 1
  fi

  exec "${php}" "${other_args[*]}"

}

zendphpctl_repo_credentials_command() {

  green "Preparing to install ZendPHP repository credentials"

  local account="${args[--account]}"
  local password="${args[--password]}"
  local rpmrepofile=''

  if is_rhel_compatible; then
      rpmrepofile=/etc/yum.repos.d/zendphp.repo
  elif is_ibmi_compatible; then
      rpmrepofile=/QOpenSys/etc/yum/repos.d/zendphp.repo
      export PATH=/QOpenSys/pkgs/bin:$PATH
  fi

  if [ "$rpmrepofile" != "" ]; then
      if [[ ! -f $rpmrepofile ]]; then
          red "You have not yet installed the ZendPHP package repository!" >&2
          red "Please run zendphpctl repo-install" >&2
          exit 1
      fi
      # Replace username and password if these are already included in the repofile
      # or else add in the repo section after baseurl line
      if grep -q "^username=" $rpmrepofile; then
          # Escape variables
          account="${account//&/\\&}"; account="${account//\\/\\\\}";account="${account//\//\\\/}"
          password="${password//&/\\&}"; password="${password//\\/\\\\}";password="${password//\//\\\/}"
          sed -i "s/^\(username=\).*/\1$account/;s/^\(password=\).*/\1$password/" $rpmrepofile
          green "ZendPHP credentials replaced!"
      else
          sed -i "/^baseurl/a username=$account\npassword=$password" $rpmrepofile
          green "ZendPHP credentials installed!"
      fi
  elif is_deb_compatible; then
      # This is intentionally valid for repos.zend.com only as the zendphp credentials are
      # valid for this site only, currently. This is to be revisited when that changes.
      echo "machine https://repos.zend.com/zendphp login ${account} password ${password}" > /etc/apt/auth.conf.d/zendphp.conf
      green "ZendPHP credentials installed!"
  elif is_apk_compatible; then
      echo "HTTP_AUTH=basic:*:${account}:${password}" > /etc/apk/zendrepo.rc
      green "ZendPHP credentials installed!"
  fi

}

zendphpctl_repo_install_command() {

  green "Preparing to install ZendPHP repository"

  local account="${args[--account]}"
  local password="${args[--password]}"
  local uri_list="${args[--uri]}"

  if [[ -n "${account}" && -z "${password}" ]] || [[ -z "${account}" && -n "${password}" ]]; then
      red "BOTH --account AND --password must be provided if you are providing credentials." >&2
      exit 2
  fi

  local -a uri_array
  if [[ -n "${uri_list}" ]]; then
      read -r -a uri_array <<< "${uri_list}"
  else
      uri_array=("https://repos.zend.com/zendphp")
  fi
  for i in "${!uri_array[@]}"; do
      uri_array[$i]="${uri_array[$i]%/}"
  done

  local auth_block=""
  [[ -n "${account}" && -n "${password}" ]] && auth_block="username=${account}"$'\n'"password=${password}" || true

  if is_rhel_compatible; then
      local os
      local os_version
      local installer

      os="$(get_rhel_os_name)"
      os_version="$(get_rhel_version)"
      installer="$(rhel_installer)"

      if [[ "${os}" == "Amazon" ]]; then
          os_version=7
      fi
      case "$os_version" in
          "10") repokey=zend-2025.key;;
          *) repokey=zend.key;;
      esac

      > /etc/yum.repos.d/zendphp.repo
      local counter=1
      for uri in "${uri_array[@]}"; do
          local name_suffix=""
          if [[ ${counter} -gt 1 ]]; then
              name_suffix="_${counter}"
          fi
          get_rhel_repo_template "${repokey}" "${uri}" "${name_suffix}" "${os_version}" "${auth_block}" >> /etc/yum.repos.d/zendphp.repo
          (( counter++ ))
      done

      if [[ "${os_version}" -gt 7 ]];then
          "${installer}" -y install dnf-plugins-core

          case $os in
          "AlmaLinux")
              "${installer}" install -y yum-utils
              ;;
          "Rocky")
              "${installer}" install -y findutils yum-utils
              ;;
          "RHEL")
              "${installer}" install -y yum-utils
              ;;
          esac
      else
          case $os in
          "Amazon")
              "${installer}" -y install scl-utils tar yum-utils
              ;;
          "Oracle")
              oracle7_install_base_repos
              "${installer}" -y install scl-utils
              ;;
          "RHEL")
              "${installer}" -y install environment-modules tar yum-utils
              yum-config-manager --enable rhel-server-rhscl-7-rpms
              ;;
          *)
              "${installer}" -y install centos-release-scl-rh
              ;;
          esac
      fi

      green "ZendPHP repository installed and configured!"
  elif is_ibmi_compatible; then
      local os_version

      os_version="$(get_ibmi_version)"

      > /QOpenSys/etc/yum/repos.d/zendphp.repo
      local counter=1
      for uri in "${uri_array[@]}"; do
          local name_suffix=""
          if [[ ${counter} -gt 1 ]]; then
              name_suffix="_${counter}"
          fi
          get_ibmi_repo_template "${uri}" "${name_suffix}" "${os_version}" "${auth_block}" >> /QOpenSys/etc/yum/repos.d/zendphp.repo
          (( counter++ ))
      done

      yum clean metadata

      green "ZendPHP repository installed and configured!"
  elif is_deb_compatible; then
      local os
      local os_version

      # Get OS and version
      if grep -q "ID=debian" /etc/os-release; then
          os_version=$(grep -E "VERSION_ID=\"(9|10|11|12|13)" /etc/os-release | sed -E 's/[^0-9]//g')
          if [ -z "${os_version}" ]; then
              red "Unsupported Debian version detected; cannot install ZendPHP repository" >&2
              exit 3
          fi
          os=debian
      elif grep -q "ID=ubuntu" /etc/os-release; then
          os_version=$(grep -E "VERSION_ID=\"(16|18|20|22|24|26)\.04" /etc/os-release | sed -E 's/[^0-9]//g')
          if [ -z "${os_version}" ]; then
              red "Unsupported Ubuntu version detected; cannot install ZendPHP repository" >&2
              exit 3
          fi
          os=ubuntu
      else
          red "Unrecognized Debian-like operating system; cannot install ZendPHP repository" >&2
          exit 3
      fi

      if [[ -n "${account}" && -n "${password}" ]]; then
          local authfile
          authfile=/etc/apt/auth.conf.d/zendphp.conf
          > ${authfile}
          for uri in "${uri_array[@]}"; do
              grep -q "^machine\ ${uri}\ " "${authfile}" || echo "machine ${uri} login ${account} password ${password}" >> ${authfile}
          done
      fi

      export DEBIAN_FRONTEND=noninteractive
      case "$os-$os_version" in
          "ubuntu-2404" | "ubuntu-2604" | "debian-13") repokey=zend-2025.key;;
          *) repokey=zend.key;;
      esac

      # When the repository key already exists and has changed then it must be updated before `apt-get update` or else it would fail
      if [ -f /usr/share/keyrings/zend.gpg ] && command gpg --version >/dev/null 2>/dev/null; then
          blue "Updating the repository key"
          curl -sS https://repos.zend.com/${repokey} | gpg --dearmor > /usr/share/keyrings/zend.gpg || red "Failed updating the key file"
          have_key=1
      fi

      apt-get update
      apt-get -y install apt-transport-https ca-certificates curl gnupg

      [ "$have_key" == "1" ] || curl -sS https://repos.zend.com/${repokey} | gpg --dearmor > /usr/share/keyrings/zend.gpg

      > /etc/apt/sources.list.d/zendphp.list
      for uri in "${uri_array[@]}"; do
          echo "deb [signed-by=/usr/share/keyrings/zend.gpg] ${uri}/deb_${os}${os_version}/ zendphp non-free" >> /etc/apt/sources.list.d/zendphp.list
      done

      apt-get update

      green "ZendPHP repository installed and configured!"
  elif is_apk_compatible; then
      if ! grep -q -E "VERSION_ID=3\.(16|18|20|22|24)\." /etc/os-release; then
          red "Unsupported Alpine version detected; cannot install ZendPHP repository" >&2
          exit 3
      fi
      os=alpine
      os_version=$(grep -E "VERSION_ID=3\.(16|18|20|22|24)" /etc/os-release | sed -E 's/[^0-9.]//g' | sed -E 's/^([0-9]+)\.([0-9]+).*$/\1\2/')

      wget "https://repos.zend.com/zendphp/apk_alpine${os_version}/zendphp-alpine-devel.rsa.pub" -O /etc/apk/keys/zendphp-alpine-devel.rsa.pub

      if [[ -n "${account}" && -n "${password}" ]]; then
          echo "HTTP_AUTH=basic:*:${account}:${password}" > /etc/apk/zendrepo.rc
          green "ZendPHP repository credentials installed"
      fi

      for uri in "${uri_array[@]}"; do
          echo "${uri}/apk_alpine${os_version}/" >> /etc/apk/repositories
      done

      apk update

      blue "Installing utilities required by zendphpctl..."
      apk add coreutils curl findutils grep

      green "ZendPHP repository installed and configured!"
  fi

}

zendphpctl_repo_uninstall_command() {

  if is_rhel_compatible; then
      rm -f /etc/yum.repos.d/zendphp.repo
      green "Removed ZendPHP package repository from your operating system"
      echo "NOTE: This action DOES NOT remove already installed ZendPHP packages."
  elif is_ibmi_compatible; then
      rm -f /QOpenSys/etc/yum/repos.d/zendphp.repo
      green "Removed ZendPHP package repository from your operating system"
      echo "NOTE: This action DOES NOT remove already installed ZendPHP packages."
  elif is_deb_compatible; then
      rm -f /etc/apt/sources.list.d/zendphp.list
      if [[ -f /etc/apt/auth.conf.d/zendphp.conf ]]; then
          rm -f /etc/apt/auth.conf.d/zendphp.conf
      fi
      apt-get update
      green "Removed ZendPHP package repository from your operating system"
      echo "NOTE: This action DOES NOT remove already installed ZendPHP packages."
  elif is_apk_compatible; then
      sed --in-place -E -e '/^http.*repos\.zend\.com\/zendphp\/apk_alpine.*$/d' /etc/apk/repositories
      if [[ -f /etc/apk/zendrepo.rc ]]; then
          rm -f /etc/apk/zendrepo.rc
      fi
      green "Removed ZendPHP package repository from your operating system"
      echo "NOTE: This action DOES NOT remove already installed ZendPHP packages."
  fi

}

zendphpctl_zendhq_token_command() {

  local token="${args[token]}"
  local no_restart=${args[--no-restart]}

  local hashed_token
  local timestamp

  hashed_token="$(echo -n "${token}" | sha256sum | awk '{ print $1 }')"
  timestamp="$(date +%FT%k%M%S)"

  green "Backing up zendhqd.ini file to /opt/zend/zendphp/etc/zendhqd.ini.${timestamp}"
  cp /opt/zend/zendphp/etc/zendhqd.ini "/opt/zend/zendphp/etc/zendhqd.ini.${timestamp}"

  green "Updating token"
  sed --in-place -E -e "s/^(zendhqd.session.auth_token_hash\s*=\s*).*$/\1${hashed_token}/" /opt/zend/zendphp/etc/zendhqd.ini
  yellow "This command is deprecated and may not work as expected"
  yellow "Please use: zendhqctl access user password <username> <password>"
  if /opt/zend/zendphp/bin/zendhqctl access user print admin |grep 'admin\s*no\ password' >>/dev/null; then
  yellow "Token is currently set"
  else
  red "Token is written to the ini file but it will not be used as it is overriden by database setup"
  fi

  if [[ ! $no_restart ]]; then
      if is_apk_compatible; then
          /etc/init.d/zendhq reload
      else
          systemctl restart zendhqd
      fi
  fi

  green "Done!"

}

zendphpctl_zray_plugin_install_command() {

  local php_version="${args[--php]}"
  if [[ -z "${php_version}" ]]; then
      php_version=$(detect_current_php_version "$(get_php_binary)")
  fi

  green "Installing Z-Ray plugins"
  green "Detected PHP version: ${php_version}"

  if is_rhel_compatible; then
      local installer
      installer="$(rhel_installer)"
      "${installer}" install -y "php${php_version//[![:digit:]]/}zend-php-zendhq" php-zray-plugins
  elif is_deb_compatible; then
      apt-get update
      apt-get install -y "php${php_version}-zend-zendhq" php-zray-plugins
  elif is_apk_compatible; then
      apk update
      apk add php-zray-plugins
      ensure_zray_plugin_tree
  fi

}

zendphpctl_zray_plugin_list_command() {

  local enabled_only=${args[--enabled]}

  local plugins_path=/opt/zend/zendphp/plugins

  if [[ ! -d "${plugins_path}" ]]; then
      blue "No Z-Ray plugins are installed; please run the zendphpctl zray-plugins-install command"
  elif [[ $enabled_only ]]; then
      ensure_zray_plugin_tree

      green "Enabled Z-Ray plugins:"
      for plugin in "${plugins_path}/enabled/"*; do
          if [[ -L "${plugin}" || -d "${plugin}" ]]; then
              basename "${plugin}"
          fi
      done
  else
      ensure_zray_plugin_tree

      green "Available Z-Ray plugins:"
      for plugin in "${plugins_path}/available/"*; do
          if [[ -d "${plugin}" ]]; then
              basename "${plugin}"
          fi
      done
  fi

}

zendphpctl_zray_plugin_disable_command() {


  local invalid=0

  ensure_zray_plugin_tree

  for plugin in "${other_args[@]}"; do
      local is_valid
      is_valid=$(validate_zray_plugin_name "${plugin}" "enabled")
      if [[ -n "${is_valid}" ]]; then
          invalid=1
          echo "${is_valid}" >&2
          continue
      fi
  done

  if [[ $invalid == 1 ]]; then
      red "One or more plugin names were invalid" >&2
      exit 1
  fi

  local errors=0
  local plugins_path=/opt/zend/zendphp/plugins
  local available="${plugins_path}/available"
  local enabled="${plugins_path}/enabled"

  for plugin in "${other_args[@]}"; do
      if [[ ! -e "${enabled}/${plugin}" ]]; then
          # Not "enabled"; skip
          blue "Plugin ${plugin} is not currently enabled; skipping"
      elif [[ -L "${enabled}/${plugin}" ]]; then
          # Symlink; remove
          green "Disabling plugin ${plugin}"
          unlink "${enabled}/${plugin}"
      elif [[ -f "${enabled}/${plugin}" ]]; then
          # Is a file; skip
          red "Plugin ${plugin} is not a valid plugin; skipping"
          errors=2
      else
          # Plugin is a directory
          # Does an "available" plugin already exist?
          if [[ -e "${available}/${plugin}" ]]; then
              red "Cannot disable plugin ${plugin}; is a directory, and another entry by that name is in the available plugins list"
              errors=3
          else
              mv "${enabled}/${plugin}" "${available}/$plugin}"
          fi
      fi
  done

  if [[ $errors -gt 0 ]]; then
      red "One or more plugins were invalid; check logs for details"
      exit $errors
  fi

}

zendphpctl_zray_plugin_enable_command() {

  local invalid=0

  ensure_zray_plugin_tree

  for plugin in "${other_args[@]}"; do
      local is_valid
      is_valid=$(validate_zray_plugin_name "${plugin}")
      if [[ -n "${is_valid}" ]]; then
          invalid=1
          echo "${is_valid}" >&2
          continue
      fi
  done

  if [[ $invalid == 1 ]]; then
      red "One or more plugin names were invalid" >&2
      exit 1
  fi

  local errors=0
  local plugins_path=/opt/zend/zendphp/plugins
  local available="${plugins_path}/available"
  local enabled="${plugins_path}/enabled"

  for plugin in "${other_args[@]}"; do
      # Check if it is already enabled; if so skip
      if [[ -d "${enabled}/${plugin}" ]]; then
          blue "Plugin ${plugin} is already enabled; skipping"
      elif [[ ! -d "${available}/${plugin}" ]]; then
          red "Plugin ${plugin} is not a directory; skipping"
          errors=1
      else
          green "Enabling plugin ${plugin}"
          ln -s "${available}/${plugin}" "${enabled}/${plugin}"
      fi
  done

  if [[ $errors -gt 0 ]]; then
      red "One or more plugins were invalid; check logs for details"
      exit 2
  fi

}

php_config_command() {

  local php_version="${args[php]}"
  # shellcheck disable=2154
  local fpm=${args[--fpm]}

  if [[ -z "${php_version}" ]]; then
      php_version=$(detect_current_php_version "$(get_php_binary)")
  fi

  green "Using PHP version ${php_version}"

  if is_rhel_compatible; then
      # CLI and FPM share same php.ini on RHEL systems
      # shellcheck disable=SC2153
      if [[ -z "${EDITOR}" ]]; then
          red "No editor configured; please install nano, vim, or your favorite command line editor, and export the EDITOR env variable" >&2
          exit 1
      else
          # CLI and FPM share same php.ini on RHEL systems
          exec "${EDITOR}" "/etc/opt/zend/php${php_version//[![:digit:]]/}zend/php.ini"
      fi
  elif is_ibmi_compatible; then
      # CLI and FPM share same php.ini on IBM i systems
      if [[ -z "${EDITOR}" ]]; then
          red "No editor configured; please install nano, vim, or your favorite command line editor, and export the EDITOR env variable" >&2
          exit 1
      else
          # CLI and FPM share same php.ini on IBM i systems
          exec "${EDITOR}" "/QOpenSys/etc/php/${php_version//[![:digit:]]/}zend/php.ini"
      fi
  elif is_deb_compatible; then
      local editor

      editor=$(command -v editor || true)
      if [[ -z "${editor}" ]]; then
          red "No editor configured; please install nano, vim, or your favorite command line editor" >&2
          exit 1
      else
          local conf_path="/etc/php/${php_version}-zend"
          if [[ $fpm ]]; then
              conf_path="${conf_path}/fpm/php.ini"
          else
              conf_path="${conf_path}/cli/php.ini"
          fi
          exec "${editor}" "${conf_path}"
      fi
  elif is_apk_compatible; then
      # shellcheck disable=SC2153
      if [[ -z "${EDITOR}" ]]; then
          red "No editor configured; please install nano, vim, or your favorite command line editor, and set export the EDITOR env variable" >&2
          exit 1
      else
          # CLI and FPM share same php.ini on RHEL systems
          exec "${EDITOR}" "/etc//php/${php_version//[![:digit:]]/}zend/php.ini"
      fi
  fi

}

php_list_installed_command() {

  local json=${args[--json]}
  local verbose=${args[--verbose]}
  local details=()
  local binary
  local extension_dir
  local full_version
  local is_jq_installed
  local version
  local versions

  set +e
  is_jq_installed="$(type jq 2> /dev/null)"
  set -e

  if [[ $json && -z $is_jq_installed ]]; then
      red "Usage of the --json option requires the binary 'jq' in your path"
      exit 1
  fi
  set -e

  if [[ $verbose ]]; then
      if [[ $json ]]; then
          for version in $(get_installed_versions); do
              binary="$(get_php_binary "${version}")"
              full_version="$(${binary} -v | head -n1 | cut -d' ' -f2)"
              extension_dir="$("${binary}" -r 'echo ini_get("extension_dir");')"
              details+=( "$(display_version_details_as_json "${version}" "${full_version}" "${extension_dir}")" )
          done
          echo "${details[*]}" | jq --slurp .
      else
          for version in $(get_installed_versions); do
              binary="$(get_php_binary "${version}")"
              full_version="$(${binary} -v | head -n1 | cut -d' ' -f2)"
              extension_dir="$("${binary}" -r 'echo ini_get("extension_dir");')"
              display_version_details_as_text "${version}" "${full_version}" "${extension_dir}"
          done
      fi
  else
      versions=$(get_installed_versions)
      if [[ $json ]]; then
          echo "${versions}" | jq -nR '[ inputs | split(" ") | . ] | add'
      else
          echo "${versions}" | tr " " "\n"
      fi
  fi

}

php_set_default_command() {

  local php_version="${args[php]}"

  if is_rhel_compatible; then
      set_default_rhel "${php_version}"
  elif is_ibmi_compatible; then
      set_default_ibmi "${php_version}"
  elif is_deb_compatible; then
      set_default_deb "${php_version}"
  elif is_apk_compatible; then
      set_default_apk "${php_version}"
  fi

}

php_install_command() {

  local php_version="${args[php]}"
  local do_not_make_default=${args[--not-default]}

  if is_rhel_compatible; then
      local installer

      installer="$(rhel_installer)"

      if [[ "${php_version}" =~ ^(5\.6|7\.(1|2|3)) ]]; then
          install_epel
      fi

      green "Installing for RHEL system"
      "${installer}" install -y "php${php_version//[![:digit:]]/}zend" "php${php_version//[![:digit:]]/}zend-php-opcache"

      if [[ ! $do_not_make_default ]]; then

          set_default_rhel "${php_version}"
      fi
  elif is_ibmi_compatible; then
      green "Installing for IBM i system"
      yum install -y "php${php_version//[![:digit:]]/}zend" "php${php_version//[![:digit:]]/}zend-php-pecl-ibm-db2" phpzend-xmltoolkit

      if [[ ! $do_not_make_default ]]; then

          set_default_ibmi "${php_version}"
      fi
  elif is_deb_compatible; then
      green "Installing for DEB system"
      apt-get update
      apt-get install -y "php${php_version}-zend-cli"
      if [[ ! $do_not_make_default ]]; then

          set_default_deb "${php_version}"
      fi
  elif is_apk_compatible; then
      local package_base="php${php_version//[![:digit:]]/}zend"
      local packages=(
          "${package_base}"
          "${package_base}-calendar"

          "${package_base}-ctype"

          "${package_base}-exif"

          "${package_base}-fileinfo"

          "${package_base}-ftp"

          "${package_base}-gettext"

          "${package_base}-iconv"

          "${package_base}-opcache"

          "${package_base}-openssl"

          "${package_base}-pcntl"

          "${package_base}-pdo"

          "${package_base}-phar"

          "${package_base}-posix"

          "${package_base}-session"

          "${package_base}-shmop"

          "${package_base}-sockets"

          "${package_base}-sodium"

          "${package_base}-sysvmsg"

          "${package_base}-sysvsem"

          "${package_base}-sysvshm"

          "${package_base}-tokenizer"

          "${package_base}-tokenizer"
      )

      if [[ "${php_version}" =~ ^(7\.4|8\.) ]]; then
          packages+=("${package_base}-ffi")
      fi

      green "Installing for APK system"

      apk_init_credentials
      apk update
      apk add "${packages[@]}"
      if [[ ! $do_not_make_default ]]; then

          set_default_apk "${php_version}"
      fi
  fi

}

php_uninstall_command() {

  local php_version="${args[php]}"

  if is_rhel_compatible || is_ibmi_compatible; then
      local installer
      local target_os

      if is_ibmi_compatible; then
          installer=yum
          target_os="IBM i"
      else
          installer="$(rhel_installer)"
          target_os=RHEL
      fi

      green "Uninstalling PHP ${php_version} for ${target_os} system"
      "${installer}" remove -y "php${php_version//[![:digit:]]/}zend*"
  elif is_deb_compatible; then
      green "Uninstalling PHP ${php_version} for DEB system"
      # shellcheck disable=SC2046
      apt-get remove -y $(dpkg-query -f '${Package}\n' -W | grep "php${php_version}-zend")
  elif is_apk_compatible; then
      local version="${php_version//[![:digit:]]/}"

      green "Uninstalling PHP ${php_version} for APK system"

      # shellcheck disable=SC2046
      apk del $(apk list -I 2>&1 | grep "php${version}zend" | awk '{print $1}' | sed -E -e "s/^(php${version}zend.*?)(-${php_version}\..*)$/\1/g" | tr "\n" " ")
  fi

}

php_exec_command() {

  local php

  if [[ "${args[--php]+abc}" ]]; then
      php=$(get_php_binary "${args[--php]}")
  else
      php=$(get_php_binary)
  fi

  if [[ -z "${php}" ]]; then
      red "No PHP binary found" >&2
      exit 1
  fi

  exec "${php}" "${other_args[*]}"

}

apache_mod_php_install_command() {

  local php_version="${args[php]}"
  if [[ -z "${php_version}" ]]; then
      php_version=$(detect_current_php_version "$(get_php_binary)")
  fi

  green "Installing mod_php for PHP version ${php_version}"

  if is_rhel_compatible; then
      local installer
      installer="$(rhel_installer)"

      if [[ "$(get_rhel_os_name)" == "CentOS" && "$(get_rhel_version)" == "7" ]]; then
          install_epel
      fi

      "${installer}" install -y "php${php_version//[![:digit:]]/}zend-php"
  elif is_ibmi_compatible; then
      yum install -y phpzend-apache-conf
  elif is_deb_compatible; then
      apt-get update
      apt-get install -y "libapache2-mod-php${php_version}-zend"
  elif is_apk_compatible; then
      apk_init_credentials
      apk update
      apk add "php${php_version//[![:digit:]]/}zend-apache2"
  fi

}

apache_mod_php_is_installed_command() {

  local php_version="${args[php]}"
  if [[ -z "${php_version}" ]]; then
      php_version=$(detect_current_php_version "$(get_php_binary)")
  fi

  green "Checking if mod_php is installed for PHP ${php_version}..."

  if is_ibmi_compatible; then
      red "mod_php IS NOT installed for version ${php_version}"
  elif is_mod_php_installed "${php_version}"; then
      green "mod_php IS installed for version ${php_version}"
  else
      red "mod_php IS NOT installed for version ${php_version}"
  fi

}

apache_mod_php_uninstall_command() {

  local php_version="${args[php]}"
  if [[ -z "${php_version}" ]]; then
      php_version=$(detect_current_php_version "$(get_php_binary)")
  fi

  green "Uninstalling mod_php for PHP version ${php_version}"

  if is_rhel_compatible; then
      local installer

      installer="$(rhel_installer)"
      "${installer}" remove -y "php${php_version//[![:digit:]]/}zend-php"
  elif is_ibmi_compatible; then
      yum remove -y phpzend-apache-conf
  elif is_deb_compatible; then
      apt-get remove -y "libapache2-mod-php${php_version}-zend"
  elif is_apk_compatible; then
      apk del "php${php_version//[![:digit:]]/}zend-apache2"
  fi

}

ext_disable_command() {

  local php_version="${args[--php]}"
  if [[ -z "${php_version}" ]]; then
      php_version=$(detect_current_php_version "$(get_php_binary)")
  fi

  local invalid=0
  # shellcheck disable=2154
  for ext in "${other_args[@]}"; do
      local is_valid
      is_valid=$(validate_extension_name "${ext}")
      if [[ -n "${is_valid}" ]]; then
          invalid=1
          echo "${is_valid}" >&2
          continue
      fi
  done

  if [[ $invalid == 1 ]]; then
      red "One or more extension names were invalid" >&2
      exit 1
  fi

  if is_rhel_compatible; then
      local ext
      local installer

      installer=$(rhel_installer)

      for ext in "${other_args[@]}"; do
          local package
          local ext_package_name

          ext_package_name="$(echo "${ext}" | sed 's/_/-/g')"

          # Determine if it was installed via a package
          package="$( \
              yum list installed 2>&1 | \
              grep "php${php_version//[^[:digit:]]/}zend-php-" | \
              awk '{print $1}' | \
              grep -E "${ext_package_name}\." || \
              true)"

          if [[ -n "${package}" ]]; then
              green "Removing extension ${ext} via package manager"
              package="$(echo "${package}" | sed -E -e 's/\..*$//')"
              "${installer}" remove -y "${package}"
          fi
          # - not package? or conf file still present? comment out config file
          local conf_file

          conf_file=$(find "/etc/opt/zend/php${php_version//[![:digit:]]/}zend/php.d" -name '*.ini' -printf '%f\n' | \
              grep -E "^[0-9]+[-_]${ext}.ini" || true)

          if [[ -n "${conf_file}" ]]; then
              green "Disabling the extension ${ext}"
              sed --in-place -E -e "s/^($(get_ext_load_directive ${ext})=${ext}.so)/;\1/" "/etc/opt/zend/php${php_version//[![:digit:]]/}zend/php.d/${conf_file}"
          elif [[ -z "${package}" ]]; then
              green "Extension ${ext} not found; doing nothing"
          fi
      done
  elif is_ibmi_compatible; then
      local ext

      for ext in "${other_args[@]}"; do
          local ext_package_name
          local package

          ext_package_name="$(echo "${ext}" | sed 's/_/-/g')"

          # Determine if it was installed via a package
          package="$( \
              yum list installed 2>&1 | \
              grep "php${php_version//[^[:digit:]]/}zend-php-" | \
              awk '{print $1}' | \
              grep -E "${ext_package_name}\." || \
              true)"

          if [[ -n "${package}" ]]; then
              green "Removing extension ${ext} via package manager"
              package="$(echo "${package}" | sed -E -e 's/\..*$//')"
              yum remove -y "${package}"
          fi
          # - not package? or conf file still present? comment out config file
          local conf_file

          conf_file=$(find "/QOpenSys/etc/php/${php_version//[![:digit:]]/}zend/conf.d" -name '*.ini' -printf '%f\n' | \
              grep -E "^[0-9]+[-_]${ext}.ini" || true)

          if [[ -n "${conf_file}" ]]; then
              green "Disabling the extension ${ext}"
              sed --in-place -E -e "s/^($(get_ext_load_directive ${ext})=${ext}.so)/;\1/" "/QOpenSys/etc/php/${php_version//[![:digit:]]/}zend/conf.d/${conf_file}"
          elif [[ -z "${package}" ]]; then
              green "Extension ${ext} not found; doing nothing"
          fi
      done

      blue "Please restart Apache for these changes to take effect."
      blue "See 'STRTCPSVR SERVER(*HTTP) RESTART(*HTTP)' CL command for more details."
  elif is_deb_compatible; then
      local sapi="${args[--sapi]}"
      green "Disabling the following modules for ${sapi}: ${other_args[*]}"
      phpdismod -v "${php_version}-zend" -s "${sapi}" "${other_args[*]}"
  elif is_apk_compatible; then
      local ext

      for ext in "${other_args[@]}"; do
          local package

          # Determine if it was installed via a package
          package="$( \
              apk list -I "php${php_version//[^[:digit:]]/}zend-"* 2>&1 | \
              awk '{print $1}' | \
              grep -E "${ext}-" || \
              true)"

          if [[ -n "${package}" ]]; then
              green "Removing extension ${ext} via package manager"
              package="$(echo "${package}" | sed -E -e 's/-\d+\.\d+\.\d+.*$//')"
              apk del "${package}"
              # Please note that the configuration file may still remain in place.
          fi
          # - not package? or conf file still present? comment out config file
          local conf_file

          conf_file=$(find "/etc/php/${php_version//[![:digit:]]/}zend/conf.d" -name '*.ini' -printf '%f\n' | \
              grep -E "^[0-9]+[-_]${ext}.ini" || true)

          if [[ -n "${conf_file}" ]]; then
              green "Disabling the extension ${ext}"
              sed --in-place -E -e "s/^($(get_ext_load_directive ${ext})=${ext}.so)/;\1/" "/etc/php/${php_version//[![:digit:]]/}zend/conf.d/${conf_file}"
          elif [[ -z "${package}" ]]; then
              green "Extension ${ext} not found; doing nothing"
          fi
      done
  fi

}

ext_enable_command() {

  local php_version="${args[--php]}"
  if [[ -z "${php_version}" ]]; then
      php_version=$(detect_current_php_version "$(get_php_binary)")
  fi

  local invalid=0
  for ext in "${other_args[@]}"; do
      local is_valid
      is_valid=$(validate_extension_name "${ext}")
      if [[ -n "${is_valid}" ]]; then
          invalid=1
          echo "${is_valid}" >&2
          continue
      fi
  done

  if [[ $invalid == 1 ]]; then
      red "One or more extension names were invalid" >&2
      exit 1
  fi

  if is_rhel_compatible; then
      local ext

      for ext in "${other_args[@]}"; do
          # First check to see if there is a configuration file present
          local conf_file
          local ext_package_name

          ext_package_name="${ext//_/-}"

          conf_file=$(find "/etc/opt/zend/php${php_version//[![:digit:]]/}zend/php.d" -name '*.ini' -printf '%f\n' | \
              grep -E "^[0-9]+[-_]${ext}.ini" || true)

          if [[ -z "${conf_file}" ]]; then
              # Time to install
              local installable
              local installer
              local package

              installable=$(create_installable_extension_list_for_rpm "${php_version}")

              if [[ "${installable}" =~ $ext_package_name ]]; then
                  installer=$(rhel_installer)
                  package="$(is_installable_rpm_package "${php_version}" "${ext_package_name}")"
                  green "Installing ${ext} via package manager"
                  "${installer}" install -y "${package}"
              else
                  green "Installing ${ext} from source"
                  install_extension_for_rhel "${php_version}" "${ext}" "20" "-"
              fi
          else
              # Enable the module
              green "Enabling the extension ${ext}"
              sed --in-place -E -e "s/^;+($(get_ext_load_directive ${ext})=${ext}.so)/\1/" "/etc/opt/zend/php${php_version//[![:digit:]]/}zend/php.d/${conf_file}"
          fi
      done
  elif is_ibmi_compatible; then
      local ext

      for ext in "${other_args[@]}"; do
          # First check to see if there is a configuration file present
          local conf_file
          local ext_package_name

          ext_package_name="${ext//_/-}"

          conf_file=$(find "/QOpenSys/etc/php/${php_version//[![:digit:]]/}zend/conf.d" -name '*.ini' -printf '%f\n' | \
              grep -E "^[0-9]+[-_]${ext}.ini" || true)

          if [[ -z "${conf_file}" ]]; then
              # Time to install
              local installable
              local package

              installable=$(create_installable_extension_list_for_rpm "${php_version}")

              if [[ "${installable}" =~ $ext_package_name ]]; then
                  package="$(is_installable_rpm_package "${php_version}" "${ext_package_name}")"
                  green "Installing ${ext} via package manager"
                  yum install -y "${package}"
              else
                  green "Installing ${ext} from source"
                  install_extension_for_ibmi "${php_version}" "${ext}" "20" "-"
              fi
          else
              # Enable the module
              green "Enabling the extension ${ext}"
              sed --in-place -E -e "s/^;+($(get_ext_load_directive ${ext})=${ext}.so)/\1/" "/QOpenSys/etc/php/${php_version//[![:digit:]]/}zend/conf.d/${conf_file}"
          fi
      done

      blue "Please restart Apache for these changes to take effect."
      blue "See 'STRTCPSVR SERVER(*HTTP) RESTART(*HTTP)' CL command for more details."
  elif is_deb_compatible; then
      local sapi="${args[--sapi]}"
      green "Enabling the following modules for ${sapi}: ${other_args[*]}"
      phpenmod -v "${php_version}-zend" -s "${sapi}" "${other_args[*]}"
  elif is_apk_compatible; then
      local ext

      for ext in "${other_args[@]}"; do
          # First check to see if there is a configuration file present
          local conf_file

          conf_file=$(find "/etc/php/${php_version//[![:digit:]]/}zend/conf.d" -name '*.ini' -printf '%f\n' | \
              grep -E "^([0-9]+[-_])?${ext}.ini" || true)

          if [[ -z "${conf_file}" ]]; then
              # Time to install
              local installable
              local packages=()

              installable=$(create_installable_extension_list_for_apk "${php_version}")

              if [[ "${installable}" =~ $ext ]]; then
                  mapfile -t packages < <(is_installable_apk_package "${php_version}" "${ext}")

                  green "Installing ${ext} via package manager"
                  apk_init_credentials
                  apk add "${packages[@]}"
                  # Not all extensions have been enabled by default, therefore we force-enable it below
                  conf_file=$(find "/etc/php/${php_version//[![:digit:]]/}zend/conf.d" -name '*.ini' -printf '%f\n' | \
                      grep -E "^([0-9]+[-_])?${ext}.ini" || true)
              else
                  green "Installing ${ext} from source"
                  apk_init_credentials
                  install_extension_for_apk "${php_version}" "${ext}" "20" "-"
                  continue
              fi
          fi
          # Enable the module
          green "Enabling the extension ${ext}"
          sed --in-place -E -e "s/^;+($(get_ext_load_directive ${ext})=${ext}.so)/\1/" "/etc/php/${php_version//[![:digit:]]/}zend/conf.d/${conf_file}"
      done
  fi

}

ext_install_command() {

  # shellcheck enable=SC1010,SC1009,SC1054,SC1083,SC1073,SC1072,SC1036
  local php_version="${args[--php]}"
  if [[ -z "${php_version}" ]]; then
      php_version=$(detect_current_php_version "$(get_php_binary)")
  fi

  if is_rhel_compatible; then
      local installer
      local installable
      local module

      declare -A package_map=(
          ["bz2"]="common"
          ["calendar"]="common"
          ["curl"]="common"
          ["ctype"]="common"
          ["date"]="common"
          ["dom"]="xml"
          ["exif"]="common"
          ["fileinfo"]="common"
          ["filter"]="common"
          ["ftp"]="common"
          ["gettext"]="common"
          ["hash"]="common"
          ["iconv"]="common"
          ["json"]="common"
          ["libxml"]="common"
          ["mysqli"]="mysqlnd"
          ["oci8"]="oci8"
          ["opcache"]="opcache"
          ["openssl"]="common"
          ["pcntl"]="common"
          ["pcre"]="common"
          ["pdo-dblib"]="pdo-dblib"
          ["pdo_dblib"]="pdo-dblib"
          ["pdo-oci"]="pdo-oci"
          ["pdo_oci"]="pdo-oci"
          ["phar"]="common"
          ["phpdbg"]="dbg"
          ["posix"]="process"
          ["readline"]="common"
          ["redis"]="pecl-redis"
          ["redis5"]="pecl-redis5"
          ["redis6"]="pecl-redis6"
          ["reflection"]="common"
          ["session"]="common"
          ["shmop"]="process"
          ["simplexml"]="xml"
          ["sockets"]="common"
          ["spl"]="common"
          ["sqlite3"]="pdo"
          ["sysvmsg"]="process"
          ["sysvsem"]="process"
          ["sysvshm"]="process"
          ["tokenizer"]="common"
          ["xml"]="xml"
          ["xmlreader"]="xml"
          ["xmlrpc"]="xml"
          ["xmlwriter"]="xml"
          ["xsl"]="xml"
          ["zlib"]="common"
      )

      local epel_packages=(
          "imagick"
          "imap"
          "memcached"
          "mongodb"
          "pdo_dblib"
          "pdo-dblib"
          "redis"
          "redis5"
          "redis6"
          "sodium"
          "tidy"
      )

      green "Installing the following extensions: ${other_args[*]}"
      installer="$(rhel_installer)"
      installable=$(create_installable_extension_list_for_rpm "${php_version}")

      for module in "${other_args[@]}"; do
          local ext_version="-"
          local name
          local package
          local pattern
          local priority=''

          name=$(echo -n "${module}" | sed -E 's/^([0-9]+-){0,1}(.*)/\2/' | sed -E 's/(.*)(-[^-]+)$/\1/')

          pattern='^([0-9]+)-'
          if [[ "${module}" =~ $pattern ]]; then
              priority="${BASH_REMATCH[1]}"
          fi

          pattern="${name}-([^-]+)$"
          if [[ "${module}" =~ $pattern ]]; then
              ext_version="${BASH_REMATCH[1]}"
          fi

          green "Installing extension '${name}'"
          green "- Detected priority: '${priority}'"
          green "- Detected version: '${ext_version}'"

          if [[ -z "${priority}" && "${ext_version}" == "-" && -n "${package_map[$name]+abc}" ]]; then
              # Installable package from map
              if [[ "${package_map[$name]}" == "common" ]]; then
                  green  "The package ${name} is part of the common package; skipping"
              else
                  if [[ "${epel_packages[@]}" =~ $name ]]; then
                      if ! is_epel_enabled; then
                          green "Enabling EPEL repository"
                          install_epel
                      fi
                  fi

                  package="php${php_version//./}zend-php-${package_map[$name]}"

                  green "Installing extension ${module} via package manager"
                  "${installer}" install -y "${package}"
              fi
          elif [[ -z "${priority}" && "${ext_version}" == "-" && "${installable}" =~ $name ]]; then
              if [[ "${epel_packages[@]}" =~ $name ]]; then
                  if ! is_epel_enabled; then
                      green "Enabling EPEL repository"
                      install_epel
                  fi
              fi

              # Installable package
              package="$(is_installable_rpm_package "${php_version}" "${module}")"

              green "Installing extension ${module} via package manager"
              "${installer}" install -y "${package}"
          else
              # PECL
              if [[ -z "${priority}" ]]; then
                  priority=20
              fi

              green "Installing extension ${module} from source"
              install_extension_for_rhel "${php_version}" "${name}" "${priority}" "${ext_version}"
          fi
      done
  elif is_ibmi_compatible; then
      local installable
      local module

      declare -A package_map=(
          ["bz2"]="common"
          ["calendar"]="common"
          ["curl"]="common"
          ["ctype"]="common"
          ["date"]="common"
          ["dom"]="xml"
          ["exif"]="common"
          ["fileinfo"]="common"
          ["filter"]="common"
          ["ftp"]="common"
          ["gd"]="gd"
          ["gettext"]="common"
          ["gmp"]="gmp"
          ["hash"]="common"
          ["ibm_db2"]="pecl-ibm-db2"
          ["iconv"]="common"
          ["igbinary"]="pecl-igbinary"
          ["imagick"]="pecl-imagick"
          ["imap"]="imap"
          ["intl"]="intl"
          ["json"]="common"
          ["ldap"]="ldap"
          ["libxml"]="common"
          ["mbstring"]="mbstring"
          ["mongodb"]="mongodb"
          ["mysqli"]="mysqlnd"
          ["oauth"]="pecl-oauth"
          ["oci8"]="oci8"
          ["odbc"]="odbc"
          ["opcache"]="opcache"
          ["openssl"]="common"
          ["pcntl"]="common"
          ["pcre"]="common"
          ["pdo"]="common"
          ["pdo_dblib"]="pdo-dblib"
          ["pdo_odbc"]="pdo-odbc"
          ["pdo_pgsql"]="pdo-pgsql"
          ["pdo_sqlite"]="common"
          ["pgsl"]="pgsql"
          ["phar"]="common"
          ["posix"]="process"
          ["pspell"]="pspell"
          ["readline"]="common"
          ["redis"]="pecl-redis"
          ["reflection"]="common"
          ["session"]="common"
          ["shmop"]="process"
          ["simplexml"]="xml"
          ["soap"]="soap"
          ["sockets"]="common"
          ["sodium"]="common"
          ["spl"]="common"
          ["sqlite3"]="common"
          ["ssh2"]="pecl-ssh2"
          ["sysvmsg"]="process"
          ["sysvsem"]="process"
          ["sysvshm"]="process"
          ["tidy"]="tidy"
          ["tokenizer"]="common"
          ["xdebug"]="pecl-xdebug"
          ["xml"]="xml"
          ["xmlreader"]="xml"
          ["xmlrpc"]="xml"
          ["xmlwriter"]="xml"
          ["xsl"]="xml"
          ["zip"]="zip"
          ["zlib"]="common"
          ["zmail"]="common"
      )

      green "Installing the following extensions: ${other_args[*]}"
      installable=$(create_installable_extension_list_for_rpm "${php_version}")

      for module in "${other_args[@]}"; do
          local ext_version="-"
          local name
          local package
          local pattern
          local priority=''

          name=$(echo -n "${module}" | sed -E 's/^([0-9]+-){0,1}(.*)/\2/' | sed -E 's/(.*)(-[^-]+)$/\1/')

          pattern='^([0-9]+)-'
          if [[ "${module}" =~ $pattern ]]; then
              priority="${BASH_REMATCH[1]}"
          fi

          pattern="${name}-([^-]+)$"
          if [[ "${module}" =~ $pattern ]]; then
              ext_version="${BASH_REMATCH[1]}"
          fi

          green "Installing extension '${name}'"
          green "- Detected priority: '${priority}'"
          green "- Detected version: '${ext_version}'"

          if [[ -z "${priority}" && "${ext_version}" == "-" && -n "${package_map[$name]+abc}" ]]; then
              # Installable package from map
              if [[ "${package_map[$name]}" == "common" ]]; then
                  green  "The package ${name} is part of the common package; skipping"
              else
                  package="php${php_version//./}zend-php-${package_map[$name]}"

                  green "Installing extension ${module} via package manager"
                  yum install -y "${package}"
              fi
          elif [[ -z "${priority}" && "${ext_version}" == "-" && "${installable}" =~ $name ]]; then
              # Installable package
              package="$(is_installable_rpm_package "${php_version}" "${module}")"

              green "Installing extension ${module} via package manager"
              yum install -y "${package}"
          else
              # PECL
              if [[ -z "${priority}" ]]; then
                  priority=20
              fi

              green "Installing extension ${module} from source"
              install_extension_for_ibmi "${php_version}" "${name}" "${priority}" "${ext_version}"
          fi
      done

      blue "Please restart Apache for these changes to take effect."
      blue "See 'STRTCPSVR SERVER(*HTTP) RESTART(*HTTP)' CL command for more details."
  elif is_deb_compatible; then
      local installable
      local module
      local sapi="${args[--sapi]}"

      declare -A package_map=(
          ["calendar"]="common"
          ["ctype"]="common"
          ["date"]="common"
          ["dom"]="xml"
          ["exif"]="common"
          ["ffi"]="common"
          ["fileinfo"]="common"
          ["filter"]="common"
          ["ftp"]="common"
          ["gettext"]="common"
          ["hash"]="common"
          ["iconv"]="common"
          ["json"]="common"
          ["libxml"]="common"
          ["mysqli"]="mysql"
          ["mysqlnd"]="mysql"
          ["oci8"]="oci8"
          ["openssl"]="common"
          ["pcntl"]="common"
          ["pcre"]="common"
          ["pdo"]="common"
          ["pdo_oci"]="pdo-oci"
          ["pdo-oci"]="pdo-oci"
          ["phar"]="common"
          ["posix"]="common"
          ["reflection"]="common"
          ["shmop"]="common"
          ["simplexml"]="xml"
          ["sockets"]="common"
          ["sodium"]="common"
          ["spl"]="common"
          ["sysvmsg"]="common"
          ["sysvsem"]="common"
          ["sysvshm"]="common"
          ["xml"]="xml"
          ["xmlreader"]="xml"
          ["xmlrpc"]="xml"
          ["xmlwriter"]="xml"
          ["zlib"]="common"
      )

      green "Installing the following extensions for ${sapi}: ${other_args[*]}"
      installable=$(create_installable_extension_list_for_deb "${php_version}")

      apt-get update > /dev/null 2>&1
      for module in "${other_args[@]}"; do
          local ext_version="-"
          local name
          local package
          local pattern
          local priority=''

          name=$(echo -n "${module}" | sed -E 's/^([0-9]+-){0,1}(.*)/\2/' | sed -E 's/(.*)(-[^-]+)$/\1/')

          pattern='^([0-9]+)-'
          if [[ "${module}" =~ $pattern ]]; then
              priority="${BASH_REMATCH[1]}"
          fi

          pattern="${name}-([^-]+)$"
          if [[ "${module}" =~ $pattern ]]; then
              ext_version="${BASH_REMATCH[1]}"
          fi

          green "Installing extension '${name}'"
          green "- Detected priority: '${priority}'"
          green "- Detected version: '${ext_version}'"

          if [[ -z "${priority}" && "${ext_version}" == "-" && -n "${package_map[$name]+abc}" ]]; then
              if [[ "${package_map[$name]}" == "common" ]]; then
                  green  "The package ${name} is part of the common package; skipping"
              else
                  # Installable package from map
                  package="php${php_version}-zend-${package_map[$name]}"

                  green "Installing ${package}..."
                  apt-get install -y "${package}"
              fi
          elif [[ -z "${priority}" && "${ext_version}" == "-" && "${installable}" =~ $name ]]; then
              # Installable package at default priority and version provided
              green "Checking for availability via package manager"
              package=$(apt-cache search --names-only "php${php_version}-zend" | \
                  cut -d' ' -f1 | \
                  grep -E "\-${name}$" | \
                  tr "\n" " " | \
                  sed 's/ *$//g')
              if [[ -z "${package}" || "${package}" =~ [[:space:]] ]]; then
                  red "No package found, or more than one package found (found '${package}'); cannot proceed" >&2
                  exit 1
              else
                  green "Installing ${package}..."
                  apt-get install -y "${package}"
              fi
          else
              if [[ -z "${priority}" ]]; then
                  priority=20
              fi

              green "Installing from source"
              install_extension_for_deb "${php_version}" "${name}" "${priority}" "${ext_version}"

              green "Enabling extension"
              phpenmod -v "${php_version}-zend" -s "${sapi}" "${name}"
          fi
      done
  elif is_apk_compatible; then
      local installable
      local module

      declare -A package_map=(
          ["apcu"]="pecl-apcu"
          ["ctype"]="common"
          ["date"]="common"
          ["dblib"]="pdo_dblib"
          ["filter"]="common"
          ["igbinary"]="pecl-igbinary"
          ["imagick"]="pecl-imagick"
          ["json"]="common"
          ["libxml"]="xml"
          ["memcached"]="pecl-memcached"
          ["mongo"]="pecl-mongodb"
          ["mongodb"]="pecl-mongodb"
          ["msgpack"]="pecl-msgpack"
          ["oauth"]="pecl-oauth"
          ["pcre"]="common"
          ["phar"]="common"
          ["readline"]="common"
          ["redis"]="pecl-redis"
          ["reflection"]="common"
          ["spl"]="common"
          ["ssh2"]="pecl-ssh2"
          ["xdebug"]="pecl-xdebug"
          ["zlib"]="common"
      )

      green "Installing the following extensions: ${other_args[*]}"
      installable=$(create_installable_extension_list_for_apk "${php_version}")

      for module in "${other_args[@]}"; do
          local ext_version="-"
          local name
          local package
          local pattern
          local priority=''

          name=$(echo -n "${module}" | sed -E 's/^([0-9]+-){0,1}(.*)/\2/' | sed -E 's/(.*)(-[^-]+)$/\1/')

          pattern='^([0-9]+)-'
          if [[ "${module}" =~ $pattern ]]; then
              priority="${BASH_REMATCH[1]}"
          fi

          pattern="${name}-([^-]+)$"
          if [[ "${module}" =~ $pattern ]]; then
              ext_version="${BASH_REMATCH[1]}"
          fi

          green "Installing extension '${name}'"
          green "- Detected priority: '${priority}'"
          green "- Detected version: '${ext_version}'"

          if [[ -z "${priority}" && "${ext_version}" == "-" && -n "${package_map[$name]+abc}" ]]; then
              # Installable package from map
              if [[ "${package_map[$name]}" == "common" ]]; then
                  green  "The package ${name} is part of the common package; skipping"
              else
                  package="php${php_version//./}zend-${package_map[$name]}"

                  green "Installing extension ${module} via package manager"
                  apk_init_credentials
                  apk add "${package}"
              fi
          elif [[ -z "${priority}" && "${ext_version}" == "-" && "${installable}" =~ $name ]]; then
              local packages=()

              # Installable package(s)
              mapfile -t packages < <(is_installable_apk_package "${php_version}" "${module}")

              green "Installing extension ${module} via package manager"
              apk_init_credentials
              apk add "${packages[@]}"
          else
              # PECL
              if [[ -z "${priority}" ]]; then
                  priority=20
              fi

              green "Installing extension ${module} from source"
              install_extension_for_apk "${php_version}" "${name}" "${priority}" "${ext_version}"
          fi
      done
  fi

}

ext_list_enabled_command() {

  local sapi
  local php_version="${args[php]}"
  if [[ -z "${php_version}" ]]; then
      php_version=$(detect_current_php_version "$(get_php_binary)")
  fi
  local fpm=${args[--fpm]}

  if is_rhel_compatible; then
      # RHEL does not differentiate between CLI and PHP versions for purposes of
      # extension enablement
      list_enabled_extensions_for_rhel "${php_version}" | sort
  elif is_ibmi_compatible; then
      find "/QOpenSys/etc/php/${php_version//[![:digit:]]/}zend/conf.d" -name '*.ini' -exec basename {} \; | \
          grep -vE '^[^0-9]' | \
          sed -E 's/[[:digit:]]+\-([^.]+)\.ini/\1/' | \
          sort
  elif is_deb_compatible; then
      if [[ $fpm ]]; then
          sapi=fpm
      else
          sapi=cli
      fi

      find "/etc/php/${php_version}-zend/${sapi}/conf.d" -name '*.ini' -printf '%f\n' | \
          grep -vE '^[^0-9]' | \
          sed -E 's/[[:digit:]]+\-([^.]+)\.ini/\1/' | \
          sort
  elif is_apk_compatible; then
      # APK does not differentiate between CLI and PHP versions for purposes of
      # extension enablement
      list_enabled_extensions_for_apk "${php_version}" | sort
  fi

}

ext_list_packages_command() {

  local php_version="${args[php]}"
  if [[ -z "${php_version}" ]]; then
      php_version=$(detect_current_php_version "$(get_php_binary)")
  fi

  create_installable_extension_list "${php_version}"

}

fpm_config_command() {

  local php_version="${args[php]}"
  if [[ -z "${php_version}" ]]; then
      php_version=$(detect_current_php_version "$(get_php_binary)")
  fi

  green "Using PHP version ${php_version}"

  if is_rhel_compatible; then
      # CLI and FPM share same php.ini on RHEL systems
      # shellcheck disable=SC2153
      if [[ -z "${EDITOR}" ]]; then
          red "No editor configured; please install nano, vim, or your favorite command line editor, and set export the EDITOR env variable" >&2
          exit 1
      else
          # CLI and FPM share same php.ini on RHEL systems
          exec "${EDITOR}" "/etc/opt/zend/php${php_version//[![:digit:]]/}zend/php-fpm.conf"
      fi
  elif is_ibmi_compatible; then
      if [[ -z "${EDITOR}" ]]; then
          red "No editor configured; please install nano, vim, or your favorite command line editor, and set export the EDITOR env variable" >&2
          exit 1
      else
          exec "${EDITOR}" "/QOpenSys/etc/php/${php_version//[![:digit:]]/}zend/php-fpm.conf"
      fi
  elif is_deb_compatible; then
      local editor

      editor=$(command -v editor)
      if [[ -z "${editor}" ]]; then
          red "No editor configured; please install nano, vim, or your favorite command line editor" >&2
          exit 1
      else
          exec "${editor}" "/etc/php/${php_version}-zend/fpm/php-fpm.conf"
      fi
  elif is_apk_compatible; then
      # shellcheck disable=SC2153
      if [[ -z "${EDITOR}" ]]; then
          red "No editor configured; please install nano, vim, or your favorite command line editor, and set export the EDITOR env variable" >&2
          exit 1
      else
          # CLI and FPM share same php.ini on RHEL systems
          exec "${EDITOR}" "/etc//php/${php_version//[![:digit:]]/}zend/php-fpm.conf"
      fi
  fi

}

fpm_install_command() {

  local php_version="${args[php]}"
  if [[ -z "${php_version}" ]]; then
      php_version=$(detect_current_php_version "$(get_php_binary)")
  fi

  green "Installing FPM for PHP version ${php_version}"

  if is_rhel_compatible; then
      local installer
      installer="$(rhel_installer)"
      install_epel
      "${installer}" install -y fcgi "php${php_version//[![:digit:]]/}zend-php-fpm"
  elif is_ibmi_compatible; then
      yum install -y "php${php_version//[![:digit:]]/}zend-php-fpm"
  elif is_deb_compatible; then
      apt-get update
      apt-get install -y "php${php_version}-zend-fpm"
  elif is_apk_compatible; then
      apk_init_credentials
      apk update
      apk add "php${php_version//[![:digit:]]/}zend-fpm"

      if apk_is_default_php_version "${php_version}"; then
          ln -fs "/usr/sbin/php-fpm${php_version//[![:digit:]]/}zend" "/usr/sbin/php-fpm"
      fi
  fi

}

fpm_is_installed_command() {

  local php_version="${args[php]}"
  if [[ -z "${php_version}" ]]; then
      php_version=$(detect_current_php_version "$(get_php_binary)")
  fi

  green "Checking if FPM is installed for PHP ${php_version}..."

  if is_fpm_installed "${php_version}"; then
      green "FPM IS installed for version ${php_version}"
  else
      red "FPM IS NOT installed for version ${php_version}"
  fi

}

fpm_uninstall_command() {

  local php_version="${args[php]}"
  if [[ -z "${php_version}" ]]; then
      php_version=$(detect_current_php_version "$(get_php_binary)")
  fi

  green "Uninstalling FPM for PHP version ${php_version}"

  if is_rhel_compatible; then
      local installer

      installer="$(rhel_installer)"
      "${installer}" remove -y "php${php_version//[![:digit:]]/}zend-php-fpm"
  elif is_ibmi_compatible; then
      yum remove -y "php${php_version//[![:digit:]]/}zend-php-fpm"
  elif is_deb_compatible; then
      apt-get remove -y "php${php_version}-zend-fpm"
  elif is_apk_compatible; then
      apk del "php${php_version//[![:digit:]]/}zend-fpm"
  fi

}

repo_credentials_command() {

  green "Preparing to install ZendPHP repository credentials"

  local account="${args[--account]}"
  local password="${args[--password]}"
  local rpmrepofile=''

  if is_rhel_compatible; then
      rpmrepofile=/etc/yum.repos.d/zendphp.repo
  elif is_ibmi_compatible; then
      rpmrepofile=/QOpenSys/etc/yum/repos.d/zendphp.repo
      export PATH=/QOpenSys/pkgs/bin:$PATH
  fi

  if [ "$rpmrepofile" != "" ]; then
      if [[ ! -f $rpmrepofile ]]; then
          red "You have not yet installed the ZendPHP package repository!" >&2
          red "Please run zendphpctl repo-install" >&2
          exit 1
      fi
      # Replace username and password if these are already included in the repofile
      # or else add in the repo section after baseurl line
      if grep -q "^username=" $rpmrepofile; then
          # Escape variables
          account="${account//&/\\&}"; account="${account//\\/\\\\}";account="${account//\//\\\/}"
          password="${password//&/\\&}"; password="${password//\\/\\\\}";password="${password//\//\\\/}"
          sed -i "s/^\(username=\).*/\1$account/;s/^\(password=\).*/\1$password/" $rpmrepofile
          green "ZendPHP credentials replaced!"
      else
          sed -i "/^baseurl/a username=$account\npassword=$password" $rpmrepofile
          green "ZendPHP credentials installed!"
      fi
  elif is_deb_compatible; then
      # This is intentionally valid for repos.zend.com only as the zendphp credentials are
      # valid for this site only, currently. This is to be revisited when that changes.
      echo "machine https://repos.zend.com/zendphp login ${account} password ${password}" > /etc/apt/auth.conf.d/zendphp.conf
      green "ZendPHP credentials installed!"
  elif is_apk_compatible; then
      echo "HTTP_AUTH=basic:*:${account}:${password}" > /etc/apk/zendrepo.rc
      green "ZendPHP credentials installed!"
  fi

}

repo_install_command() {

  green "Preparing to install ZendPHP repository"

  local account="${args[--account]}"
  local password="${args[--password]}"
  local uri_list="${args[--uri]}"

  if [[ -n "${account}" && -z "${password}" ]] || [[ -z "${account}" && -n "${password}" ]]; then
      red "BOTH --account AND --password must be provided if you are providing credentials." >&2
      exit 2
  fi

  local -a uri_array
  if [[ -n "${uri_list}" ]]; then
      read -r -a uri_array <<< "${uri_list}"
  else
      uri_array=("https://repos.zend.com/zendphp")
  fi
  for i in "${!uri_array[@]}"; do
      uri_array[$i]="${uri_array[$i]%/}"
  done

  local auth_block=""
  [[ -n "${account}" && -n "${password}" ]] && auth_block="username=${account}"$'\n'"password=${password}" || true

  if is_rhel_compatible; then
      local os
      local os_version
      local installer

      os="$(get_rhel_os_name)"
      os_version="$(get_rhel_version)"
      installer="$(rhel_installer)"

      if [[ "${os}" == "Amazon" ]]; then
          os_version=7
      fi
      case "$os_version" in
          "10") repokey=zend-2025.key;;
          *) repokey=zend.key;;
      esac

      > /etc/yum.repos.d/zendphp.repo
      local counter=1
      for uri in "${uri_array[@]}"; do
          local name_suffix=""
          if [[ ${counter} -gt 1 ]]; then
              name_suffix="_${counter}"
          fi
          get_rhel_repo_template "${repokey}" "${uri}" "${name_suffix}" "${os_version}" "${auth_block}" >> /etc/yum.repos.d/zendphp.repo
          (( counter++ ))
      done

      if [[ "${os_version}" -gt 7 ]];then
          "${installer}" -y install dnf-plugins-core

          case $os in
          "AlmaLinux")
              "${installer}" install -y yum-utils
              ;;
          "Rocky")
              "${installer}" install -y findutils yum-utils
              ;;
          "RHEL")
              "${installer}" install -y yum-utils
              ;;
          esac
      else
          case $os in
          "Amazon")
              "${installer}" -y install scl-utils tar yum-utils
              ;;
          "Oracle")
              oracle7_install_base_repos
              "${installer}" -y install scl-utils
              ;;
          "RHEL")
              "${installer}" -y install environment-modules tar yum-utils
              yum-config-manager --enable rhel-server-rhscl-7-rpms
              ;;
          *)
              "${installer}" -y install centos-release-scl-rh
              ;;
          esac
      fi

      green "ZendPHP repository installed and configured!"
  elif is_ibmi_compatible; then
      local os_version

      os_version="$(get_ibmi_version)"

      > /QOpenSys/etc/yum/repos.d/zendphp.repo
      local counter=1
      for uri in "${uri_array[@]}"; do
          local name_suffix=""
          if [[ ${counter} -gt 1 ]]; then
              name_suffix="_${counter}"
          fi
          get_ibmi_repo_template "${uri}" "${name_suffix}" "${os_version}" "${auth_block}" >> /QOpenSys/etc/yum/repos.d/zendphp.repo
          (( counter++ ))
      done

      yum clean metadata

      green "ZendPHP repository installed and configured!"
  elif is_deb_compatible; then
      local os
      local os_version

      # Get OS and version
      if grep -q "ID=debian" /etc/os-release; then
          os_version=$(grep -E "VERSION_ID=\"(9|10|11|12|13)" /etc/os-release | sed -E 's/[^0-9]//g')
          if [ -z "${os_version}" ]; then
              red "Unsupported Debian version detected; cannot install ZendPHP repository" >&2
              exit 3
          fi
          os=debian
      elif grep -q "ID=ubuntu" /etc/os-release; then
          os_version=$(grep -E "VERSION_ID=\"(16|18|20|22|24|26)\.04" /etc/os-release | sed -E 's/[^0-9]//g')
          if [ -z "${os_version}" ]; then
              red "Unsupported Ubuntu version detected; cannot install ZendPHP repository" >&2
              exit 3
          fi
          os=ubuntu
      else
          red "Unrecognized Debian-like operating system; cannot install ZendPHP repository" >&2
          exit 3
      fi

      if [[ -n "${account}" && -n "${password}" ]]; then
          local authfile
          authfile=/etc/apt/auth.conf.d/zendphp.conf
          > ${authfile}
          for uri in "${uri_array[@]}"; do
              grep -q "^machine\ ${uri}\ " "${authfile}" || echo "machine ${uri} login ${account} password ${password}" >> ${authfile}
          done
      fi

      export DEBIAN_FRONTEND=noninteractive
      case "$os-$os_version" in
          "ubuntu-2404" | "ubuntu-2604" | "debian-13") repokey=zend-2025.key;;
          *) repokey=zend.key;;
      esac

      # When the repository key already exists and has changed then it must be updated before `apt-get update` or else it would fail
      if [ -f /usr/share/keyrings/zend.gpg ] && command gpg --version >/dev/null 2>/dev/null; then
          blue "Updating the repository key"
          curl -sS https://repos.zend.com/${repokey} | gpg --dearmor > /usr/share/keyrings/zend.gpg || red "Failed updating the key file"
          have_key=1
      fi

      apt-get update
      apt-get -y install apt-transport-https ca-certificates curl gnupg

      [ "$have_key" == "1" ] || curl -sS https://repos.zend.com/${repokey} | gpg --dearmor > /usr/share/keyrings/zend.gpg

      > /etc/apt/sources.list.d/zendphp.list
      for uri in "${uri_array[@]}"; do
          echo "deb [signed-by=/usr/share/keyrings/zend.gpg] ${uri}/deb_${os}${os_version}/ zendphp non-free" >> /etc/apt/sources.list.d/zendphp.list
      done

      apt-get update

      green "ZendPHP repository installed and configured!"
  elif is_apk_compatible; then
      if ! grep -q -E "VERSION_ID=3\.(16|18|20|22|24)\." /etc/os-release; then
          red "Unsupported Alpine version detected; cannot install ZendPHP repository" >&2
          exit 3
      fi
      os=alpine
      os_version=$(grep -E "VERSION_ID=3\.(16|18|20|22|24)" /etc/os-release | sed -E 's/[^0-9.]//g' | sed -E 's/^([0-9]+)\.([0-9]+).*$/\1\2/')

      wget "https://repos.zend.com/zendphp/apk_alpine${os_version}/zendphp-alpine-devel.rsa.pub" -O /etc/apk/keys/zendphp-alpine-devel.rsa.pub

      if [[ -n "${account}" && -n "${password}" ]]; then
          echo "HTTP_AUTH=basic:*:${account}:${password}" > /etc/apk/zendrepo.rc
          green "ZendPHP repository credentials installed"
      fi

      for uri in "${uri_array[@]}"; do
          echo "${uri}/apk_alpine${os_version}/" >> /etc/apk/repositories
      done

      apk update

      blue "Installing utilities required by zendphpctl..."
      apk add coreutils curl findutils grep

      green "ZendPHP repository installed and configured!"
  fi

}

repo_uninstall_command() {

  if is_rhel_compatible; then
      rm -f /etc/yum.repos.d/zendphp.repo
      green "Removed ZendPHP package repository from your operating system"
      echo "NOTE: This action DOES NOT remove already installed ZendPHP packages."
  elif is_ibmi_compatible; then
      rm -f /QOpenSys/etc/yum/repos.d/zendphp.repo
      green "Removed ZendPHP package repository from your operating system"
      echo "NOTE: This action DOES NOT remove already installed ZendPHP packages."
  elif is_deb_compatible; then
      rm -f /etc/apt/sources.list.d/zendphp.list
      if [[ -f /etc/apt/auth.conf.d/zendphp.conf ]]; then
          rm -f /etc/apt/auth.conf.d/zendphp.conf
      fi
      apt-get update
      green "Removed ZendPHP package repository from your operating system"
      echo "NOTE: This action DOES NOT remove already installed ZendPHP packages."
  elif is_apk_compatible; then
      sed --in-place -E -e '/^http.*repos\.zend\.com\/zendphp\/apk_alpine.*$/d' /etc/apk/repositories
      if [[ -f /etc/apk/zendrepo.rc ]]; then
          rm -f /etc/apk/zendrepo.rc
      fi
      green "Removed ZendPHP package repository from your operating system"
      echo "NOTE: This action DOES NOT remove already installed ZendPHP packages."
  fi

}

zendhq_token_command() {

  local token="${args[token]}"
  local no_restart=${args[--no-restart]}

  local hashed_token
  local timestamp

  hashed_token="$(echo -n "${token}" | sha256sum | awk '{ print $1 }')"
  timestamp="$(date +%FT%k%M%S)"

  green "Backing up zendhqd.ini file to /opt/zend/zendphp/etc/zendhqd.ini.${timestamp}"
  cp /opt/zend/zendphp/etc/zendhqd.ini "/opt/zend/zendphp/etc/zendhqd.ini.${timestamp}"

  green "Updating token"
  sed --in-place -E -e "s/^(zendhqd.session.auth_token_hash\s*=\s*).*$/\1${hashed_token}/" /opt/zend/zendphp/etc/zendhqd.ini
  yellow "This command is deprecated and may not work as expected"
  yellow "Please use: zendhqctl access user password <username> <password>"
  if /opt/zend/zendphp/bin/zendhqctl access user print admin |grep 'admin\s*no\ password' >>/dev/null; then
  yellow "Token is currently set"
  else
  red "Token is written to the ini file but it will not be used as it is overriden by database setup"
  fi

  if [[ ! $no_restart ]]; then
      if is_apk_compatible; then
          /etc/init.d/zendhq reload
      else
          systemctl restart zendhqd
      fi
  fi

  green "Done!"

}

zray_plugin_install_command() {

  local php_version="${args[--php]}"
  if [[ -z "${php_version}" ]]; then
      php_version=$(detect_current_php_version "$(get_php_binary)")
  fi

  green "Installing Z-Ray plugins"
  green "Detected PHP version: ${php_version}"

  if is_rhel_compatible; then
      local installer
      installer="$(rhel_installer)"
      "${installer}" install -y "php${php_version//[![:digit:]]/}zend-php-zendhq" php-zray-plugins
  elif is_deb_compatible; then
      apt-get update
      apt-get install -y "php${php_version}-zend-zendhq" php-zray-plugins
  elif is_apk_compatible; then
      apk update
      apk add php-zray-plugins
      ensure_zray_plugin_tree
  fi

}

zray_plugin_list_command() {

  local enabled_only=${args[--enabled]}

  local plugins_path=/opt/zend/zendphp/plugins

  if [[ ! -d "${plugins_path}" ]]; then
      blue "No Z-Ray plugins are installed; please run the zendphpctl zray-plugins-install command"
  elif [[ $enabled_only ]]; then
      ensure_zray_plugin_tree

      green "Enabled Z-Ray plugins:"
      for plugin in "${plugins_path}/enabled/"*; do
          if [[ -L "${plugin}" || -d "${plugin}" ]]; then
              basename "${plugin}"
          fi
      done
  else
      ensure_zray_plugin_tree

      green "Available Z-Ray plugins:"
      for plugin in "${plugins_path}/available/"*; do
          if [[ -d "${plugin}" ]]; then
              basename "${plugin}"
          fi
      done
  fi

}

zray_plugin_disable_command() {


  local invalid=0

  ensure_zray_plugin_tree

  for plugin in "${other_args[@]}"; do
      local is_valid
      is_valid=$(validate_zray_plugin_name "${plugin}" "enabled")
      if [[ -n "${is_valid}" ]]; then
          invalid=1
          echo "${is_valid}" >&2
          continue
      fi
  done

  if [[ $invalid == 1 ]]; then
      red "One or more plugin names were invalid" >&2
      exit 1
  fi

  local errors=0
  local plugins_path=/opt/zend/zendphp/plugins
  local available="${plugins_path}/available"
  local enabled="${plugins_path}/enabled"

  for plugin in "${other_args[@]}"; do
      if [[ ! -e "${enabled}/${plugin}" ]]; then
          # Not "enabled"; skip
          blue "Plugin ${plugin} is not currently enabled; skipping"
      elif [[ -L "${enabled}/${plugin}" ]]; then
          # Symlink; remove
          green "Disabling plugin ${plugin}"
          unlink "${enabled}/${plugin}"
      elif [[ -f "${enabled}/${plugin}" ]]; then
          # Is a file; skip
          red "Plugin ${plugin} is not a valid plugin; skipping"
          errors=2
      else
          # Plugin is a directory
          # Does an "available" plugin already exist?
          if [[ -e "${available}/${plugin}" ]]; then
              red "Cannot disable plugin ${plugin}; is a directory, and another entry by that name is in the available plugins list"
              errors=3
          else
              mv "${enabled}/${plugin}" "${available}/$plugin}"
          fi
      fi
  done

  if [[ $errors -gt 0 ]]; then
      red "One or more plugins were invalid; check logs for details"
      exit $errors
  fi

}

zray_plugin_enable_command() {

  local invalid=0

  ensure_zray_plugin_tree

  for plugin in "${other_args[@]}"; do
      local is_valid
      is_valid=$(validate_zray_plugin_name "${plugin}")
      if [[ -n "${is_valid}" ]]; then
          invalid=1
          echo "${is_valid}" >&2
          continue
      fi
  done

  if [[ $invalid == 1 ]]; then
      red "One or more plugin names were invalid" >&2
      exit 1
  fi

  local errors=0
  local plugins_path=/opt/zend/zendphp/plugins
  local available="${plugins_path}/available"
  local enabled="${plugins_path}/enabled"

  for plugin in "${other_args[@]}"; do
      # Check if it is already enabled; if so skip
      if [[ -d "${enabled}/${plugin}" ]]; then
          blue "Plugin ${plugin} is already enabled; skipping"
      elif [[ ! -d "${available}/${plugin}" ]]; then
          red "Plugin ${plugin} is not a directory; skipping"
          errors=1
      else
          green "Enabling plugin ${plugin}"
          ln -s "${available}/${plugin}" "${enabled}/${plugin}"
      fi
  done

  if [[ $errors -gt 0 ]]; then
      red "One or more plugins were invalid; check logs for details"
      exit 2
  fi

}

parse_requirements() {

  while [[ $# -gt 0 ]]; do
    key="$1"
    case "$key" in
      --version | -v)
        version_command
        exit
        ;;

      --help | -h)
        long_usage=yes
        zendphpctl_usage
        exit
        ;;

      *)
        break
        ;;

    esac
  done

  action=${1:-}

  case $action in
    -*) ;;

    completions)
      action="completions"
      shift
      zendphpctl_completions_parse_requirements "$@"
      shift $#
      ;;

    self-update)
      action="self-update"
      shift
      zendphpctl_self_update_parse_requirements "$@"
      shift $#
      ;;

    apache)
      action="apache"
      shift
      zendphpctl_apache_parse_requirements "$@"
      shift $#
      ;;

    ext)
      action="ext"
      shift
      zendphpctl_ext_parse_requirements "$@"
      shift $#
      ;;

    fpm)
      action="fpm"
      shift
      zendphpctl_fpm_parse_requirements "$@"
      shift $#
      ;;

    php)
      action="php"
      shift
      zendphpctl_php_parse_requirements "$@"
      shift $#
      ;;

    repo)
      action="repo"
      shift
      zendphpctl_repo_parse_requirements "$@"
      shift $#
      ;;

    zendhq)
      action="zendhq"
      shift
      zendphpctl_zendhq_parse_requirements "$@"
      shift $#
      ;;

    zray)
      action="zray"
      shift
      zendphpctl_zray_parse_requirements "$@"
      shift $#
      ;;

    php-config)
      action="php-config"
      shift
      php_config_parse_requirements "$@"
      shift $#
      ;;

    php-list-installed)
      action="php-list-installed"
      shift
      php_list_installed_parse_requirements "$@"
      shift $#
      ;;

    php-set-default)
      action="php-set-default"
      shift
      php_set_default_parse_requirements "$@"
      shift $#
      ;;

    php-install)
      action="php-install"
      shift
      php_install_parse_requirements "$@"
      shift $#
      ;;

    php-uninstall)
      action="php-uninstall"
      shift
      php_uninstall_parse_requirements "$@"
      shift $#
      ;;

    exec)
      action="exec"
      shift
      php_exec_parse_requirements "$@"
      shift $#
      ;;

    apache-mod-php-install)
      action="apache-mod-php-install"
      shift
      apache_mod_php_install_parse_requirements "$@"
      shift $#
      ;;

    apache-mod-php-is-installed)
      action="apache-mod-php-is-installed"
      shift
      apache_mod_php_is_installed_parse_requirements "$@"
      shift $#
      ;;

    apache-mod-php-uninstall)
      action="apache-mod-php-uninstall"
      shift
      apache_mod_php_uninstall_parse_requirements "$@"
      shift $#
      ;;

    ext-disable)
      action="ext-disable"
      shift
      ext_disable_parse_requirements "$@"
      shift $#
      ;;

    ext-enable)
      action="ext-enable"
      shift
      ext_enable_parse_requirements "$@"
      shift $#
      ;;

    ext-install)
      action="ext-install"
      shift
      ext_install_parse_requirements "$@"
      shift $#
      ;;

    ext-list-enabled)
      action="ext-list-enabled"
      shift
      ext_list_enabled_parse_requirements "$@"
      shift $#
      ;;

    ext-list-packages)
      action="ext-list-packages"
      shift
      ext_list_packages_parse_requirements "$@"
      shift $#
      ;;

    fpm-config)
      action="fpm-config"
      shift
      fpm_config_parse_requirements "$@"
      shift $#
      ;;

    fpm-install)
      action="fpm-install"
      shift
      fpm_install_parse_requirements "$@"
      shift $#
      ;;

    fpm-is-installed)
      action="fpm-is-installed"
      shift
      fpm_is_installed_parse_requirements "$@"
      shift $#
      ;;

    fpm-uninstall)
      action="fpm-uninstall"
      shift
      fpm_uninstall_parse_requirements "$@"
      shift $#
      ;;

    repo-credentials)
      action="repo-credentials"
      shift
      repo_credentials_parse_requirements "$@"
      shift $#
      ;;

    repo-install)
      action="repo-install"
      shift
      repo_install_parse_requirements "$@"
      shift $#
      ;;

    repo-uninstall)
      action="repo-uninstall"
      shift
      repo_uninstall_parse_requirements "$@"
      shift $#
      ;;

    zendhq-token)
      action="zendhq-token"
      shift
      zendhq_token_parse_requirements "$@"
      shift $#
      ;;

    zray-plugins-install)
      action="zray-plugins-install"
      shift
      zray_plugin_install_parse_requirements "$@"
      shift $#
      ;;

    zray-plugins-list)
      action="zray-plugins-list"
      shift
      zray_plugin_list_parse_requirements "$@"
      shift $#
      ;;

    zray-plugin-disable)
      action="zray-plugin-disable"
      shift
      zray_plugin_disable_parse_requirements "$@"
      shift $#
      ;;

    zray-plugin-enable)
      action="zray-plugin-enable"
      shift
      zray_plugin_enable_parse_requirements "$@"
      shift $#
      ;;

    "")
      zendphpctl_usage >&2
      exit 1
      ;;

    *)
      printf "invalid command: %s\n" "$action" >&2
      exit 1
      ;;

  esac

  while [[ $# -gt 0 ]]; do
    key="$1"
    case "$key" in

      -?*)
        printf "invalid option: %s\n" "$key" >&2
        exit 1
        ;;

      *)

        printf "invalid argument: %s\n" "$key" >&2
        exit 1

        ;;

    esac
  done

}

zendphpctl_completions_parse_requirements() {

  while [[ $# -gt 0 ]]; do
    key="$1"
    case "$key" in
      --help | -h)
        long_usage=yes
        zendphpctl_completions_usage
        exit
        ;;

      *)
        break
        ;;

    esac
  done

  action="completions"

  while [[ $# -gt 0 ]]; do
    key="$1"
    case "$key" in

      -?*)
        printf "invalid option: %s\n" "$key" >&2
        exit 1
        ;;

      *)

        printf "invalid argument: %s\n" "$key" >&2
        exit 1

        ;;

    esac
  done

}

zendphpctl_self_update_parse_requirements() {

  while [[ $# -gt 0 ]]; do
    key="$1"
    case "$key" in
      --help | -h)
        long_usage=yes
        zendphpctl_self_update_usage
        exit
        ;;

      *)
        break
        ;;

    esac
  done

  missing_deps=

  if ! command -v chmod >/dev/null 2>&1; then
    printf "missing dependency: chmod\n" >&2
    missing_deps=1
  else
    deps['chmod']="$(command -v chmod | head -n1)"
  fi

  if ! command -v chown >/dev/null 2>&1; then
    printf "missing dependency: chown\n" >&2
    missing_deps=1
  else
    deps['chown']="$(command -v chown | head -n1)"
  fi

  if ! command -v curl >/dev/null 2>&1; then
    printf "missing dependency: curl\n" >&2
    missing_deps=1
  else
    deps['curl']="$(command -v curl | head -n1)"
  fi

  if ! command -v mktemp >/dev/null 2>&1; then
    printf "missing dependency: mktemp\n" >&2
    missing_deps=1
  else
    deps['mktemp']="$(command -v mktemp | head -n1)"
  fi

  if ! command -v mv >/dev/null 2>&1; then
    printf "missing dependency: mv\n" >&2
    missing_deps=1
  else
    deps['mv']="$(command -v mv | head -n1)"
  fi

  if ! command -v rm >/dev/null 2>&1; then
    printf "missing dependency: rm\n" >&2
    missing_deps=1
  else
    deps['rm']="$(command -v rm | head -n1)"
  fi

  if ! command -v sha256sum >/dev/null 2>&1; then
    printf "missing dependency: sha256sum\n" >&2
    missing_deps=1
  else
    deps['sha256sum']="$(command -v sha256sum | head -n1)"
  fi

  if [[ -n $missing_deps ]]; then
    exit 1
  fi

  action="self-update"

  while [[ $# -gt 0 ]]; do
    key="$1"
    case "$key" in

      -?*)
        printf "invalid option: %s\n" "$key" >&2
        exit 1
        ;;

      *)

        printf "invalid argument: %s\n" "$key" >&2
        exit 1

        ;;

    esac
  done

}

zendphpctl_apache_parse_requirements() {

  while [[ $# -gt 0 ]]; do
    key="$1"
    case "$key" in
      --help | -h)
        long_usage=yes
        zendphpctl_apache_usage
        exit
        ;;

      *)
        break
        ;;

    esac
  done

  action=${1:-}

  case $action in
    -*) ;;

    mod_php)
      action="mod_php"
      shift
      zendphpctl_apache_mod_php_parse_requirements "$@"
      shift $#
      ;;

    "")
      zendphpctl_apache_usage >&2
      exit 1
      ;;

    *)
      printf "invalid command: %s\n" "$action" >&2
      exit 1
      ;;

  esac

  while [[ $# -gt 0 ]]; do
    key="$1"
    case "$key" in

      -?*)
        printf "invalid option: %s\n" "$key" >&2
        exit 1
        ;;

      *)

        printf "invalid argument: %s\n" "$key" >&2
        exit 1

        ;;

    esac
  done

}

zendphpctl_apache_mod_php_parse_requirements() {

  while [[ $# -gt 0 ]]; do
    key="$1"
    case "$key" in
      --help | -h)
        long_usage=yes
        zendphpctl_apache_mod_php_usage
        exit
        ;;

      *)
        break
        ;;

    esac
  done

  action=${1:-}

  case $action in
    -*) ;;

    install)
      action="install"
      shift
      zendphpctl_apache_mod_php_install_parse_requirements "$@"
      shift $#
      ;;

    is-installed)
      action="is-installed"
      shift
      zendphpctl_apache_mod_php_is_installed_parse_requirements "$@"
      shift $#
      ;;

    uninstall)
      action="uninstall"
      shift
      zendphpctl_apache_mod_php_uninstall_parse_requirements "$@"
      shift $#
      ;;

    "")
      zendphpctl_apache_mod_php_usage >&2
      exit 1
      ;;

    *)
      printf "invalid command: %s\n" "$action" >&2
      exit 1
      ;;

  esac

  while [[ $# -gt 0 ]]; do
    key="$1"
    case "$key" in

      -?*)
        printf "invalid option: %s\n" "$key" >&2
        exit 1
        ;;

      *)

        printf "invalid argument: %s\n" "$key" >&2
        exit 1

        ;;

    esac
  done

}

zendphpctl_apache_mod_php_install_parse_requirements() {

  while [[ $# -gt 0 ]]; do
    key="$1"
    case "$key" in
      --help | -h)
        long_usage=yes
        zendphpctl_apache_mod_php_install_usage
        exit
        ;;

      *)
        break
        ;;

    esac
  done

  action="apache mod_php install"

  while [[ $# -gt 0 ]]; do
    key="$1"
    case "$key" in

      -?*)
        printf "invalid option: %s\n" "$key" >&2
        exit 1
        ;;

      *)

        if [[ -z ${args['php']+x} ]]; then
          args['php']=$1
          shift
        else
          printf "invalid argument: %s\n" "$key" >&2
          exit 1
        fi

        ;;

    esac
  done

  if [[ -v args['php'] && -n $(validate_php_version "${args['php']:-}") ]]; then
    printf "validation error in %s:\n%s\n" "PHP" "$(validate_php_version "${args['php']:-}")" >&2
    exit 1
  fi

  filter_error=$(filter_is_valid_os)
  if [[ -n $filter_error ]]; then
    echo "$filter_error" >&2
    exit 1
  fi

  filter_error=$(filter_is_not_ibm_i)
  if [[ -n $filter_error ]]; then
    echo "$filter_error" >&2
    exit 1
  fi

  filter_error=$(filter_is_root)
  if [[ -n $filter_error ]]; then
    echo "$filter_error" >&2
    exit 1
  fi

}

zendphpctl_apache_mod_php_is_installed_parse_requirements() {

  while [[ $# -gt 0 ]]; do
    key="$1"
    case "$key" in
      --help | -h)
        long_usage=yes
        zendphpctl_apache_mod_php_is_installed_usage
        exit
        ;;

      *)
        break
        ;;

    esac
  done

  action="apache mod_php is-installed"

  while [[ $# -gt 0 ]]; do
    key="$1"
    case "$key" in

      -?*)
        printf "invalid option: %s\n" "$key" >&2
        exit 1
        ;;

      *)

        if [[ -z ${args['php']+x} ]]; then
          args['php']=$1
          shift
        else
          printf "invalid argument: %s\n" "$key" >&2
          exit 1
        fi

        ;;

    esac
  done

  filter_error=$(filter_is_valid_os)
  if [[ -n $filter_error ]]; then
    echo "$filter_error" >&2
    exit 1
  fi

}

zendphpctl_apache_mod_php_uninstall_parse_requirements() {

  while [[ $# -gt 0 ]]; do
    key="$1"
    case "$key" in
      --help | -h)
        long_usage=yes
        zendphpctl_apache_mod_php_uninstall_usage
        exit
        ;;

      *)
        break
        ;;

    esac
  done

  action="apache mod_php uninstall"

  while [[ $# -gt 0 ]]; do
    key="$1"
    case "$key" in

      -?*)
        printf "invalid option: %s\n" "$key" >&2
        exit 1
        ;;

      *)

        if [[ -z ${args['php']+x} ]]; then
          args['php']=$1
          shift
        else
          printf "invalid argument: %s\n" "$key" >&2
          exit 1
        fi

        ;;

    esac
  done

  if [[ -v args['php'] && -n $(validate_php_version "${args['php']:-}") ]]; then
    printf "validation error in %s:\n%s\n" "PHP" "$(validate_php_version "${args['php']:-}")" >&2
    exit 1
  fi

  filter_error=$(filter_is_valid_os)
  if [[ -n $filter_error ]]; then
    echo "$filter_error" >&2
    exit 1
  fi

  filter_error=$(filter_is_not_ibm_i)
  if [[ -n $filter_error ]]; then
    echo "$filter_error" >&2
    exit 1
  fi

  filter_error=$(filter_is_root)
  if [[ -n $filter_error ]]; then
    echo "$filter_error" >&2
    exit 1
  fi

}

zendphpctl_ext_parse_requirements() {

  while [[ $# -gt 0 ]]; do
    key="$1"
    case "$key" in
      --help | -h)
        long_usage=yes
        zendphpctl_ext_usage
        exit
        ;;

      *)
        break
        ;;

    esac
  done

  action=${1:-}

  case $action in
    -*) ;;

    disable)
      action="disable"
      shift
      zendphpctl_ext_disable_parse_requirements "$@"
      shift $#
      ;;

    enable)
      action="enable"
      shift
      zendphpctl_ext_enable_parse_requirements "$@"
      shift $#
      ;;

    install)
      action="install"
      shift
      zendphpctl_ext_install_parse_requirements "$@"
      shift $#
      ;;

    list-enabled)
      action="list-enabled"
      shift
      zendphpctl_ext_list_enabled_parse_requirements "$@"
      shift $#
      ;;

    list-packages)
      action="list-packages"
      shift
      zendphpctl_ext_list_packages_parse_requirements "$@"
      shift $#
      ;;

    "")
      zendphpctl_ext_usage >&2
      exit 1
      ;;

    *)
      printf "invalid command: %s\n" "$action" >&2
      exit 1
      ;;

  esac

  while [[ $# -gt 0 ]]; do
    key="$1"
    case "$key" in

      -?*)
        printf "invalid option: %s\n" "$key" >&2
        exit 1
        ;;

      *)

        printf "invalid argument: %s\n" "$key" >&2
        exit 1

        ;;

    esac
  done

}

zendphpctl_ext_disable_parse_requirements() {

  while [[ $# -gt 0 ]]; do
    key="$1"
    case "$key" in
      --help | -h)
        long_usage=yes
        zendphpctl_ext_disable_usage
        exit
        ;;

      *)
        break
        ;;

    esac
  done

  missing_deps=

  if ! command -v awk >/dev/null 2>&1; then
    printf "missing dependency: awk\n" >&2
    missing_deps=1
  else
    deps['awk']="$(command -v awk | head -n1)"
  fi

  if ! command -v find >/dev/null 2>&1; then
    printf "missing dependency: find\n" >&2
    missing_deps=1
  else
    deps['find']="$(command -v find | head -n1)"
  fi

  if ! command -v grep >/dev/null 2>&1; then
    printf "missing dependency: grep\n" >&2
    missing_deps=1
  else
    deps['grep']="$(command -v grep | head -n1)"
  fi

  if ! command -v sed >/dev/null 2>&1; then
    printf "missing dependency: sed\n" >&2
    missing_deps=1
  else
    deps['sed']="$(command -v sed | head -n1)"
  fi

  if [[ -n $missing_deps ]]; then
    exit 1
  fi

  action="ext disable"

  while [[ $# -gt 0 ]]; do
    key="$1"
    case "$key" in

      --php)

        if [[ -n ${2+x} ]]; then
          args['--php']="$2"
          shift
          shift
        else
          printf "%s\n" "--php requires an argument: --php PHP" >&2
          exit 1
        fi
        ;;

      --sapi)

        if [[ -n ${2+x} ]]; then
          args['--sapi']="$2"
          shift
          shift
        else
          printf "%s\n" "--sapi requires an argument: --sapi SAPI" >&2
          exit 1
        fi
        ;;

      --)
        shift
        other_args+=("$@")
        break
        ;;

      -?*)
        other_args+=("$1")
        shift
        ;;

      *)

        other_args+=("$1")
        shift

        ;;

    esac
  done

  if [[ ${#other_args[@]} -eq 0 ]]; then
    printf "missing required argument: EXTENSIONS...\nusage: zendphpctl ext disable [OPTIONS] [--] EXTENSIONS...\n" >&2
    exit 1
  fi

  [[ -n ${args['--sapi']:-} ]] || args['--sapi']="ALL"

  if [[ -v args['--php'] ]]; then
    validation_output="$(validate_php_version "${args['--php']:-}")"
    if [[ -n "${validation_output}" ]]; then
      printf "validation error in %s:\n%s\n" "--php PHP" "$validation_output" >&2
      exit 1
    fi
  fi

  if [[ ${args['--sapi']:-} ]] && [[ ! ${args['--sapi']:-} =~ ^(ALL|cli|fpm)$ ]]; then
    printf "%s\n" "--sapi must be one of: ALL, cli, fpm" >&2
    exit 1
  fi

  filter_error=$(filter_is_valid_os)
  if [[ -n $filter_error ]]; then
    echo "$filter_error" >&2
    exit 1
  fi

  filter_error=$(filter_is_root)
  if [[ -n $filter_error ]]; then
    echo "$filter_error" >&2
    exit 1
  fi

}

zendphpctl_ext_enable_parse_requirements() {

  while [[ $# -gt 0 ]]; do
    key="$1"
    case "$key" in
      --help | -h)
        long_usage=yes
        zendphpctl_ext_enable_usage
        exit
        ;;

      *)
        break
        ;;

    esac
  done

  missing_deps=

  if ! command -v curl >/dev/null 2>&1; then
    printf "missing dependency: curl\n" >&2
    missing_deps=1
  else
    deps['curl']="$(command -v curl | head -n1)"
  fi

  if ! command -v find >/dev/null 2>&1; then
    printf "missing dependency: find\n" >&2
    missing_deps=1
  else
    deps['find']="$(command -v find | head -n1)"
  fi

  if ! command -v grep >/dev/null 2>&1; then
    printf "missing dependency: grep\n" >&2
    missing_deps=1
  else
    deps['grep']="$(command -v grep | head -n1)"
  fi

  if ! command -v mkdir >/dev/null 2>&1; then
    printf "missing dependency: mkdir\n" >&2
    missing_deps=1
  else
    deps['mkdir']="$(command -v mkdir | head -n1)"
  fi

  if ! command -v rm >/dev/null 2>&1; then
    printf "missing dependency: rm\n" >&2
    missing_deps=1
  else
    deps['rm']="$(command -v rm | head -n1)"
  fi

  if ! command -v sed >/dev/null 2>&1; then
    printf "missing dependency: sed\n" >&2
    missing_deps=1
  else
    deps['sed']="$(command -v sed | head -n1)"
  fi

  if ! command -v sort >/dev/null 2>&1; then
    printf "missing dependency: sort\n" >&2
    missing_deps=1
  else
    deps['sort']="$(command -v sort | head -n1)"
  fi

  if ! command -v tar >/dev/null 2>&1; then
    printf "missing dependency: tar\n" >&2
    missing_deps=1
  else
    deps['tar']="$(command -v tar | head -n1)"
  fi

  if ! command -v tr >/dev/null 2>&1; then
    printf "missing dependency: tr\n" >&2
    missing_deps=1
  else
    deps['tr']="$(command -v tr | head -n1)"
  fi

  if ! command -v repoquery apt-cache apk >/dev/null 2>&1; then
    printf "missing dependency: repo_helper (repoquery/apt-cache/apk)\n" >&2
    printf "%s\n\n" "run 'dnf install yum-utils' or 'yum install yum-utils'" >&2
    missing_deps=1
  else
    deps['repo_helper']="$(command -v repoquery apt-cache apk | head -n1)"
  fi

  if [[ -n $missing_deps ]]; then
    exit 1
  fi

  action="ext enable"

  while [[ $# -gt 0 ]]; do
    key="$1"
    case "$key" in

      --php)

        if [[ -n ${2+x} ]]; then
          args['--php']="$2"
          shift
          shift
        else
          printf "%s\n" "--php requires an argument: --php PHP" >&2
          exit 1
        fi
        ;;

      --sapi)

        if [[ -n ${2+x} ]]; then
          args['--sapi']="$2"
          shift
          shift
        else
          printf "%s\n" "--sapi requires an argument: --sapi SAPI" >&2
          exit 1
        fi
        ;;

      --)
        shift
        other_args+=("$@")
        break
        ;;

      -?*)
        other_args+=("$1")
        shift
        ;;

      *)

        other_args+=("$1")
        shift

        ;;

    esac
  done

  if [[ ${#other_args[@]} -eq 0 ]]; then
    printf "missing required argument: EXTENSIONS...\nusage: zendphpctl ext enable [OPTIONS] [--] EXTENSIONS...\n" >&2
    exit 1
  fi

  [[ -n ${args['--sapi']:-} ]] || args['--sapi']="ALL"

  if [[ -v args['--php'] ]]; then
    validation_output="$(validate_php_version "${args['--php']:-}")"
    if [[ -n "${validation_output}" ]]; then
      printf "validation error in %s:\n%s\n" "--php PHP" "$validation_output" >&2
      exit 1
    fi
  fi

  if [[ ${args['--sapi']:-} ]] && [[ ! ${args['--sapi']:-} =~ ^(ALL|cli|fpm)$ ]]; then
    printf "%s\n" "--sapi must be one of: ALL, cli, fpm" >&2
    exit 1
  fi

  filter_error=$(filter_is_valid_os)
  if [[ -n $filter_error ]]; then
    echo "$filter_error" >&2
    exit 1
  fi

  filter_error=$(filter_is_root)
  if [[ -n $filter_error ]]; then
    echo "$filter_error" >&2
    exit 1
  fi

}

zendphpctl_ext_install_parse_requirements() {

  while [[ $# -gt 0 ]]; do
    key="$1"
    case "$key" in
      --help | -h)
        long_usage=yes
        zendphpctl_ext_install_usage
        exit
        ;;

      *)
        break
        ;;

    esac
  done

  missing_deps=

  if ! command -v curl >/dev/null 2>&1; then
    printf "missing dependency: curl\n" >&2
    missing_deps=1
  else
    deps['curl']="$(command -v curl | head -n1)"
  fi

  if ! command -v cut >/dev/null 2>&1; then
    printf "missing dependency: cut\n" >&2
    missing_deps=1
  else
    deps['cut']="$(command -v cut | head -n1)"
  fi

  if ! command -v grep >/dev/null 2>&1; then
    printf "missing dependency: grep\n" >&2
    missing_deps=1
  else
    deps['grep']="$(command -v grep | head -n1)"
  fi

  if ! command -v mkdir >/dev/null 2>&1; then
    printf "missing dependency: mkdir\n" >&2
    missing_deps=1
  else
    deps['mkdir']="$(command -v mkdir | head -n1)"
  fi

  if ! command -v rm >/dev/null 2>&1; then
    printf "missing dependency: rm\n" >&2
    missing_deps=1
  else
    deps['rm']="$(command -v rm | head -n1)"
  fi

  if ! command -v sed >/dev/null 2>&1; then
    printf "missing dependency: sed\n" >&2
    missing_deps=1
  else
    deps['sed']="$(command -v sed | head -n1)"
  fi

  if ! command -v sort >/dev/null 2>&1; then
    printf "missing dependency: sort\n" >&2
    missing_deps=1
  else
    deps['sort']="$(command -v sort | head -n1)"
  fi

  if ! command -v tar >/dev/null 2>&1; then
    printf "missing dependency: tar\n" >&2
    missing_deps=1
  else
    deps['tar']="$(command -v tar | head -n1)"
  fi

  if ! command -v tr >/dev/null 2>&1; then
    printf "missing dependency: tr\n" >&2
    missing_deps=1
  else
    deps['tr']="$(command -v tr | head -n1)"
  fi

  if ! command -v repoquery apt-cache apk >/dev/null 2>&1; then
    printf "missing dependency: repo_helper (repoquery/apt-cache/apk)\n" >&2
    printf "%s\n\n" "run 'dnf install yum-utils' or 'yum install yum-utils'" >&2
    missing_deps=1
  else
    deps['repo_helper']="$(command -v repoquery apt-cache apk | head -n1)"
  fi

  if [[ -n $missing_deps ]]; then
    exit 1
  fi

  action="ext install"

  while [[ $# -gt 0 ]]; do
    key="$1"
    case "$key" in

      --php)

        if [[ -n ${2+x} ]]; then
          args['--php']="$2"
          shift
          shift
        else
          printf "%s\n" "--php requires an argument: --php PHP" >&2
          exit 1
        fi
        ;;

      --sapi)

        if [[ -n ${2+x} ]]; then
          args['--sapi']="$2"
          shift
          shift
        else
          printf "%s\n" "--sapi requires an argument: --sapi SAPI" >&2
          exit 1
        fi
        ;;

      --)
        shift
        other_args+=("$@")
        break
        ;;

      -?*)
        other_args+=("$1")
        shift
        ;;

      *)

        other_args+=("$1")
        shift

        ;;

    esac
  done

  if [[ ${#other_args[@]} -eq 0 ]]; then
    printf "missing required argument: EXTENSIONS...\nusage: zendphpctl ext install [OPTIONS] [--] EXTENSIONS...\n" >&2
    exit 1
  fi

  [[ -n ${args['--sapi']:-} ]] || args['--sapi']="ALL"

  if [[ -v args['--php'] ]]; then
    validation_output="$(validate_php_version "${args['--php']:-}")"
    if [[ -n "${validation_output}" ]]; then
      printf "validation error in %s:\n%s\n" "--php PHP" "$validation_output" >&2
      exit 1
    fi
  fi

  if [[ ${args['--sapi']:-} ]] && [[ ! ${args['--sapi']:-} =~ ^(ALL|cli|fpm)$ ]]; then
    printf "%s\n" "--sapi must be one of: ALL, cli, fpm" >&2
    exit 1
  fi

  filter_error=$(filter_is_valid_os)
  if [[ -n $filter_error ]]; then
    echo "$filter_error" >&2
    exit 1
  fi

  filter_error=$(filter_is_root)
  if [[ -n $filter_error ]]; then
    echo "$filter_error" >&2
    exit 1
  fi

}

zendphpctl_ext_list_enabled_parse_requirements() {

  while [[ $# -gt 0 ]]; do
    key="$1"
    case "$key" in
      --help | -h)
        long_usage=yes
        zendphpctl_ext_list_enabled_usage
        exit
        ;;

      *)
        break
        ;;

    esac
  done

  missing_deps=

  if ! command -v basename >/dev/null 2>&1; then
    printf "missing dependency: basename\n" >&2
    missing_deps=1
  else
    deps['basename']="$(command -v basename | head -n1)"
  fi

  if ! command -v find >/dev/null 2>&1; then
    printf "missing dependency: find\n" >&2
    missing_deps=1
  else
    deps['find']="$(command -v find | head -n1)"
  fi

  if ! command -v grep >/dev/null 2>&1; then
    printf "missing dependency: grep\n" >&2
    missing_deps=1
  else
    deps['grep']="$(command -v grep | head -n1)"
  fi

  if ! command -v sed >/dev/null 2>&1; then
    printf "missing dependency: sed\n" >&2
    missing_deps=1
  else
    deps['sed']="$(command -v sed | head -n1)"
  fi

  if ! command -v sort >/dev/null 2>&1; then
    printf "missing dependency: sort\n" >&2
    missing_deps=1
  else
    deps['sort']="$(command -v sort | head -n1)"
  fi

  if [[ -n $missing_deps ]]; then
    exit 1
  fi

  action="ext list-enabled"

  while [[ $# -gt 0 ]]; do
    key="$1"
    case "$key" in

      --fpm)

        args['--fpm']=1
        shift
        ;;

      -?*)
        printf "invalid option: %s\n" "$key" >&2
        exit 1
        ;;

      *)

        if [[ -z ${args['php']+x} ]]; then
          args['php']=$1
          shift
        else
          printf "invalid argument: %s\n" "$key" >&2
          exit 1
        fi

        ;;

    esac
  done

  if [[ -v args['php'] && -n $(validate_php_version "${args['php']:-}") ]]; then
    printf "validation error in %s:\n%s\n" "PHP" "$(validate_php_version "${args['php']:-}")" >&2
    exit 1
  fi

  filter_error=$(filter_is_valid_os)
  if [[ -n $filter_error ]]; then
    echo "$filter_error" >&2
    exit 1
  fi

}

zendphpctl_ext_list_packages_parse_requirements() {

  while [[ $# -gt 0 ]]; do
    key="$1"
    case "$key" in
      --help | -h)
        long_usage=yes
        zendphpctl_ext_list_packages_usage
        exit
        ;;

      *)
        break
        ;;

    esac
  done

  missing_deps=

  if ! command -v cut >/dev/null 2>&1; then
    printf "missing dependency: cut\n" >&2
    missing_deps=1
  else
    deps['cut']="$(command -v cut | head -n1)"
  fi

  if ! command -v grep >/dev/null 2>&1; then
    printf "missing dependency: grep\n" >&2
    missing_deps=1
  else
    deps['grep']="$(command -v grep | head -n1)"
  fi

  if ! command -v sed >/dev/null 2>&1; then
    printf "missing dependency: sed\n" >&2
    missing_deps=1
  else
    deps['sed']="$(command -v sed | head -n1)"
  fi

  if ! command -v sort >/dev/null 2>&1; then
    printf "missing dependency: sort\n" >&2
    missing_deps=1
  else
    deps['sort']="$(command -v sort | head -n1)"
  fi

  if ! command -v repoquery apt-cache apk >/dev/null 2>&1; then
    printf "missing dependency: repo_helper (repoquery/apt-cache/apk)\n" >&2
    printf "%s\n\n" "run 'dnf install yum-utils' or 'yum install yum-utils'" >&2
    missing_deps=1
  else
    deps['repo_helper']="$(command -v repoquery apt-cache apk | head -n1)"
  fi

  if [[ -n $missing_deps ]]; then
    exit 1
  fi

  action="ext list-packages"

  while [[ $# -gt 0 ]]; do
    key="$1"
    case "$key" in

      -?*)
        printf "invalid option: %s\n" "$key" >&2
        exit 1
        ;;

      *)

        if [[ -z ${args['php']+x} ]]; then
          args['php']=$1
          shift
        else
          printf "invalid argument: %s\n" "$key" >&2
          exit 1
        fi

        ;;

    esac
  done

  if [[ -v args['php'] && -n $(validate_php_version "${args['php']:-}") ]]; then
    printf "validation error in %s:\n%s\n" "PHP" "$(validate_php_version "${args['php']:-}")" >&2
    exit 1
  fi

  filter_error=$(filter_is_valid_os)
  if [[ -n $filter_error ]]; then
    echo "$filter_error" >&2
    exit 1
  fi

  filter_error=$(filter_is_root)
  if [[ -n $filter_error ]]; then
    echo "$filter_error" >&2
    exit 1
  fi

}

zendphpctl_fpm_parse_requirements() {

  while [[ $# -gt 0 ]]; do
    key="$1"
    case "$key" in
      --help | -h)
        long_usage=yes
        zendphpctl_fpm_usage
        exit
        ;;

      *)
        break
        ;;

    esac
  done

  action=${1:-}

  case $action in
    -*) ;;

    config)
      action="config"
      shift
      zendphpctl_fpm_config_parse_requirements "$@"
      shift $#
      ;;

    install)
      action="install"
      shift
      zendphpctl_fpm_install_parse_requirements "$@"
      shift $#
      ;;

    is-installed)
      action="is-installed"
      shift
      zendphpctl_fpm_is_installed_parse_requirements "$@"
      shift $#
      ;;

    uninstall)
      action="uninstall"
      shift
      zendphpctl_fpm_uninstall_parse_requirements "$@"
      shift $#
      ;;

    "")
      zendphpctl_fpm_usage >&2
      exit 1
      ;;

    *)
      printf "invalid command: %s\n" "$action" >&2
      exit 1
      ;;

  esac

  while [[ $# -gt 0 ]]; do
    key="$1"
    case "$key" in

      -?*)
        printf "invalid option: %s\n" "$key" >&2
        exit 1
        ;;

      *)

        printf "invalid argument: %s\n" "$key" >&2
        exit 1

        ;;

    esac
  done

}

zendphpctl_fpm_config_parse_requirements() {

  while [[ $# -gt 0 ]]; do
    key="$1"
    case "$key" in
      --help | -h)
        long_usage=yes
        zendphpctl_fpm_config_usage
        exit
        ;;

      *)
        break
        ;;

    esac
  done

  action="fpm config"

  while [[ $# -gt 0 ]]; do
    key="$1"
    case "$key" in

      -?*)
        printf "invalid option: %s\n" "$key" >&2
        exit 1
        ;;

      *)

        if [[ -z ${args['php']+x} ]]; then
          args['php']=$1
          shift
        else
          printf "invalid argument: %s\n" "$key" >&2
          exit 1
        fi

        ;;

    esac
  done

  if [[ -v args['php'] && -n $(validate_php_version "${args['php']:-}") ]]; then
    printf "validation error in %s:\n%s\n" "PHP" "$(validate_php_version "${args['php']:-}")" >&2
    exit 1
  fi

  filter_error=$(filter_is_valid_os)
  if [[ -n $filter_error ]]; then
    echo "$filter_error" >&2
    exit 1
  fi

  filter_error=$(filter_is_root)
  if [[ -n $filter_error ]]; then
    echo "$filter_error" >&2
    exit 1
  fi

}

zendphpctl_fpm_install_parse_requirements() {

  while [[ $# -gt 0 ]]; do
    key="$1"
    case "$key" in
      --help | -h)
        long_usage=yes
        zendphpctl_fpm_install_usage
        exit
        ;;

      *)
        break
        ;;

    esac
  done

  action="fpm install"

  while [[ $# -gt 0 ]]; do
    key="$1"
    case "$key" in

      -?*)
        printf "invalid option: %s\n" "$key" >&2
        exit 1
        ;;

      *)

        if [[ -z ${args['php']+x} ]]; then
          args['php']=$1
          shift
        else
          printf "invalid argument: %s\n" "$key" >&2
          exit 1
        fi

        ;;

    esac
  done

  if [[ -v args['php'] && -n $(validate_php_version "${args['php']:-}") ]]; then
    printf "validation error in %s:\n%s\n" "PHP" "$(validate_php_version "${args['php']:-}")" >&2
    exit 1
  fi

  filter_error=$(filter_is_valid_os)
  if [[ -n $filter_error ]]; then
    echo "$filter_error" >&2
    exit 1
  fi

  filter_error=$(filter_is_root)
  if [[ -n $filter_error ]]; then
    echo "$filter_error" >&2
    exit 1
  fi

}

zendphpctl_fpm_is_installed_parse_requirements() {

  while [[ $# -gt 0 ]]; do
    key="$1"
    case "$key" in
      --help | -h)
        long_usage=yes
        zendphpctl_fpm_is_installed_usage
        exit
        ;;

      *)
        break
        ;;

    esac
  done

  action="fpm is-installed"

  while [[ $# -gt 0 ]]; do
    key="$1"
    case "$key" in

      -?*)
        printf "invalid option: %s\n" "$key" >&2
        exit 1
        ;;

      *)

        if [[ -z ${args['php']+x} ]]; then
          args['php']=$1
          shift
        else
          printf "invalid argument: %s\n" "$key" >&2
          exit 1
        fi

        ;;

    esac
  done

  filter_error=$(filter_is_valid_os)
  if [[ -n $filter_error ]]; then
    echo "$filter_error" >&2
    exit 1
  fi

}

zendphpctl_fpm_uninstall_parse_requirements() {

  while [[ $# -gt 0 ]]; do
    key="$1"
    case "$key" in
      --help | -h)
        long_usage=yes
        zendphpctl_fpm_uninstall_usage
        exit
        ;;

      *)
        break
        ;;

    esac
  done

  action="fpm uninstall"

  while [[ $# -gt 0 ]]; do
    key="$1"
    case "$key" in

      -?*)
        printf "invalid option: %s\n" "$key" >&2
        exit 1
        ;;

      *)

        if [[ -z ${args['php']+x} ]]; then
          args['php']=$1
          shift
        else
          printf "invalid argument: %s\n" "$key" >&2
          exit 1
        fi

        ;;

    esac
  done

  if [[ -v args['php'] && -n $(validate_php_version "${args['php']:-}") ]]; then
    printf "validation error in %s:\n%s\n" "PHP" "$(validate_php_version "${args['php']:-}")" >&2
    exit 1
  fi

  filter_error=$(filter_is_valid_os)
  if [[ -n $filter_error ]]; then
    echo "$filter_error" >&2
    exit 1
  fi

  filter_error=$(filter_is_root)
  if [[ -n $filter_error ]]; then
    echo "$filter_error" >&2
    exit 1
  fi

}

zendphpctl_php_parse_requirements() {

  while [[ $# -gt 0 ]]; do
    key="$1"
    case "$key" in
      --help | -h)
        long_usage=yes
        zendphpctl_php_usage
        exit
        ;;

      *)
        break
        ;;

    esac
  done

  action=${1:-}

  case $action in
    -*) ;;

    config)
      action="config"
      shift
      zendphpctl_php_config_parse_requirements "$@"
      shift $#
      ;;

    list-installed)
      action="list-installed"
      shift
      zendphpctl_php_list_installed_parse_requirements "$@"
      shift $#
      ;;

    list-sapis)
      action="list-sapis"
      shift
      zendphpctl_php_list_sapis_parse_requirements "$@"
      shift $#
      ;;

    set-default)
      action="set-default"
      shift
      zendphpctl_php_set_default_parse_requirements "$@"
      shift $#
      ;;

    get-default)
      action="get-default"
      shift
      zendphpctl_php_get_default_parse_requirements "$@"
      shift $#
      ;;

    info)
      action="info"
      shift
      zendphpctl_php_info_parse_requirements "$@"
      shift $#
      ;;

    install)
      action="install"
      shift
      zendphpctl_php_install_parse_requirements "$@"
      shift $#
      ;;

    uninstall)
      action="uninstall"
      shift
      zendphpctl_php_uninstall_parse_requirements "$@"
      shift $#
      ;;

    exec)
      action="exec"
      shift
      zendphpctl_php_exec_parse_requirements "$@"
      shift $#
      ;;

    "")
      zendphpctl_php_usage >&2
      exit 1
      ;;

    *)
      printf "invalid command: %s\n" "$action" >&2
      exit 1
      ;;

  esac

  while [[ $# -gt 0 ]]; do
    key="$1"
    case "$key" in

      -?*)
        printf "invalid option: %s\n" "$key" >&2
        exit 1
        ;;

      *)

        printf "invalid argument: %s\n" "$key" >&2
        exit 1

        ;;

    esac
  done

}

zendphpctl_php_config_parse_requirements() {

  while [[ $# -gt 0 ]]; do
    key="$1"
    case "$key" in
      --help | -h)
        long_usage=yes
        zendphpctl_php_config_usage
        exit
        ;;

      *)
        break
        ;;

    esac
  done

  action="php config"

  while [[ $# -gt 0 ]]; do
    key="$1"
    case "$key" in

      --fpm)

        args['--fpm']=1
        shift
        ;;

      -?*)
        printf "invalid option: %s\n" "$key" >&2
        exit 1
        ;;

      *)

        if [[ -z ${args['php']+x} ]]; then
          args['php']=$1
          shift
        else
          printf "invalid argument: %s\n" "$key" >&2
          exit 1
        fi

        ;;

    esac
  done

  if [[ -v args['php'] && -n $(validate_php_version "${args['php']:-}") ]]; then
    printf "validation error in %s:\n%s\n" "PHP" "$(validate_php_version "${args['php']:-}")" >&2
    exit 1
  fi

  filter_error=$(filter_is_valid_os)
  if [[ -n $filter_error ]]; then
    echo "$filter_error" >&2
    exit 1
  fi

  filter_error=$(filter_is_root)
  if [[ -n $filter_error ]]; then
    echo "$filter_error" >&2
    exit 1
  fi

}

zendphpctl_php_list_installed_parse_requirements() {

  while [[ $# -gt 0 ]]; do
    key="$1"
    case "$key" in
      --help | -h)
        long_usage=yes
        zendphpctl_php_list_installed_usage
        exit
        ;;

      *)
        break
        ;;

    esac
  done

  missing_deps=

  if ! command -v awk >/dev/null 2>&1; then
    printf "missing dependency: awk\n" >&2
    missing_deps=1
  else
    deps['awk']="$(command -v awk | head -n1)"
  fi

  if ! command -v cut >/dev/null 2>&1; then
    printf "missing dependency: cut\n" >&2
    missing_deps=1
  else
    deps['cut']="$(command -v cut | head -n1)"
  fi

  if ! command -v grep >/dev/null 2>&1; then
    printf "missing dependency: grep\n" >&2
    missing_deps=1
  else
    deps['grep']="$(command -v grep | head -n1)"
  fi

  if ! command -v head >/dev/null 2>&1; then
    printf "missing dependency: head\n" >&2
    missing_deps=1
  else
    deps['head']="$(command -v head | head -n1)"
  fi

  if ! command -v sed >/dev/null 2>&1; then
    printf "missing dependency: sed\n" >&2
    missing_deps=1
  else
    deps['sed']="$(command -v sed | head -n1)"
  fi

  if ! command -v tr >/dev/null 2>&1; then
    printf "missing dependency: tr\n" >&2
    missing_deps=1
  else
    deps['tr']="$(command -v tr | head -n1)"
  fi

  if [[ -n $missing_deps ]]; then
    exit 1
  fi

  action="php list-installed"

  while [[ $# -gt 0 ]]; do
    key="$1"
    case "$key" in

      --verbose | -v)

        args['--verbose']=1
        shift
        ;;

      --json | -j)

        args['--json']=1
        shift
        ;;

      -?*)
        printf "invalid option: %s\n" "$key" >&2
        exit 1
        ;;

      *)

        printf "invalid argument: %s\n" "$key" >&2
        exit 1

        ;;

    esac
  done

}

zendphpctl_php_list_sapis_parse_requirements() {

  while [[ $# -gt 0 ]]; do
    key="$1"
    case "$key" in
      --help | -h)
        long_usage=yes
        zendphpctl_php_list_sapis_usage
        exit
        ;;

      *)
        break
        ;;

    esac
  done

  action="php list-sapis"

  while [[ $# -gt 0 ]]; do
    key="$1"
    case "$key" in

      -?*)
        printf "invalid option: %s\n" "$key" >&2
        exit 1
        ;;

      *)

        if [[ -z ${args['php']+x} ]]; then
          args['php']=$1
          shift
        else
          printf "invalid argument: %s\n" "$key" >&2
          exit 1
        fi

        ;;

    esac
  done

  if [[ -v args['php'] && -n $(validate_php_version "${args['php']:-}") ]]; then
    printf "validation error in %s:\n%s\n" "PHP" "$(validate_php_version "${args['php']:-}")" >&2
    exit 1
  fi

}

zendphpctl_php_set_default_parse_requirements() {

  while [[ $# -gt 0 ]]; do
    key="$1"
    case "$key" in
      --help | -h)
        long_usage=yes
        zendphpctl_php_set_default_usage
        exit
        ;;

      *)
        break
        ;;

    esac
  done

  missing_deps=

  if ! command -v awk >/dev/null 2>&1; then
    printf "missing dependency: awk\n" >&2
    missing_deps=1
  else
    deps['awk']="$(command -v awk | head -n1)"
  fi

  if ! command -v grep >/dev/null 2>&1; then
    printf "missing dependency: grep\n" >&2
    missing_deps=1
  else
    deps['grep']="$(command -v grep | head -n1)"
  fi

  if [[ -n $missing_deps ]]; then
    exit 1
  fi

  action="php set-default"

  while [[ $# -gt 0 ]]; do
    key="$1"
    case "$key" in

      -?*)
        printf "invalid option: %s\n" "$key" >&2
        exit 1
        ;;

      *)

        if [[ -z ${args['php']+x} ]]; then
          args['php']=$1
          shift
        else
          printf "invalid argument: %s\n" "$key" >&2
          exit 1
        fi

        ;;

    esac
  done

  if [[ -z ${args['php']+x} ]]; then
    printf "missing required argument: PHP\nusage: zendphpctl php set-default PHP\n" >&2

    exit 1
  fi

  if [[ -v args['php'] && -n $(validate_php_version "${args['php']:-}") ]]; then
    printf "validation error in %s:\n%s\n" "PHP" "$(validate_php_version "${args['php']:-}")" >&2
    exit 1
  fi

  filter_error=$(filter_is_valid_os)
  if [[ -n $filter_error ]]; then
    echo "$filter_error" >&2
    exit 1
  fi

  filter_error=$(filter_is_root)
  if [[ -n $filter_error ]]; then
    echo "$filter_error" >&2
    exit 1
  fi

}

zendphpctl_php_get_default_parse_requirements() {

  while [[ $# -gt 0 ]]; do
    key="$1"
    case "$key" in
      --help | -h)
        long_usage=yes
        zendphpctl_php_get_default_usage
        exit
        ;;

      *)
        break
        ;;

    esac
  done

  action="php get-default"

  while [[ $# -gt 0 ]]; do
    key="$1"
    case "$key" in

      -?*)
        printf "invalid option: %s\n" "$key" >&2
        exit 1
        ;;

      *)

        printf "invalid argument: %s\n" "$key" >&2
        exit 1

        ;;

    esac
  done

}

zendphpctl_php_info_parse_requirements() {

  while [[ $# -gt 0 ]]; do
    key="$1"
    case "$key" in
      --help | -h)
        long_usage=yes
        zendphpctl_php_info_usage
        exit
        ;;

      *)
        break
        ;;

    esac
  done

  missing_deps=

  if ! command -v awk >/dev/null 2>&1; then
    printf "missing dependency: awk\n" >&2
    missing_deps=1
  else
    deps['awk']="$(command -v awk | head -n1)"
  fi

  if ! command -v cut >/dev/null 2>&1; then
    printf "missing dependency: cut\n" >&2
    missing_deps=1
  else
    deps['cut']="$(command -v cut | head -n1)"
  fi

  if ! command -v grep >/dev/null 2>&1; then
    printf "missing dependency: grep\n" >&2
    missing_deps=1
  else
    deps['grep']="$(command -v grep | head -n1)"
  fi

  if ! command -v head >/dev/null 2>&1; then
    printf "missing dependency: head\n" >&2
    missing_deps=1
  else
    deps['head']="$(command -v head | head -n1)"
  fi

  if ! command -v sed >/dev/null 2>&1; then
    printf "missing dependency: sed\n" >&2
    missing_deps=1
  else
    deps['sed']="$(command -v sed | head -n1)"
  fi

  if ! command -v tr >/dev/null 2>&1; then
    printf "missing dependency: tr\n" >&2
    missing_deps=1
  else
    deps['tr']="$(command -v tr | head -n1)"
  fi

  if [[ -n $missing_deps ]]; then
    exit 1
  fi

  action="php info"

  while [[ $# -gt 0 ]]; do
    key="$1"
    case "$key" in

      --php)

        if [[ -n ${2+x} ]]; then
          args['--php']="$2"
          shift
          shift
        else
          printf "%s\n" "--php requires an argument: --php PHP" >&2
          exit 1
        fi
        ;;

      --json | -j)

        args['--json']=1
        shift
        ;;

      -?*)
        printf "invalid option: %s\n" "$key" >&2
        exit 1
        ;;

      *)

        printf "invalid argument: %s\n" "$key" >&2
        exit 1

        ;;

    esac
  done

  if [[ -v args['--php'] ]]; then
    validation_output="$(validate_php_version "${args['--php']:-}")"
    if [[ -n "${validation_output}" ]]; then
      printf "validation error in %s:\n%s\n" "--php PHP" "$validation_output" >&2
      exit 1
    fi
  fi

}

zendphpctl_php_install_parse_requirements() {

  while [[ $# -gt 0 ]]; do
    key="$1"
    case "$key" in
      --help | -h)
        long_usage=yes
        zendphpctl_php_install_usage
        exit
        ;;

      *)
        break
        ;;

    esac
  done

  missing_deps=

  if ! command -v awk >/dev/null 2>&1; then
    printf "missing dependency: awk\n" >&2
    missing_deps=1
  else
    deps['awk']="$(command -v awk | head -n1)"
  fi

  if ! command -v grep >/dev/null 2>&1; then
    printf "missing dependency: grep\n" >&2
    missing_deps=1
  else
    deps['grep']="$(command -v grep | head -n1)"
  fi

  if [[ -n $missing_deps ]]; then
    exit 1
  fi

  action="php install"

  while [[ $# -gt 0 ]]; do
    key="$1"
    case "$key" in

      --not-default)

        args['--not-default']=1
        shift
        ;;

      -?*)
        printf "invalid option: %s\n" "$key" >&2
        exit 1
        ;;

      *)

        if [[ -z ${args['php']+x} ]]; then
          args['php']=$1
          shift
        else
          printf "invalid argument: %s\n" "$key" >&2
          exit 1
        fi

        ;;

    esac
  done

  if [[ -z ${args['php']+x} ]]; then
    printf "missing required argument: PHP\nusage: zendphpctl php install PHP [OPTIONS]\n" >&2

    exit 1
  fi

  if [[ -n ${args['php']:-} ]] && [[ ! ${args['php']:-} =~ ^(5.6|7.1|7.2|7.3|7.4|8.0|8.1|8.2|8.3|8.4|8.5)$ ]]; then
    printf "%s\n" "php must be one of: 5.6, 7.1, 7.2, 7.3, 7.4, 8.0, 8.1, 8.2, 8.3, 8.4, 8.5" >&2
    exit 1
  fi

  filter_error=$(filter_is_valid_os)
  if [[ -n $filter_error ]]; then
    echo "$filter_error" >&2
    exit 1
  fi

  filter_error=$(filter_is_root)
  if [[ -n $filter_error ]]; then
    echo "$filter_error" >&2
    exit 1
  fi

}

zendphpctl_php_uninstall_parse_requirements() {

  while [[ $# -gt 0 ]]; do
    key="$1"
    case "$key" in
      --help | -h)
        long_usage=yes
        zendphpctl_php_uninstall_usage
        exit
        ;;

      *)
        break
        ;;

    esac
  done

  action="php uninstall"

  while [[ $# -gt 0 ]]; do
    key="$1"
    case "$key" in

      -?*)
        printf "invalid option: %s\n" "$key" >&2
        exit 1
        ;;

      *)

        if [[ -z ${args['php']+x} ]]; then
          args['php']=$1
          shift
        else
          printf "invalid argument: %s\n" "$key" >&2
          exit 1
        fi

        ;;

    esac
  done

  if [[ -z ${args['php']+x} ]]; then
    printf "missing required argument: PHP\nusage: zendphpctl php uninstall PHP\n" >&2

    exit 1
  fi

  if [[ -v args['php'] && -n $(validate_php_version "${args['php']:-}") ]]; then
    printf "validation error in %s:\n%s\n" "PHP" "$(validate_php_version "${args['php']:-}")" >&2
    exit 1
  fi

  filter_error=$(filter_is_valid_os)
  if [[ -n $filter_error ]]; then
    echo "$filter_error" >&2
    exit 1
  fi

  filter_error=$(filter_is_root)
  if [[ -n $filter_error ]]; then
    echo "$filter_error" >&2
    exit 1
  fi

}

zendphpctl_php_exec_parse_requirements() {

  while [[ $# -gt 0 ]]; do
    key="$1"
    case "$key" in
      --help | -h)
        long_usage=yes
        zendphpctl_php_exec_usage
        exit
        ;;

      *)
        break
        ;;

    esac
  done

  action="php exec"

  while [[ $# -gt 0 ]]; do
    key="$1"
    case "$key" in

      --php)

        if [[ -n ${2+x} ]]; then
          args['--php']="$2"
          shift
          shift
        else
          printf "%s\n" "--php requires an argument: --php VERSION" >&2
          exit 1
        fi
        ;;

      --)
        shift
        other_args+=("$@")
        break
        ;;

      -?*)
        other_args+=("$1")
        shift
        ;;

      *)

        other_args+=("$1")
        shift

        ;;

    esac
  done

  if [[ ${#other_args[@]} -eq 0 ]]; then
    printf "missing required argument: ARGUMENTS...\nusage: zendphpctl php exec [OPTIONS] [--] ARGUMENTS...\n" >&2
    exit 1
  fi

  if [[ -v args['--php'] ]]; then
    validation_output="$(validate_php_version "${args['--php']:-}")"
    if [[ -n "${validation_output}" ]]; then
      printf "validation error in %s:\n%s\n" "--php VERSION" "$validation_output" >&2
      exit 1
    fi
  fi

}

zendphpctl_repo_parse_requirements() {

  while [[ $# -gt 0 ]]; do
    key="$1"
    case "$key" in
      --help | -h)
        long_usage=yes
        zendphpctl_repo_usage
        exit
        ;;

      *)
        break
        ;;

    esac
  done

  action=${1:-}

  case $action in
    -*) ;;

    credentials)
      action="credentials"
      shift
      zendphpctl_repo_credentials_parse_requirements "$@"
      shift $#
      ;;

    install)
      action="install"
      shift
      zendphpctl_repo_install_parse_requirements "$@"
      shift $#
      ;;

    uninstall)
      action="uninstall"
      shift
      zendphpctl_repo_uninstall_parse_requirements "$@"
      shift $#
      ;;

    "")
      zendphpctl_repo_usage >&2
      exit 1
      ;;

    *)
      printf "invalid command: %s\n" "$action" >&2
      exit 1
      ;;

  esac

  while [[ $# -gt 0 ]]; do
    key="$1"
    case "$key" in

      -?*)
        printf "invalid option: %s\n" "$key" >&2
        exit 1
        ;;

      *)

        printf "invalid argument: %s\n" "$key" >&2
        exit 1

        ;;

    esac
  done

}

zendphpctl_repo_credentials_parse_requirements() {

  while [[ $# -gt 0 ]]; do
    key="$1"
    case "$key" in
      --help | -h)
        long_usage=yes
        zendphpctl_repo_credentials_usage
        exit
        ;;

      *)
        break
        ;;

    esac
  done

  action="repo credentials"

  while [[ $# -gt 0 ]]; do
    key="$1"
    case "$key" in

      --account)

        if [[ -n ${2+x} ]]; then
          args['--account']="$2"
          shift
          shift
        else
          printf "%s\n" "--account requires an argument: --account ACCOUNT" >&2
          exit 1
        fi
        ;;

      --password)

        if [[ -n ${2+x} ]]; then
          args['--password']="$2"
          shift
          shift
        else
          printf "%s\n" "--password requires an argument: --password PASSWORD" >&2
          exit 1
        fi
        ;;

      -?*)
        printf "invalid option: %s\n" "$key" >&2
        exit 1
        ;;

      *)

        printf "invalid argument: %s\n" "$key" >&2
        exit 1

        ;;

    esac
  done

  if [[ -z ${args['--account']+x} ]]; then
    printf "missing required flag: --account ACCOUNT\n" >&2
    exit 1
  fi
  if [[ -z ${args['--password']+x} ]]; then
    printf "missing required flag: --password PASSWORD\n" >&2
    exit 1
  fi

  filter_error=$(filter_is_valid_os)
  if [[ -n $filter_error ]]; then
    echo "$filter_error" >&2
    exit 1
  fi

  filter_error=$(filter_is_root)
  if [[ -n $filter_error ]]; then
    echo "$filter_error" >&2
    exit 1
  fi

}

zendphpctl_repo_install_parse_requirements() {

  while [[ $# -gt 0 ]]; do
    key="$1"
    case "$key" in
      --help | -h)
        long_usage=yes
        zendphpctl_repo_install_usage
        exit
        ;;

      *)
        break
        ;;

    esac
  done

  missing_deps=

  if ! command -v grep >/dev/null 2>&1; then
    printf "missing dependency: grep\n" >&2
    missing_deps=1
  else
    deps['grep']="$(command -v grep | head -n1)"
  fi

  if ! command -v sed >/dev/null 2>&1; then
    printf "missing dependency: sed\n" >&2
    missing_deps=1
  else
    deps['sed']="$(command -v sed | head -n1)"
  fi

  if ! command -v awk >/dev/null 2>&1; then
    printf "missing dependency: awk\n" >&2
    missing_deps=1
  else
    deps['awk']="$(command -v awk | head -n1)"
  fi

  if [[ -n $missing_deps ]]; then
    exit 1
  fi

  action="repo install"

  while [[ $# -gt 0 ]]; do
    key="$1"
    case "$key" in

      --account)

        if [[ -n ${2+x} ]]; then
          args['--account']="$2"
          shift
          shift
        else
          printf "%s\n" "--account requires an argument: --account ACCOUNT" >&2
          exit 1
        fi
        ;;

      --password)

        if [[ -n ${2+x} ]]; then
          args['--password']="$2"
          shift
          shift
        else
          printf "%s\n" "--password requires an argument: --password PASSWORD" >&2
          exit 1
        fi
        ;;

      --uri)

        if [[ -n ${2+x} ]]; then
          escaped="$(printf '%q' "$2")"
          if [[ -z ${args['--uri']+x} ]]; then
            args['--uri']="$escaped"
          else
            args['--uri']="${args['--uri']} $escaped"
          fi
          shift
          shift
        else
          printf "%s\n" "--uri requires an argument: --uri URI" >&2
          exit 1
        fi
        ;;

      -?*)
        printf "invalid option: %s\n" "$key" >&2
        exit 1
        ;;

      *)

        printf "invalid argument: %s\n" "$key" >&2
        exit 1

        ;;

    esac
  done

  filter_error=$(filter_is_valid_os)
  if [[ -n $filter_error ]]; then
    echo "$filter_error" >&2
    exit 1
  fi

  filter_error=$(filter_is_root)
  if [[ -n $filter_error ]]; then
    echo "$filter_error" >&2
    exit 1
  fi

}

zendphpctl_repo_uninstall_parse_requirements() {

  while [[ $# -gt 0 ]]; do
    key="$1"
    case "$key" in
      --help | -h)
        long_usage=yes
        zendphpctl_repo_uninstall_usage
        exit
        ;;

      *)
        break
        ;;

    esac
  done

  action="repo uninstall"

  while [[ $# -gt 0 ]]; do
    key="$1"
    case "$key" in

      -?*)
        printf "invalid option: %s\n" "$key" >&2
        exit 1
        ;;

      *)

        printf "invalid argument: %s\n" "$key" >&2
        exit 1

        ;;

    esac
  done

  filter_error=$(filter_is_valid_os)
  if [[ -n $filter_error ]]; then
    echo "$filter_error" >&2
    exit 1
  fi

  filter_error=$(filter_is_root)
  if [[ -n $filter_error ]]; then
    echo "$filter_error" >&2
    exit 1
  fi

}

zendphpctl_zendhq_parse_requirements() {

  while [[ $# -gt 0 ]]; do
    key="$1"
    case "$key" in
      --help | -h)
        long_usage=yes
        zendphpctl_zendhq_usage
        exit
        ;;

      *)
        break
        ;;

    esac
  done

  action=${1:-}

  case $action in
    -*) ;;

    token)
      action="token"
      shift
      zendphpctl_zendhq_token_parse_requirements "$@"
      shift $#
      ;;

    "")
      zendphpctl_zendhq_usage >&2
      exit 1
      ;;

    *)
      printf "invalid command: %s\n" "$action" >&2
      exit 1
      ;;

  esac

  while [[ $# -gt 0 ]]; do
    key="$1"
    case "$key" in

      -?*)
        printf "invalid option: %s\n" "$key" >&2
        exit 1
        ;;

      *)

        printf "invalid argument: %s\n" "$key" >&2
        exit 1

        ;;

    esac
  done

}

zendphpctl_zendhq_token_parse_requirements() {

  while [[ $# -gt 0 ]]; do
    key="$1"
    case "$key" in
      --help | -h)
        long_usage=yes
        zendphpctl_zendhq_token_usage
        exit
        ;;

      *)
        break
        ;;

    esac
  done

  missing_deps=

  if ! command -v awk >/dev/null 2>&1; then
    printf "missing dependency: awk\n" >&2
    missing_deps=1
  else
    deps['awk']="$(command -v awk | head -n1)"
  fi

  if ! command -v date >/dev/null 2>&1; then
    printf "missing dependency: date\n" >&2
    missing_deps=1
  else
    deps['date']="$(command -v date | head -n1)"
  fi

  if ! command -v sed >/dev/null 2>&1; then
    printf "missing dependency: sed\n" >&2
    missing_deps=1
  else
    deps['sed']="$(command -v sed | head -n1)"
  fi

  if ! command -v sha256sum >/dev/null 2>&1; then
    printf "missing dependency: sha256sum\n" >&2
    missing_deps=1
  else
    deps['sha256sum']="$(command -v sha256sum | head -n1)"
  fi

  if [[ -n $missing_deps ]]; then
    exit 1
  fi

  action="zendhq token"

  while [[ $# -gt 0 ]]; do
    key="$1"
    case "$key" in

      --no-restart)

        args['--no-restart']=1
        shift
        ;;

      -?*)
        printf "invalid option: %s\n" "$key" >&2
        exit 1
        ;;

      *)

        if [[ -z ${args['token']+x} ]]; then
          args['token']=$1
          shift
        else
          printf "invalid argument: %s\n" "$key" >&2
          exit 1
        fi

        ;;

    esac
  done

  if [[ -z ${args['token']+x} ]]; then
    printf "missing required argument: TOKEN\nusage: zendphpctl zendhq token TOKEN [OPTIONS]\n" >&2

    exit 1
  fi

  filter_error=$(filter_is_valid_os)
  if [[ -n $filter_error ]]; then
    echo "$filter_error" >&2
    exit 1
  fi

  filter_error=$(filter_is_not_ibm_i)
  if [[ -n $filter_error ]]; then
    echo "$filter_error" >&2
    exit 1
  fi

  filter_error=$(filter_is_root)
  if [[ -n $filter_error ]]; then
    echo "$filter_error" >&2
    exit 1
  fi

}

zendphpctl_zray_parse_requirements() {

  while [[ $# -gt 0 ]]; do
    key="$1"
    case "$key" in
      --help | -h)
        long_usage=yes
        zendphpctl_zray_usage
        exit
        ;;

      *)
        break
        ;;

    esac
  done

  action=${1:-}

  case $action in
    -*) ;;

    plugin)
      action="plugin"
      shift
      zendphpctl_zray_plugin_parse_requirements "$@"
      shift $#
      ;;

    "")
      zendphpctl_zray_usage >&2
      exit 1
      ;;

    *)
      printf "invalid command: %s\n" "$action" >&2
      exit 1
      ;;

  esac

  while [[ $# -gt 0 ]]; do
    key="$1"
    case "$key" in

      -?*)
        printf "invalid option: %s\n" "$key" >&2
        exit 1
        ;;

      *)

        printf "invalid argument: %s\n" "$key" >&2
        exit 1

        ;;

    esac
  done

}

zendphpctl_zray_plugin_parse_requirements() {

  while [[ $# -gt 0 ]]; do
    key="$1"
    case "$key" in
      --help | -h)
        long_usage=yes
        zendphpctl_zray_plugin_usage
        exit
        ;;

      *)
        break
        ;;

    esac
  done

  action=${1:-}

  case $action in
    -*) ;;

    install)
      action="install"
      shift
      zendphpctl_zray_plugin_install_parse_requirements "$@"
      shift $#
      ;;

    list)
      action="list"
      shift
      zendphpctl_zray_plugin_list_parse_requirements "$@"
      shift $#
      ;;

    disable)
      action="disable"
      shift
      zendphpctl_zray_plugin_disable_parse_requirements "$@"
      shift $#
      ;;

    enable)
      action="enable"
      shift
      zendphpctl_zray_plugin_enable_parse_requirements "$@"
      shift $#
      ;;

    "")
      zendphpctl_zray_plugin_usage >&2
      exit 1
      ;;

    *)
      printf "invalid command: %s\n" "$action" >&2
      exit 1
      ;;

  esac

  while [[ $# -gt 0 ]]; do
    key="$1"
    case "$key" in

      -?*)
        printf "invalid option: %s\n" "$key" >&2
        exit 1
        ;;

      *)

        printf "invalid argument: %s\n" "$key" >&2
        exit 1

        ;;

    esac
  done

}

zendphpctl_zray_plugin_install_parse_requirements() {

  while [[ $# -gt 0 ]]; do
    key="$1"
    case "$key" in
      --help | -h)
        long_usage=yes
        zendphpctl_zray_plugin_install_usage
        exit
        ;;

      *)
        break
        ;;

    esac
  done

  action="zray plugin install"

  while [[ $# -gt 0 ]]; do
    key="$1"
    case "$key" in

      --php)

        if [[ -n ${2+x} ]]; then
          args['--php']="$2"
          shift
          shift
        else
          printf "%s\n" "--php requires an argument: --php PHP" >&2
          exit 1
        fi
        ;;

      -?*)
        printf "invalid option: %s\n" "$key" >&2
        exit 1
        ;;

      *)

        printf "invalid argument: %s\n" "$key" >&2
        exit 1

        ;;

    esac
  done

  if [[ -v args['--php'] ]]; then
    validation_output="$(validate_php_version "${args['--php']:-}")"
    if [[ -n "${validation_output}" ]]; then
      printf "validation error in %s:\n%s\n" "--php PHP" "$validation_output" >&2
      exit 1
    fi
  fi

  filter_error=$(filter_is_valid_os)
  if [[ -n $filter_error ]]; then
    echo "$filter_error" >&2
    exit 1
  fi

  filter_error=$(filter_is_not_ibm_i)
  if [[ -n $filter_error ]]; then
    echo "$filter_error" >&2
    exit 1
  fi

  filter_error=$(filter_is_root)
  if [[ -n $filter_error ]]; then
    echo "$filter_error" >&2
    exit 1
  fi

}

zendphpctl_zray_plugin_list_parse_requirements() {

  while [[ $# -gt 0 ]]; do
    key="$1"
    case "$key" in
      --help | -h)
        long_usage=yes
        zendphpctl_zray_plugin_list_usage
        exit
        ;;

      *)
        break
        ;;

    esac
  done

  missing_deps=

  if ! command -v basename >/dev/null 2>&1; then
    printf "missing dependency: basename\n" >&2
    missing_deps=1
  else
    deps['basename']="$(command -v basename | head -n1)"
  fi

  if [[ -n $missing_deps ]]; then
    exit 1
  fi

  action="zray plugin list"

  while [[ $# -gt 0 ]]; do
    key="$1"
    case "$key" in

      --enabled)

        args['--enabled']=1
        shift
        ;;

      -?*)
        printf "invalid option: %s\n" "$key" >&2
        exit 1
        ;;

      *)

        printf "invalid argument: %s\n" "$key" >&2
        exit 1

        ;;

    esac
  done

  filter_error=$(filter_is_valid_os)
  if [[ -n $filter_error ]]; then
    echo "$filter_error" >&2
    exit 1
  fi

  filter_error=$(filter_is_not_ibm_i)
  if [[ -n $filter_error ]]; then
    echo "$filter_error" >&2
    exit 1
  fi

}

zendphpctl_zray_plugin_disable_parse_requirements() {

  while [[ $# -gt 0 ]]; do
    key="$1"
    case "$key" in
      --help | -h)
        long_usage=yes
        zendphpctl_zray_plugin_disable_usage
        exit
        ;;

      *)
        break
        ;;

    esac
  done

  missing_deps=

  if ! command -v mv >/dev/null 2>&1; then
    printf "missing dependency: mv\n" >&2
    missing_deps=1
  else
    deps['mv']="$(command -v mv | head -n1)"
  fi

  if ! command -v unlink >/dev/null 2>&1; then
    printf "missing dependency: unlink\n" >&2
    missing_deps=1
  else
    deps['unlink']="$(command -v unlink | head -n1)"
  fi

  if [[ -n $missing_deps ]]; then
    exit 1
  fi

  action="zray plugin disable"

  while [[ $# -gt 0 ]]; do
    key="$1"
    case "$key" in

      --)
        shift
        other_args+=("$@")
        break
        ;;

      -?*)
        other_args+=("$1")
        shift
        ;;

      *)

        other_args+=("$1")
        shift

        ;;

    esac
  done

  if [[ ${#other_args[@]} -eq 0 ]]; then
    printf "missing required argument: PLUGINS...\nusage: zendphpctl zray plugin disable [--] PLUGINS...\n" >&2
    exit 1
  fi

  filter_error=$(filter_is_valid_os)
  if [[ -n $filter_error ]]; then
    echo "$filter_error" >&2
    exit 1
  fi

  filter_error=$(filter_is_not_ibm_i)
  if [[ -n $filter_error ]]; then
    echo "$filter_error" >&2
    exit 1
  fi

  filter_error=$(filter_is_root)
  if [[ -n $filter_error ]]; then
    echo "$filter_error" >&2
    exit 1
  fi

}

zendphpctl_zray_plugin_enable_parse_requirements() {

  while [[ $# -gt 0 ]]; do
    key="$1"
    case "$key" in
      --help | -h)
        long_usage=yes
        zendphpctl_zray_plugin_enable_usage
        exit
        ;;

      *)
        break
        ;;

    esac
  done

  missing_deps=

  if ! command -v ln >/dev/null 2>&1; then
    printf "missing dependency: ln\n" >&2
    missing_deps=1
  else
    deps['ln']="$(command -v ln | head -n1)"
  fi

  if [[ -n $missing_deps ]]; then
    exit 1
  fi

  action="zray plugin enable"

  while [[ $# -gt 0 ]]; do
    key="$1"
    case "$key" in

      --)
        shift
        other_args+=("$@")
        break
        ;;

      -?*)
        other_args+=("$1")
        shift
        ;;

      *)

        other_args+=("$1")
        shift

        ;;

    esac
  done

  if [[ ${#other_args[@]} -eq 0 ]]; then
    printf "missing required argument: PLUGINS...\nusage: zendphpctl zray plugin enable [--] PLUGINS...\n" >&2
    exit 1
  fi

  filter_error=$(filter_is_valid_os)
  if [[ -n $filter_error ]]; then
    echo "$filter_error" >&2
    exit 1
  fi

  filter_error=$(filter_is_not_ibm_i)
  if [[ -n $filter_error ]]; then
    echo "$filter_error" >&2
    exit 1
  fi

  filter_error=$(filter_is_root)
  if [[ -n $filter_error ]]; then
    echo "$filter_error" >&2
    exit 1
  fi

}

php_config_parse_requirements() {

  while [[ $# -gt 0 ]]; do
    key="$1"
    case "$key" in
      --help | -h)
        long_usage=yes
        php_config_usage
        exit
        ;;

      *)
        break
        ;;

    esac
  done

  action="php-config"

  while [[ $# -gt 0 ]]; do
    key="$1"
    case "$key" in

      --fpm)

        args['--fpm']=1
        shift
        ;;

      -?*)
        printf "invalid option: %s\n" "$key" >&2
        exit 1
        ;;

      *)

        if [[ -z ${args['php']+x} ]]; then
          args['php']=$1
          shift
        else
          printf "invalid argument: %s\n" "$key" >&2
          exit 1
        fi

        ;;

    esac
  done

  if [[ -v args['php'] && -n $(validate_php_version "${args['php']:-}") ]]; then
    printf "validation error in %s:\n%s\n" "PHP" "$(validate_php_version "${args['php']:-}")" >&2
    exit 1
  fi

  filter_error=$(filter_is_valid_os)
  if [[ -n $filter_error ]]; then
    echo "$filter_error" >&2
    exit 1
  fi

  filter_error=$(filter_is_root)
  if [[ -n $filter_error ]]; then
    echo "$filter_error" >&2
    exit 1
  fi

}

php_list_installed_parse_requirements() {

  while [[ $# -gt 0 ]]; do
    key="$1"
    case "$key" in
      --help | -h)
        long_usage=yes
        php_list_installed_usage
        exit
        ;;

      *)
        break
        ;;

    esac
  done

  missing_deps=

  if ! command -v awk >/dev/null 2>&1; then
    printf "missing dependency: awk\n" >&2
    missing_deps=1
  else
    deps['awk']="$(command -v awk | head -n1)"
  fi

  if ! command -v cut >/dev/null 2>&1; then
    printf "missing dependency: cut\n" >&2
    missing_deps=1
  else
    deps['cut']="$(command -v cut | head -n1)"
  fi

  if ! command -v grep >/dev/null 2>&1; then
    printf "missing dependency: grep\n" >&2
    missing_deps=1
  else
    deps['grep']="$(command -v grep | head -n1)"
  fi

  if ! command -v head >/dev/null 2>&1; then
    printf "missing dependency: head\n" >&2
    missing_deps=1
  else
    deps['head']="$(command -v head | head -n1)"
  fi

  if ! command -v sed >/dev/null 2>&1; then
    printf "missing dependency: sed\n" >&2
    missing_deps=1
  else
    deps['sed']="$(command -v sed | head -n1)"
  fi

  if ! command -v tr >/dev/null 2>&1; then
    printf "missing dependency: tr\n" >&2
    missing_deps=1
  else
    deps['tr']="$(command -v tr | head -n1)"
  fi

  if [[ -n $missing_deps ]]; then
    exit 1
  fi

  action="php-list-installed"

  while [[ $# -gt 0 ]]; do
    key="$1"
    case "$key" in

      --verbose | -v)

        args['--verbose']=1
        shift
        ;;

      --json | -j)

        args['--json']=1
        shift
        ;;

      -?*)
        printf "invalid option: %s\n" "$key" >&2
        exit 1
        ;;

      *)

        printf "invalid argument: %s\n" "$key" >&2
        exit 1

        ;;

    esac
  done

}

php_set_default_parse_requirements() {

  while [[ $# -gt 0 ]]; do
    key="$1"
    case "$key" in
      --help | -h)
        long_usage=yes
        php_set_default_usage
        exit
        ;;

      *)
        break
        ;;

    esac
  done

  missing_deps=

  if ! command -v awk >/dev/null 2>&1; then
    printf "missing dependency: awk\n" >&2
    missing_deps=1
  else
    deps['awk']="$(command -v awk | head -n1)"
  fi

  if ! command -v grep >/dev/null 2>&1; then
    printf "missing dependency: grep\n" >&2
    missing_deps=1
  else
    deps['grep']="$(command -v grep | head -n1)"
  fi

  if [[ -n $missing_deps ]]; then
    exit 1
  fi

  action="php-set-default"

  while [[ $# -gt 0 ]]; do
    key="$1"
    case "$key" in

      -?*)
        printf "invalid option: %s\n" "$key" >&2
        exit 1
        ;;

      *)

        if [[ -z ${args['php']+x} ]]; then
          args['php']=$1
          shift
        else
          printf "invalid argument: %s\n" "$key" >&2
          exit 1
        fi

        ;;

    esac
  done

  if [[ -z ${args['php']+x} ]]; then
    printf "missing required argument: PHP\nusage: zendphpctl php-set-default PHP\n" >&2

    exit 1
  fi

  if [[ -v args['php'] && -n $(validate_php_version "${args['php']:-}") ]]; then
    printf "validation error in %s:\n%s\n" "PHP" "$(validate_php_version "${args['php']:-}")" >&2
    exit 1
  fi

  filter_error=$(filter_is_valid_os)
  if [[ -n $filter_error ]]; then
    echo "$filter_error" >&2
    exit 1
  fi

  filter_error=$(filter_is_root)
  if [[ -n $filter_error ]]; then
    echo "$filter_error" >&2
    exit 1
  fi

}

php_install_parse_requirements() {

  while [[ $# -gt 0 ]]; do
    key="$1"
    case "$key" in
      --help | -h)
        long_usage=yes
        php_install_usage
        exit
        ;;

      *)
        break
        ;;

    esac
  done

  missing_deps=

  if ! command -v awk >/dev/null 2>&1; then
    printf "missing dependency: awk\n" >&2
    missing_deps=1
  else
    deps['awk']="$(command -v awk | head -n1)"
  fi

  if ! command -v grep >/dev/null 2>&1; then
    printf "missing dependency: grep\n" >&2
    missing_deps=1
  else
    deps['grep']="$(command -v grep | head -n1)"
  fi

  if [[ -n $missing_deps ]]; then
    exit 1
  fi

  action="php-install"

  while [[ $# -gt 0 ]]; do
    key="$1"
    case "$key" in

      --not-default)

        args['--not-default']=1
        shift
        ;;

      -?*)
        printf "invalid option: %s\n" "$key" >&2
        exit 1
        ;;

      *)

        if [[ -z ${args['php']+x} ]]; then
          args['php']=$1
          shift
        else
          printf "invalid argument: %s\n" "$key" >&2
          exit 1
        fi

        ;;

    esac
  done

  if [[ -z ${args['php']+x} ]]; then
    printf "missing required argument: PHP\nusage: zendphpctl php-install PHP [OPTIONS]\n" >&2

    exit 1
  fi

  if [[ -n ${args['php']:-} ]] && [[ ! ${args['php']:-} =~ ^(5.6|7.1|7.2|7.3|7.4|8.0|8.1|8.2|8.3|8.4|8.5)$ ]]; then
    printf "%s\n" "php must be one of: 5.6, 7.1, 7.2, 7.3, 7.4, 8.0, 8.1, 8.2, 8.3, 8.4, 8.5" >&2
    exit 1
  fi

  filter_error=$(filter_is_valid_os)
  if [[ -n $filter_error ]]; then
    echo "$filter_error" >&2
    exit 1
  fi

  filter_error=$(filter_is_root)
  if [[ -n $filter_error ]]; then
    echo "$filter_error" >&2
    exit 1
  fi

}

php_uninstall_parse_requirements() {

  while [[ $# -gt 0 ]]; do
    key="$1"
    case "$key" in
      --help | -h)
        long_usage=yes
        php_uninstall_usage
        exit
        ;;

      *)
        break
        ;;

    esac
  done

  action="php-uninstall"

  while [[ $# -gt 0 ]]; do
    key="$1"
    case "$key" in

      -?*)
        printf "invalid option: %s\n" "$key" >&2
        exit 1
        ;;

      *)

        if [[ -z ${args['php']+x} ]]; then
          args['php']=$1
          shift
        else
          printf "invalid argument: %s\n" "$key" >&2
          exit 1
        fi

        ;;

    esac
  done

  if [[ -z ${args['php']+x} ]]; then
    printf "missing required argument: PHP\nusage: zendphpctl php-uninstall PHP\n" >&2

    exit 1
  fi

  if [[ -v args['php'] && -n $(validate_php_version "${args['php']:-}") ]]; then
    printf "validation error in %s:\n%s\n" "PHP" "$(validate_php_version "${args['php']:-}")" >&2
    exit 1
  fi

  filter_error=$(filter_is_valid_os)
  if [[ -n $filter_error ]]; then
    echo "$filter_error" >&2
    exit 1
  fi

  filter_error=$(filter_is_root)
  if [[ -n $filter_error ]]; then
    echo "$filter_error" >&2
    exit 1
  fi

}

php_exec_parse_requirements() {

  while [[ $# -gt 0 ]]; do
    key="$1"
    case "$key" in
      --help | -h)
        long_usage=yes
        php_exec_usage
        exit
        ;;

      *)
        break
        ;;

    esac
  done

  action="exec"

  while [[ $# -gt 0 ]]; do
    key="$1"
    case "$key" in

      --php)

        if [[ -n ${2+x} ]]; then
          args['--php']="$2"
          shift
          shift
        else
          printf "%s\n" "--php requires an argument: --php VERSION" >&2
          exit 1
        fi
        ;;

      --)
        shift
        other_args+=("$@")
        break
        ;;

      -?*)
        other_args+=("$1")
        shift
        ;;

      *)

        other_args+=("$1")
        shift

        ;;

    esac
  done

  if [[ ${#other_args[@]} -eq 0 ]]; then
    printf "missing required argument: ARGUMENTS...\nusage: zendphpctl exec [OPTIONS] [--] ARGUMENTS...\n" >&2
    exit 1
  fi

  if [[ -v args['--php'] ]]; then
    validation_output="$(validate_php_version "${args['--php']:-}")"
    if [[ -n "${validation_output}" ]]; then
      printf "validation error in %s:\n%s\n" "--php VERSION" "$validation_output" >&2
      exit 1
    fi
  fi

}

apache_mod_php_install_parse_requirements() {

  while [[ $# -gt 0 ]]; do
    key="$1"
    case "$key" in
      --help | -h)
        long_usage=yes
        apache_mod_php_install_usage
        exit
        ;;

      *)
        break
        ;;

    esac
  done

  action="apache-mod-php-install"

  while [[ $# -gt 0 ]]; do
    key="$1"
    case "$key" in

      -?*)
        printf "invalid option: %s\n" "$key" >&2
        exit 1
        ;;

      *)

        if [[ -z ${args['php']+x} ]]; then
          args['php']=$1
          shift
        else
          printf "invalid argument: %s\n" "$key" >&2
          exit 1
        fi

        ;;

    esac
  done

  if [[ -v args['php'] && -n $(validate_php_version "${args['php']:-}") ]]; then
    printf "validation error in %s:\n%s\n" "PHP" "$(validate_php_version "${args['php']:-}")" >&2
    exit 1
  fi

  filter_error=$(filter_is_valid_os)
  if [[ -n $filter_error ]]; then
    echo "$filter_error" >&2
    exit 1
  fi

  filter_error=$(filter_is_not_ibm_i)
  if [[ -n $filter_error ]]; then
    echo "$filter_error" >&2
    exit 1
  fi

  filter_error=$(filter_is_root)
  if [[ -n $filter_error ]]; then
    echo "$filter_error" >&2
    exit 1
  fi

}

apache_mod_php_is_installed_parse_requirements() {

  while [[ $# -gt 0 ]]; do
    key="$1"
    case "$key" in
      --help | -h)
        long_usage=yes
        apache_mod_php_is_installed_usage
        exit
        ;;

      *)
        break
        ;;

    esac
  done

  action="apache-mod-php-is-installed"

  while [[ $# -gt 0 ]]; do
    key="$1"
    case "$key" in

      -?*)
        printf "invalid option: %s\n" "$key" >&2
        exit 1
        ;;

      *)

        if [[ -z ${args['php']+x} ]]; then
          args['php']=$1
          shift
        else
          printf "invalid argument: %s\n" "$key" >&2
          exit 1
        fi

        ;;

    esac
  done

  filter_error=$(filter_is_valid_os)
  if [[ -n $filter_error ]]; then
    echo "$filter_error" >&2
    exit 1
  fi

}

apache_mod_php_uninstall_parse_requirements() {

  while [[ $# -gt 0 ]]; do
    key="$1"
    case "$key" in
      --help | -h)
        long_usage=yes
        apache_mod_php_uninstall_usage
        exit
        ;;

      *)
        break
        ;;

    esac
  done

  action="apache-mod-php-uninstall"

  while [[ $# -gt 0 ]]; do
    key="$1"
    case "$key" in

      -?*)
        printf "invalid option: %s\n" "$key" >&2
        exit 1
        ;;

      *)

        if [[ -z ${args['php']+x} ]]; then
          args['php']=$1
          shift
        else
          printf "invalid argument: %s\n" "$key" >&2
          exit 1
        fi

        ;;

    esac
  done

  if [[ -v args['php'] && -n $(validate_php_version "${args['php']:-}") ]]; then
    printf "validation error in %s:\n%s\n" "PHP" "$(validate_php_version "${args['php']:-}")" >&2
    exit 1
  fi

  filter_error=$(filter_is_valid_os)
  if [[ -n $filter_error ]]; then
    echo "$filter_error" >&2
    exit 1
  fi

  filter_error=$(filter_is_not_ibm_i)
  if [[ -n $filter_error ]]; then
    echo "$filter_error" >&2
    exit 1
  fi

  filter_error=$(filter_is_root)
  if [[ -n $filter_error ]]; then
    echo "$filter_error" >&2
    exit 1
  fi

}

ext_disable_parse_requirements() {

  while [[ $# -gt 0 ]]; do
    key="$1"
    case "$key" in
      --help | -h)
        long_usage=yes
        ext_disable_usage
        exit
        ;;

      *)
        break
        ;;

    esac
  done

  missing_deps=

  if ! command -v awk >/dev/null 2>&1; then
    printf "missing dependency: awk\n" >&2
    missing_deps=1
  else
    deps['awk']="$(command -v awk | head -n1)"
  fi

  if ! command -v find >/dev/null 2>&1; then
    printf "missing dependency: find\n" >&2
    missing_deps=1
  else
    deps['find']="$(command -v find | head -n1)"
  fi

  if ! command -v grep >/dev/null 2>&1; then
    printf "missing dependency: grep\n" >&2
    missing_deps=1
  else
    deps['grep']="$(command -v grep | head -n1)"
  fi

  if ! command -v sed >/dev/null 2>&1; then
    printf "missing dependency: sed\n" >&2
    missing_deps=1
  else
    deps['sed']="$(command -v sed | head -n1)"
  fi

  if [[ -n $missing_deps ]]; then
    exit 1
  fi

  action="ext-disable"

  while [[ $# -gt 0 ]]; do
    key="$1"
    case "$key" in

      --php)

        if [[ -n ${2+x} ]]; then
          args['--php']="$2"
          shift
          shift
        else
          printf "%s\n" "--php requires an argument: --php PHP" >&2
          exit 1
        fi
        ;;

      --sapi)

        if [[ -n ${2+x} ]]; then
          args['--sapi']="$2"
          shift
          shift
        else
          printf "%s\n" "--sapi requires an argument: --sapi SAPI" >&2
          exit 1
        fi
        ;;

      --)
        shift
        other_args+=("$@")
        break
        ;;

      -?*)
        other_args+=("$1")
        shift
        ;;

      *)

        other_args+=("$1")
        shift

        ;;

    esac
  done

  if [[ ${#other_args[@]} -eq 0 ]]; then
    printf "missing required argument: EXTENSIONS...\nusage: zendphpctl ext-disable [OPTIONS] [--] EXTENSIONS...\n" >&2
    exit 1
  fi

  [[ -n ${args['--sapi']:-} ]] || args['--sapi']="ALL"

  if [[ -v args['--php'] ]]; then
    validation_output="$(validate_php_version "${args['--php']:-}")"
    if [[ -n "${validation_output}" ]]; then
      printf "validation error in %s:\n%s\n" "--php PHP" "$validation_output" >&2
      exit 1
    fi
  fi

  if [[ ${args['--sapi']:-} ]] && [[ ! ${args['--sapi']:-} =~ ^(ALL|cli|fpm)$ ]]; then
    printf "%s\n" "--sapi must be one of: ALL, cli, fpm" >&2
    exit 1
  fi

  filter_error=$(filter_is_valid_os)
  if [[ -n $filter_error ]]; then
    echo "$filter_error" >&2
    exit 1
  fi

  filter_error=$(filter_is_root)
  if [[ -n $filter_error ]]; then
    echo "$filter_error" >&2
    exit 1
  fi

}

ext_enable_parse_requirements() {

  while [[ $# -gt 0 ]]; do
    key="$1"
    case "$key" in
      --help | -h)
        long_usage=yes
        ext_enable_usage
        exit
        ;;

      *)
        break
        ;;

    esac
  done

  missing_deps=

  if ! command -v curl >/dev/null 2>&1; then
    printf "missing dependency: curl\n" >&2
    missing_deps=1
  else
    deps['curl']="$(command -v curl | head -n1)"
  fi

  if ! command -v find >/dev/null 2>&1; then
    printf "missing dependency: find\n" >&2
    missing_deps=1
  else
    deps['find']="$(command -v find | head -n1)"
  fi

  if ! command -v grep >/dev/null 2>&1; then
    printf "missing dependency: grep\n" >&2
    missing_deps=1
  else
    deps['grep']="$(command -v grep | head -n1)"
  fi

  if ! command -v mkdir >/dev/null 2>&1; then
    printf "missing dependency: mkdir\n" >&2
    missing_deps=1
  else
    deps['mkdir']="$(command -v mkdir | head -n1)"
  fi

  if ! command -v rm >/dev/null 2>&1; then
    printf "missing dependency: rm\n" >&2
    missing_deps=1
  else
    deps['rm']="$(command -v rm | head -n1)"
  fi

  if ! command -v sed >/dev/null 2>&1; then
    printf "missing dependency: sed\n" >&2
    missing_deps=1
  else
    deps['sed']="$(command -v sed | head -n1)"
  fi

  if ! command -v sort >/dev/null 2>&1; then
    printf "missing dependency: sort\n" >&2
    missing_deps=1
  else
    deps['sort']="$(command -v sort | head -n1)"
  fi

  if ! command -v tar >/dev/null 2>&1; then
    printf "missing dependency: tar\n" >&2
    missing_deps=1
  else
    deps['tar']="$(command -v tar | head -n1)"
  fi

  if ! command -v tr >/dev/null 2>&1; then
    printf "missing dependency: tr\n" >&2
    missing_deps=1
  else
    deps['tr']="$(command -v tr | head -n1)"
  fi

  if ! command -v repoquery apt-cache apk >/dev/null 2>&1; then
    printf "missing dependency: repo_helper (repoquery/apt-cache/apk)\n" >&2
    printf "%s\n\n" "run 'dnf install yum-utils' or 'yum install yum-utils'" >&2
    missing_deps=1
  else
    deps['repo_helper']="$(command -v repoquery apt-cache apk | head -n1)"
  fi

  if [[ -n $missing_deps ]]; then
    exit 1
  fi

  action="ext-enable"

  while [[ $# -gt 0 ]]; do
    key="$1"
    case "$key" in

      --php)

        if [[ -n ${2+x} ]]; then
          args['--php']="$2"
          shift
          shift
        else
          printf "%s\n" "--php requires an argument: --php PHP" >&2
          exit 1
        fi
        ;;

      --sapi)

        if [[ -n ${2+x} ]]; then
          args['--sapi']="$2"
          shift
          shift
        else
          printf "%s\n" "--sapi requires an argument: --sapi SAPI" >&2
          exit 1
        fi
        ;;

      --)
        shift
        other_args+=("$@")
        break
        ;;

      -?*)
        other_args+=("$1")
        shift
        ;;

      *)

        other_args+=("$1")
        shift

        ;;

    esac
  done

  if [[ ${#other_args[@]} -eq 0 ]]; then
    printf "missing required argument: EXTENSIONS...\nusage: zendphpctl ext-enable [OPTIONS] [--] EXTENSIONS...\n" >&2
    exit 1
  fi

  [[ -n ${args['--sapi']:-} ]] || args['--sapi']="ALL"

  if [[ -v args['--php'] ]]; then
    validation_output="$(validate_php_version "${args['--php']:-}")"
    if [[ -n "${validation_output}" ]]; then
      printf "validation error in %s:\n%s\n" "--php PHP" "$validation_output" >&2
      exit 1
    fi
  fi

  if [[ ${args['--sapi']:-} ]] && [[ ! ${args['--sapi']:-} =~ ^(ALL|cli|fpm)$ ]]; then
    printf "%s\n" "--sapi must be one of: ALL, cli, fpm" >&2
    exit 1
  fi

  filter_error=$(filter_is_valid_os)
  if [[ -n $filter_error ]]; then
    echo "$filter_error" >&2
    exit 1
  fi

  filter_error=$(filter_is_root)
  if [[ -n $filter_error ]]; then
    echo "$filter_error" >&2
    exit 1
  fi

}

ext_install_parse_requirements() {

  while [[ $# -gt 0 ]]; do
    key="$1"
    case "$key" in
      --help | -h)
        long_usage=yes
        ext_install_usage
        exit
        ;;

      *)
        break
        ;;

    esac
  done

  missing_deps=

  if ! command -v curl >/dev/null 2>&1; then
    printf "missing dependency: curl\n" >&2
    missing_deps=1
  else
    deps['curl']="$(command -v curl | head -n1)"
  fi

  if ! command -v cut >/dev/null 2>&1; then
    printf "missing dependency: cut\n" >&2
    missing_deps=1
  else
    deps['cut']="$(command -v cut | head -n1)"
  fi

  if ! command -v grep >/dev/null 2>&1; then
    printf "missing dependency: grep\n" >&2
    missing_deps=1
  else
    deps['grep']="$(command -v grep | head -n1)"
  fi

  if ! command -v mkdir >/dev/null 2>&1; then
    printf "missing dependency: mkdir\n" >&2
    missing_deps=1
  else
    deps['mkdir']="$(command -v mkdir | head -n1)"
  fi

  if ! command -v rm >/dev/null 2>&1; then
    printf "missing dependency: rm\n" >&2
    missing_deps=1
  else
    deps['rm']="$(command -v rm | head -n1)"
  fi

  if ! command -v sed >/dev/null 2>&1; then
    printf "missing dependency: sed\n" >&2
    missing_deps=1
  else
    deps['sed']="$(command -v sed | head -n1)"
  fi

  if ! command -v sort >/dev/null 2>&1; then
    printf "missing dependency: sort\n" >&2
    missing_deps=1
  else
    deps['sort']="$(command -v sort | head -n1)"
  fi

  if ! command -v tar >/dev/null 2>&1; then
    printf "missing dependency: tar\n" >&2
    missing_deps=1
  else
    deps['tar']="$(command -v tar | head -n1)"
  fi

  if ! command -v tr >/dev/null 2>&1; then
    printf "missing dependency: tr\n" >&2
    missing_deps=1
  else
    deps['tr']="$(command -v tr | head -n1)"
  fi

  if ! command -v repoquery apt-cache apk >/dev/null 2>&1; then
    printf "missing dependency: repo_helper (repoquery/apt-cache/apk)\n" >&2
    printf "%s\n\n" "run 'dnf install yum-utils' or 'yum install yum-utils'" >&2
    missing_deps=1
  else
    deps['repo_helper']="$(command -v repoquery apt-cache apk | head -n1)"
  fi

  if [[ -n $missing_deps ]]; then
    exit 1
  fi

  action="ext-install"

  while [[ $# -gt 0 ]]; do
    key="$1"
    case "$key" in

      --php)

        if [[ -n ${2+x} ]]; then
          args['--php']="$2"
          shift
          shift
        else
          printf "%s\n" "--php requires an argument: --php PHP" >&2
          exit 1
        fi
        ;;

      --sapi)

        if [[ -n ${2+x} ]]; then
          args['--sapi']="$2"
          shift
          shift
        else
          printf "%s\n" "--sapi requires an argument: --sapi SAPI" >&2
          exit 1
        fi
        ;;

      --)
        shift
        other_args+=("$@")
        break
        ;;

      -?*)
        other_args+=("$1")
        shift
        ;;

      *)

        other_args+=("$1")
        shift

        ;;

    esac
  done

  if [[ ${#other_args[@]} -eq 0 ]]; then
    printf "missing required argument: EXTENSIONS...\nusage: zendphpctl ext-install [OPTIONS] [--] EXTENSIONS...\n" >&2
    exit 1
  fi

  [[ -n ${args['--sapi']:-} ]] || args['--sapi']="ALL"

  if [[ -v args['--php'] ]]; then
    validation_output="$(validate_php_version "${args['--php']:-}")"
    if [[ -n "${validation_output}" ]]; then
      printf "validation error in %s:\n%s\n" "--php PHP" "$validation_output" >&2
      exit 1
    fi
  fi

  if [[ ${args['--sapi']:-} ]] && [[ ! ${args['--sapi']:-} =~ ^(ALL|cli|fpm)$ ]]; then
    printf "%s\n" "--sapi must be one of: ALL, cli, fpm" >&2
    exit 1
  fi

  filter_error=$(filter_is_valid_os)
  if [[ -n $filter_error ]]; then
    echo "$filter_error" >&2
    exit 1
  fi

  filter_error=$(filter_is_root)
  if [[ -n $filter_error ]]; then
    echo "$filter_error" >&2
    exit 1
  fi

}

ext_list_enabled_parse_requirements() {

  while [[ $# -gt 0 ]]; do
    key="$1"
    case "$key" in
      --help | -h)
        long_usage=yes
        ext_list_enabled_usage
        exit
        ;;

      *)
        break
        ;;

    esac
  done

  missing_deps=

  if ! command -v basename >/dev/null 2>&1; then
    printf "missing dependency: basename\n" >&2
    missing_deps=1
  else
    deps['basename']="$(command -v basename | head -n1)"
  fi

  if ! command -v find >/dev/null 2>&1; then
    printf "missing dependency: find\n" >&2
    missing_deps=1
  else
    deps['find']="$(command -v find | head -n1)"
  fi

  if ! command -v grep >/dev/null 2>&1; then
    printf "missing dependency: grep\n" >&2
    missing_deps=1
  else
    deps['grep']="$(command -v grep | head -n1)"
  fi

  if ! command -v sed >/dev/null 2>&1; then
    printf "missing dependency: sed\n" >&2
    missing_deps=1
  else
    deps['sed']="$(command -v sed | head -n1)"
  fi

  if ! command -v sort >/dev/null 2>&1; then
    printf "missing dependency: sort\n" >&2
    missing_deps=1
  else
    deps['sort']="$(command -v sort | head -n1)"
  fi

  if [[ -n $missing_deps ]]; then
    exit 1
  fi

  action="ext-list-enabled"

  while [[ $# -gt 0 ]]; do
    key="$1"
    case "$key" in

      --fpm)

        args['--fpm']=1
        shift
        ;;

      -?*)
        printf "invalid option: %s\n" "$key" >&2
        exit 1
        ;;

      *)

        if [[ -z ${args['php']+x} ]]; then
          args['php']=$1
          shift
        else
          printf "invalid argument: %s\n" "$key" >&2
          exit 1
        fi

        ;;

    esac
  done

  if [[ -v args['php'] && -n $(validate_php_version "${args['php']:-}") ]]; then
    printf "validation error in %s:\n%s\n" "PHP" "$(validate_php_version "${args['php']:-}")" >&2
    exit 1
  fi

  filter_error=$(filter_is_valid_os)
  if [[ -n $filter_error ]]; then
    echo "$filter_error" >&2
    exit 1
  fi

}

ext_list_packages_parse_requirements() {

  while [[ $# -gt 0 ]]; do
    key="$1"
    case "$key" in
      --help | -h)
        long_usage=yes
        ext_list_packages_usage
        exit
        ;;

      *)
        break
        ;;

    esac
  done

  action="ext-list-packages"

  while [[ $# -gt 0 ]]; do
    key="$1"
    case "$key" in

      -?*)
        printf "invalid option: %s\n" "$key" >&2
        exit 1
        ;;

      *)

        printf "invalid argument: %s\n" "$key" >&2
        exit 1

        ;;

    esac
  done

}

fpm_config_parse_requirements() {

  while [[ $# -gt 0 ]]; do
    key="$1"
    case "$key" in
      --help | -h)
        long_usage=yes
        fpm_config_usage
        exit
        ;;

      *)
        break
        ;;

    esac
  done

  action="fpm-config"

  while [[ $# -gt 0 ]]; do
    key="$1"
    case "$key" in

      -?*)
        printf "invalid option: %s\n" "$key" >&2
        exit 1
        ;;

      *)

        if [[ -z ${args['php']+x} ]]; then
          args['php']=$1
          shift
        else
          printf "invalid argument: %s\n" "$key" >&2
          exit 1
        fi

        ;;

    esac
  done

  if [[ -v args['php'] && -n $(validate_php_version "${args['php']:-}") ]]; then
    printf "validation error in %s:\n%s\n" "PHP" "$(validate_php_version "${args['php']:-}")" >&2
    exit 1
  fi

  filter_error=$(filter_is_valid_os)
  if [[ -n $filter_error ]]; then
    echo "$filter_error" >&2
    exit 1
  fi

  filter_error=$(filter_is_root)
  if [[ -n $filter_error ]]; then
    echo "$filter_error" >&2
    exit 1
  fi

}

fpm_install_parse_requirements() {

  while [[ $# -gt 0 ]]; do
    key="$1"
    case "$key" in
      --help | -h)
        long_usage=yes
        fpm_install_usage
        exit
        ;;

      *)
        break
        ;;

    esac
  done

  action="fpm-install"

  while [[ $# -gt 0 ]]; do
    key="$1"
    case "$key" in

      -?*)
        printf "invalid option: %s\n" "$key" >&2
        exit 1
        ;;

      *)

        if [[ -z ${args['php']+x} ]]; then
          args['php']=$1
          shift
        else
          printf "invalid argument: %s\n" "$key" >&2
          exit 1
        fi

        ;;

    esac
  done

  if [[ -v args['php'] && -n $(validate_php_version "${args['php']:-}") ]]; then
    printf "validation error in %s:\n%s\n" "PHP" "$(validate_php_version "${args['php']:-}")" >&2
    exit 1
  fi

  filter_error=$(filter_is_valid_os)
  if [[ -n $filter_error ]]; then
    echo "$filter_error" >&2
    exit 1
  fi

  filter_error=$(filter_is_root)
  if [[ -n $filter_error ]]; then
    echo "$filter_error" >&2
    exit 1
  fi

}

fpm_is_installed_parse_requirements() {

  while [[ $# -gt 0 ]]; do
    key="$1"
    case "$key" in
      --help | -h)
        long_usage=yes
        fpm_is_installed_usage
        exit
        ;;

      *)
        break
        ;;

    esac
  done

  action="fpm-is-installed"

  while [[ $# -gt 0 ]]; do
    key="$1"
    case "$key" in

      -?*)
        printf "invalid option: %s\n" "$key" >&2
        exit 1
        ;;

      *)

        if [[ -z ${args['php']+x} ]]; then
          args['php']=$1
          shift
        else
          printf "invalid argument: %s\n" "$key" >&2
          exit 1
        fi

        ;;

    esac
  done

  filter_error=$(filter_is_valid_os)
  if [[ -n $filter_error ]]; then
    echo "$filter_error" >&2
    exit 1
  fi

}

fpm_uninstall_parse_requirements() {

  while [[ $# -gt 0 ]]; do
    key="$1"
    case "$key" in
      --help | -h)
        long_usage=yes
        fpm_uninstall_usage
        exit
        ;;

      *)
        break
        ;;

    esac
  done

  action="fpm-uninstall"

  while [[ $# -gt 0 ]]; do
    key="$1"
    case "$key" in

      -?*)
        printf "invalid option: %s\n" "$key" >&2
        exit 1
        ;;

      *)

        if [[ -z ${args['php']+x} ]]; then
          args['php']=$1
          shift
        else
          printf "invalid argument: %s\n" "$key" >&2
          exit 1
        fi

        ;;

    esac
  done

  if [[ -v args['php'] && -n $(validate_php_version "${args['php']:-}") ]]; then
    printf "validation error in %s:\n%s\n" "PHP" "$(validate_php_version "${args['php']:-}")" >&2
    exit 1
  fi

  filter_error=$(filter_is_valid_os)
  if [[ -n $filter_error ]]; then
    echo "$filter_error" >&2
    exit 1
  fi

  filter_error=$(filter_is_root)
  if [[ -n $filter_error ]]; then
    echo "$filter_error" >&2
    exit 1
  fi

}

repo_credentials_parse_requirements() {

  while [[ $# -gt 0 ]]; do
    key="$1"
    case "$key" in
      --help | -h)
        long_usage=yes
        repo_credentials_usage
        exit
        ;;

      *)
        break
        ;;

    esac
  done

  action="repo-credentials"

  while [[ $# -gt 0 ]]; do
    key="$1"
    case "$key" in

      --account)

        if [[ -n ${2+x} ]]; then
          args['--account']="$2"
          shift
          shift
        else
          printf "%s\n" "--account requires an argument: --account ACCOUNT" >&2
          exit 1
        fi
        ;;

      --password)

        if [[ -n ${2+x} ]]; then
          args['--password']="$2"
          shift
          shift
        else
          printf "%s\n" "--password requires an argument: --password PASSWORD" >&2
          exit 1
        fi
        ;;

      -?*)
        printf "invalid option: %s\n" "$key" >&2
        exit 1
        ;;

      *)

        printf "invalid argument: %s\n" "$key" >&2
        exit 1

        ;;

    esac
  done

  if [[ -z ${args['--account']+x} ]]; then
    printf "missing required flag: --account ACCOUNT\n" >&2
    exit 1
  fi
  if [[ -z ${args['--password']+x} ]]; then
    printf "missing required flag: --password PASSWORD\n" >&2
    exit 1
  fi

  filter_error=$(filter_is_valid_os)
  if [[ -n $filter_error ]]; then
    echo "$filter_error" >&2
    exit 1
  fi

  filter_error=$(filter_is_root)
  if [[ -n $filter_error ]]; then
    echo "$filter_error" >&2
    exit 1
  fi

}

repo_install_parse_requirements() {

  while [[ $# -gt 0 ]]; do
    key="$1"
    case "$key" in
      --help | -h)
        long_usage=yes
        repo_install_usage
        exit
        ;;

      *)
        break
        ;;

    esac
  done

  missing_deps=

  if ! command -v grep >/dev/null 2>&1; then
    printf "missing dependency: grep\n" >&2
    missing_deps=1
  else
    deps['grep']="$(command -v grep | head -n1)"
  fi

  if ! command -v sed >/dev/null 2>&1; then
    printf "missing dependency: sed\n" >&2
    missing_deps=1
  else
    deps['sed']="$(command -v sed | head -n1)"
  fi

  if ! command -v awk >/dev/null 2>&1; then
    printf "missing dependency: awk\n" >&2
    missing_deps=1
  else
    deps['awk']="$(command -v awk | head -n1)"
  fi

  if [[ -n $missing_deps ]]; then
    exit 1
  fi

  action="repo-install"

  while [[ $# -gt 0 ]]; do
    key="$1"
    case "$key" in

      --account)

        if [[ -n ${2+x} ]]; then
          args['--account']="$2"
          shift
          shift
        else
          printf "%s\n" "--account requires an argument: --account ACCOUNT" >&2
          exit 1
        fi
        ;;

      --password)

        if [[ -n ${2+x} ]]; then
          args['--password']="$2"
          shift
          shift
        else
          printf "%s\n" "--password requires an argument: --password PASSWORD" >&2
          exit 1
        fi
        ;;

      --uri)

        if [[ -n ${2+x} ]]; then
          escaped="$(printf '%q' "$2")"
          if [[ -z ${args['--uri']+x} ]]; then
            args['--uri']="$escaped"
          else
            args['--uri']="${args['--uri']} $escaped"
          fi
          shift
          shift
        else
          printf "%s\n" "--uri requires an argument: --uri URI" >&2
          exit 1
        fi
        ;;

      -?*)
        printf "invalid option: %s\n" "$key" >&2
        exit 1
        ;;

      *)

        printf "invalid argument: %s\n" "$key" >&2
        exit 1

        ;;

    esac
  done

  filter_error=$(filter_is_valid_os)
  if [[ -n $filter_error ]]; then
    echo "$filter_error" >&2
    exit 1
  fi

  filter_error=$(filter_is_root)
  if [[ -n $filter_error ]]; then
    echo "$filter_error" >&2
    exit 1
  fi

}

repo_uninstall_parse_requirements() {

  while [[ $# -gt 0 ]]; do
    key="$1"
    case "$key" in
      --help | -h)
        long_usage=yes
        repo_uninstall_usage
        exit
        ;;

      *)
        break
        ;;

    esac
  done

  action="repo-uninstall"

  while [[ $# -gt 0 ]]; do
    key="$1"
    case "$key" in

      -?*)
        printf "invalid option: %s\n" "$key" >&2
        exit 1
        ;;

      *)

        printf "invalid argument: %s\n" "$key" >&2
        exit 1

        ;;

    esac
  done

  filter_error=$(filter_is_valid_os)
  if [[ -n $filter_error ]]; then
    echo "$filter_error" >&2
    exit 1
  fi

  filter_error=$(filter_is_root)
  if [[ -n $filter_error ]]; then
    echo "$filter_error" >&2
    exit 1
  fi

}

zendhq_token_parse_requirements() {

  while [[ $# -gt 0 ]]; do
    key="$1"
    case "$key" in
      --help | -h)
        long_usage=yes
        zendhq_token_usage
        exit
        ;;

      *)
        break
        ;;

    esac
  done

  missing_deps=

  if ! command -v awk >/dev/null 2>&1; then
    printf "missing dependency: awk\n" >&2
    missing_deps=1
  else
    deps['awk']="$(command -v awk | head -n1)"
  fi

  if ! command -v date >/dev/null 2>&1; then
    printf "missing dependency: date\n" >&2
    missing_deps=1
  else
    deps['date']="$(command -v date | head -n1)"
  fi

  if ! command -v sed >/dev/null 2>&1; then
    printf "missing dependency: sed\n" >&2
    missing_deps=1
  else
    deps['sed']="$(command -v sed | head -n1)"
  fi

  if ! command -v sha256sum >/dev/null 2>&1; then
    printf "missing dependency: sha256sum\n" >&2
    missing_deps=1
  else
    deps['sha256sum']="$(command -v sha256sum | head -n1)"
  fi

  if [[ -n $missing_deps ]]; then
    exit 1
  fi

  action="zendhq-token"

  while [[ $# -gt 0 ]]; do
    key="$1"
    case "$key" in

      --no-restart)

        args['--no-restart']=1
        shift
        ;;

      -?*)
        printf "invalid option: %s\n" "$key" >&2
        exit 1
        ;;

      *)

        if [[ -z ${args['token']+x} ]]; then
          args['token']=$1
          shift
        else
          printf "invalid argument: %s\n" "$key" >&2
          exit 1
        fi

        ;;

    esac
  done

  if [[ -z ${args['token']+x} ]]; then
    printf "missing required argument: TOKEN\nusage: zendphpctl zendhq-token TOKEN [OPTIONS]\n" >&2

    exit 1
  fi

  filter_error=$(filter_is_valid_os)
  if [[ -n $filter_error ]]; then
    echo "$filter_error" >&2
    exit 1
  fi

  filter_error=$(filter_is_not_ibm_i)
  if [[ -n $filter_error ]]; then
    echo "$filter_error" >&2
    exit 1
  fi

  filter_error=$(filter_is_root)
  if [[ -n $filter_error ]]; then
    echo "$filter_error" >&2
    exit 1
  fi

}

zray_plugin_install_parse_requirements() {

  while [[ $# -gt 0 ]]; do
    key="$1"
    case "$key" in
      --help | -h)
        long_usage=yes
        zray_plugin_install_usage
        exit
        ;;

      *)
        break
        ;;

    esac
  done

  action="zray-plugins-install"

  while [[ $# -gt 0 ]]; do
    key="$1"
    case "$key" in

      --php)

        if [[ -n ${2+x} ]]; then
          args['--php']="$2"
          shift
          shift
        else
          printf "%s\n" "--php requires an argument: --php PHP" >&2
          exit 1
        fi
        ;;

      -?*)
        printf "invalid option: %s\n" "$key" >&2
        exit 1
        ;;

      *)

        printf "invalid argument: %s\n" "$key" >&2
        exit 1

        ;;

    esac
  done

  if [[ -v args['--php'] ]]; then
    validation_output="$(validate_php_version "${args['--php']:-}")"
    if [[ -n "${validation_output}" ]]; then
      printf "validation error in %s:\n%s\n" "--php PHP" "$validation_output" >&2
      exit 1
    fi
  fi

  filter_error=$(filter_is_valid_os)
  if [[ -n $filter_error ]]; then
    echo "$filter_error" >&2
    exit 1
  fi

  filter_error=$(filter_is_not_ibm_i)
  if [[ -n $filter_error ]]; then
    echo "$filter_error" >&2
    exit 1
  fi

  filter_error=$(filter_is_root)
  if [[ -n $filter_error ]]; then
    echo "$filter_error" >&2
    exit 1
  fi

}

zray_plugin_list_parse_requirements() {

  while [[ $# -gt 0 ]]; do
    key="$1"
    case "$key" in
      --help | -h)
        long_usage=yes
        zray_plugin_list_usage
        exit
        ;;

      *)
        break
        ;;

    esac
  done

  missing_deps=

  if ! command -v basename >/dev/null 2>&1; then
    printf "missing dependency: basename\n" >&2
    missing_deps=1
  else
    deps['basename']="$(command -v basename | head -n1)"
  fi

  if [[ -n $missing_deps ]]; then
    exit 1
  fi

  action="zray-plugins-list"

  while [[ $# -gt 0 ]]; do
    key="$1"
    case "$key" in

      --enabled)

        args['--enabled']=1
        shift
        ;;

      -?*)
        printf "invalid option: %s\n" "$key" >&2
        exit 1
        ;;

      *)

        printf "invalid argument: %s\n" "$key" >&2
        exit 1

        ;;

    esac
  done

  filter_error=$(filter_is_valid_os)
  if [[ -n $filter_error ]]; then
    echo "$filter_error" >&2
    exit 1
  fi

  filter_error=$(filter_is_not_ibm_i)
  if [[ -n $filter_error ]]; then
    echo "$filter_error" >&2
    exit 1
  fi

}

zray_plugin_disable_parse_requirements() {

  while [[ $# -gt 0 ]]; do
    key="$1"
    case "$key" in
      --help | -h)
        long_usage=yes
        zray_plugin_disable_usage
        exit
        ;;

      *)
        break
        ;;

    esac
  done

  missing_deps=

  if ! command -v mv >/dev/null 2>&1; then
    printf "missing dependency: mv\n" >&2
    missing_deps=1
  else
    deps['mv']="$(command -v mv | head -n1)"
  fi

  if ! command -v unlink >/dev/null 2>&1; then
    printf "missing dependency: unlink\n" >&2
    missing_deps=1
  else
    deps['unlink']="$(command -v unlink | head -n1)"
  fi

  if [[ -n $missing_deps ]]; then
    exit 1
  fi

  action="zray-plugin-disable"

  while [[ $# -gt 0 ]]; do
    key="$1"
    case "$key" in

      --)
        shift
        other_args+=("$@")
        break
        ;;

      -?*)
        other_args+=("$1")
        shift
        ;;

      *)

        other_args+=("$1")
        shift

        ;;

    esac
  done

  if [[ ${#other_args[@]} -eq 0 ]]; then
    printf "missing required argument: PLUGINS...\nusage: zendphpctl zray-plugin-disable [--] PLUGINS...\n" >&2
    exit 1
  fi

  filter_error=$(filter_is_valid_os)
  if [[ -n $filter_error ]]; then
    echo "$filter_error" >&2
    exit 1
  fi

  filter_error=$(filter_is_not_ibm_i)
  if [[ -n $filter_error ]]; then
    echo "$filter_error" >&2
    exit 1
  fi

  filter_error=$(filter_is_root)
  if [[ -n $filter_error ]]; then
    echo "$filter_error" >&2
    exit 1
  fi

}

zray_plugin_enable_parse_requirements() {

  while [[ $# -gt 0 ]]; do
    key="$1"
    case "$key" in
      --help | -h)
        long_usage=yes
        zray_plugin_enable_usage
        exit
        ;;

      *)
        break
        ;;

    esac
  done

  missing_deps=

  if ! command -v ln >/dev/null 2>&1; then
    printf "missing dependency: ln\n" >&2
    missing_deps=1
  else
    deps['ln']="$(command -v ln | head -n1)"
  fi

  if [[ -n $missing_deps ]]; then
    exit 1
  fi

  action="zray-plugin-enable"

  while [[ $# -gt 0 ]]; do
    key="$1"
    case "$key" in

      --)
        shift
        other_args+=("$@")
        break
        ;;

      -?*)
        other_args+=("$1")
        shift
        ;;

      *)

        other_args+=("$1")
        shift

        ;;

    esac
  done

  if [[ ${#other_args[@]} -eq 0 ]]; then
    printf "missing required argument: PLUGINS...\nusage: zendphpctl zray-plugin-enable [--] PLUGINS...\n" >&2
    exit 1
  fi

  filter_error=$(filter_is_valid_os)
  if [[ -n $filter_error ]]; then
    echo "$filter_error" >&2
    exit 1
  fi

  filter_error=$(filter_is_not_ibm_i)
  if [[ -n $filter_error ]]; then
    echo "$filter_error" >&2
    exit 1
  fi

  filter_error=$(filter_is_root)
  if [[ -n $filter_error ]]; then
    echo "$filter_error" >&2
    exit 1
  fi

}

initialize() {
  declare -g version="0.2.60"
  set -e


}

run() {

  declare -g long_usage=''
  declare -g -A args=()
  declare -g -a other_args=()
  declare -g -A deps=()
  declare -g -a env_var_names=()
  declare -g -a input=()

  normalize_input "$@"
  parse_requirements "${input[@]}"

  case "$action" in
    "completions") zendphpctl_completions_command ;;
    "self-update") zendphpctl_self_update_command ;;
    "apache") zendphpctl_apache_command ;;
    "apache mod_php") zendphpctl_apache_mod_php_command ;;
    "apache mod_php install") zendphpctl_apache_mod_php_install_command ;;
    "apache mod_php is-installed") zendphpctl_apache_mod_php_is_installed_command ;;
    "apache mod_php uninstall") zendphpctl_apache_mod_php_uninstall_command ;;
    "ext") zendphpctl_ext_command ;;
    "ext disable") zendphpctl_ext_disable_command ;;
    "ext enable") zendphpctl_ext_enable_command ;;
    "ext install") zendphpctl_ext_install_command ;;
    "ext list-enabled") zendphpctl_ext_list_enabled_command ;;
    "ext list-packages") zendphpctl_ext_list_packages_command ;;
    "fpm") zendphpctl_fpm_command ;;
    "fpm config") zendphpctl_fpm_config_command ;;
    "fpm install") zendphpctl_fpm_install_command ;;
    "fpm is-installed") zendphpctl_fpm_is_installed_command ;;
    "fpm uninstall") zendphpctl_fpm_uninstall_command ;;
    "php") zendphpctl_php_command ;;
    "php config") zendphpctl_php_config_command ;;
    "php list-installed") zendphpctl_php_list_installed_command ;;
    "php list-sapis") zendphpctl_php_list_sapis_command ;;
    "php set-default") zendphpctl_php_set_default_command ;;
    "php get-default") zendphpctl_php_get_default_command ;;
    "php info") zendphpctl_php_info_command ;;
    "php install") zendphpctl_php_install_command ;;
    "php uninstall") zendphpctl_php_uninstall_command ;;
    "php exec") zendphpctl_php_exec_command ;;
    "repo") zendphpctl_repo_command ;;
    "repo credentials") zendphpctl_repo_credentials_command ;;
    "repo install") zendphpctl_repo_install_command ;;
    "repo uninstall") zendphpctl_repo_uninstall_command ;;
    "zendhq") zendphpctl_zendhq_command ;;
    "zendhq token") zendphpctl_zendhq_token_command ;;
    "zray") zendphpctl_zray_command ;;
    "zray plugin") zendphpctl_zray_plugin_command ;;
    "zray plugin install") zendphpctl_zray_plugin_install_command ;;
    "zray plugin list") zendphpctl_zray_plugin_list_command ;;
    "zray plugin disable") zendphpctl_zray_plugin_disable_command ;;
    "zray plugin enable") zendphpctl_zray_plugin_enable_command ;;
    "php-config") php_config_command ;;
    "php-list-installed") php_list_installed_command ;;
    "php-set-default") php_set_default_command ;;
    "php-install") php_install_command ;;
    "php-uninstall") php_uninstall_command ;;
    "exec") php_exec_command ;;
    "apache-mod-php-install") apache_mod_php_install_command ;;
    "apache-mod-php-is-installed") apache_mod_php_is_installed_command ;;
    "apache-mod-php-uninstall") apache_mod_php_uninstall_command ;;
    "ext-disable") ext_disable_command ;;
    "ext-enable") ext_enable_command ;;
    "ext-install") ext_install_command ;;
    "ext-list-enabled") ext_list_enabled_command ;;
    "ext-list-packages") ext_list_packages_command ;;
    "fpm-config") fpm_config_command ;;
    "fpm-install") fpm_install_command ;;
    "fpm-is-installed") fpm_is_installed_command ;;
    "fpm-uninstall") fpm_uninstall_command ;;
    "repo-credentials") repo_credentials_command ;;
    "repo-install") repo_install_command ;;
    "repo-uninstall") repo_uninstall_command ;;
    "zendhq-token") zendhq_token_command ;;
    "zray-plugins-install") zray_plugin_install_command ;;
    "zray-plugins-list") zray_plugin_list_command ;;
    "zray-plugin-disable") zray_plugin_disable_command ;;
    "zray-plugin-enable") zray_plugin_enable_command ;;
  esac
}

initialize
run "$@"
