#!/bin/bash
#
# BlueButton open source conferencing system - https://www.bigbluebutton.org/
#
# Copyright (c) 2020 BigBlueButton Inc. and by respective authors (see below).
#
# This program is free software; you can redistribute it and/or modify it under the
# terms of the GNU Lesser General Public License as published by the Free Software
# Foundation; either version 3.0 of the License, or (at your option) any later
# version.
#
# BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License along
# with BigBlueButton; if not, see <https://www.gnu.org/licenses/>.
#
# Author(s):
#   Fred Dixon <ffdixon@bigbluebutton.org>
#   Sebastian Schneider <seb.sschneider@gmail.com>
#   Ghazi Triki <ghazi.nocturne@gmail.com>
#
# Changelog:
#   2009-10-18 FFD  Initial Version
#   2009-11-05 FFD  Updated for 0.62
#   2009-12-09 FFD  Updated for 0.63
#   2009-12-11 FFD  Added ability to switch conference servers
#   2009-12-12 FFD  Added cleaning and watching of log files
#   2010-01-05 FFD  Added zipping of log files
#   2010-01-18 FFD  Added resetting of environment back to using packages
#   2010-03-02 JRT  Added trunk checkout options / fixed bbb-apps instructions
#   2010-04-02 FFD  Updated for 0.64
#   2010-06-21 SEB  Cleaned up some code / Updated for 0.70
#   2010-06-25 SEB  Added ability to change the security secret
#   2010-06-30 SEB  Added some extra error checking
#   2010-07-06 SEB  Added more error checking and report messages
#   2010-09-15 FFD  Updates for 0.71-dev
#   2010-10-16 FFD  Updates for 0.71-beta
#   2010-11-06 FFD  Added logic to ensure red5 shuts down
#   2010-12-12 FFD  Fixed bug #778
#   2010-12-12 FFD  Added support for Intalio VM
#   2010-02-28 FFD  Fixed #834
#   2011-06-26 FFD  Updates for 0.8
#   2012-01-14 FFD  Testing the development environment for 0.8
#   2012-02-22 FFD  Updates to development environment
#   2012-04-27 FFD  Added sum of version numbers in --check
#   2013-02-03 FFD  Updated for changes to parameters for 0.81 in bigbluebutton-sip.properties
#   2013-11-07 FFD  Finished 0.81
#   2014-01-13 FFD  Working on updates for 0.9.0
#   2014-03-10 GUG  Enable WebRTC
#   2015-03-12 FFD  Added start/stop of HTML5 server
#   2016-01-13 FFD  Updates for 1.0
#   2016-02-28 FFD  Updates to support HTTPS configuration
#   2016-05-28 FFD  Initial updates for 1.1-dev
#   2016-08-15 GTR  Archive more logs with zip option and show more applications with status
#   2016-10-17 GTR  Added redis to checked server components & added ownership check for video and freeswitch recording directories
#   2017-04-08 FFD  Cleanup for 1.1-beta
#   2018-11-22 MNE  Dynamically detect if sudo is needed
#   2018-12-09 GTR  More logs cleanup
#   2019-02-08 GTR  Updates for 2.2 after extracting bbb-web to a standalone server application
#   2019-03-14 FFD  Refactoring and cleanup for 2.2
#   2019-05-14 FFD  Added more checks for configuration issues
#   2019-07-08 GTR  Set IP for all recording formats
#   2019-10-31 GTR  Set IP and shared secret for bbb-webhooks
#   2019-11-09 GTR  Keep HTML5 client logs permissions when cleaning logs
#   2020-05-20 NJH  Add port 443 to --Network and clean up tmp file.
#   2020-06-23 JFS  Remove defaultGuestPolicy warning for HTML5 client
#   2020-10-22 AGG  Removing Flash/Red5 related code (yay!)
#   2021-07-16 JFS  Add defaultMeetingLayout information

#set -x
#set -e

PATH=$PATH:/sbin

if [[ "$(id -u)" != "0" ]]; then
    if [[ -x "$(which sudo)" ]]; then
        SUDO="$(which sudo)"
    else
        echo "bbb-conf must be ran as root!" && exit 1
    fi
fi

if [[ ! -f /etc/bigbluebutton/bigbluebutton-release ]]; then
    echo
    echo "# BigBlueButton does not appear to be installed.  Could not"
    echo "# locate: /etc/bigbluebutton/bigbluebutton-release"
    echo
    exit 1
fi

# Load the content of the file as variables
source /etc/bigbluebutton/bigbluebutton-release

#
# Figure out our environment (Debian vs. CentOS)
#

if [ -f /etc/centos-release ] || [ -f /etc/system-release ]; then
    DISTRIB_ID=centos
    REDIS_SERVICE=redis.service
else
    . /etc/lsb-release    # Get value for DISTRIB_ID
    REDIS_SERVICE=redis-server
fi

# Common to Ubuntu and CentOS
FREESWITCH_VARS=/opt/freeswitch/etc/freeswitch/vars.xml
FREESWITCH_EXTERNAL=/opt/freeswitch/etc/freeswitch/sip_profiles/external.xml
FREESWITCH_PID=/opt/freeswitch/var/run/freeswitch/freeswitch.pid
FREESWITCH_EVENT_SOCKET=/opt/freeswitch/etc/freeswitch/autoload_configs/event_socket.conf.xml
FREESWITCH_SWITCH_CONF=/opt/freeswitch/etc/freeswitch/autoload_configs/switch.conf.xml

if [ -f /usr/share/bbb-web/WEB-INF/classes/bigbluebutton.properties ]; then
    SERVLET_DIR=/usr/share/bbb-web
fi


get_properties_value() {
    key="$1"
    file="$2"
    if [[ -f $file ]]; then
        val=$(grep "^$key" "$file"| cut -d = -f 2-)
        echo "$val"
        return 0
    fi
    return 1
}
get_bbb_web_config_value() {
    key="$1"
    val="$(get_properties_value "$key" "$BBB_WEB_ETC_CONFIG")"
    if [[ -n $val ]]; then
        echo "$val"
        return 0
    fi
    val="$(get_properties_value "$key" "$BBB_WEB_CONFIG")"
    if [[ -n $val ]]; then
        echo "$val"
        return 0
    fi
    return 1
}

RECORD_CONFIG=/usr/local/bigbluebutton/core/scripts/bigbluebutton.yml

WEBRTC_RECORDER_DEFAULT_CONFIG=/etc/bbb-webrtc-recorder/bbb-webrtc-recorder.yml
WEBRTC_RECORDER_ETC_CONFIG=/etc/bigbluebutton/bbb-webrtc-recorder.yml
if [ -f $WEBRTC_RECORDER_ETC_CONFIG ]; then
    WEBRTC_RECORDER_CONFIG=$(yq eval-all '. as $item ireduce ({}; . * $item )' $WEBRTC_RECORDER_DEFAULT_CONFIG $WEBRTC_RECORDER_ETC_CONFIG 2> /dev/null)
else
    WEBRTC_RECORDER_CONFIG=$(yq e $WEBRTC_RECORDER_DEFAULT_CONFIG 2> /dev/null)
fi

HTML5_DEFAULT_CONFIG=/usr/share/bigbluebutton/html5-client/private/config/settings.yml
HTML5_ETC_CONFIG=/etc/bigbluebutton/bbb-html5.yml
if [ -f $HTML5_ETC_CONFIG ]; then
    HTML5_CONFIG=$(yq eval-all '. as $item ireduce ({}; . * $item )' $HTML5_DEFAULT_CONFIG $HTML5_ETC_CONFIG 2> /dev/null)
else
    HTML5_CONFIG=$(yq e $HTML5_DEFAULT_CONFIG 2> /dev/null)
fi

mkdir -p /etc/bigbluebutton/bbb-webrtc-sfu
WEBRTC_SFU_DEFAULT_CONFIG=/usr/local/bigbluebutton/bbb-webrtc-sfu/config/default.yml
WEBRTC_SFU_ETC_CONFIG=/etc/bigbluebutton/bbb-webrtc-sfu/production.yml
WEBRTC_SFU_CONFIG=$(yq eval-all '. as $item ireduce ({}; . * $item )' $WEBRTC_SFU_DEFAULT_CONFIG $WEBRTC_SFU_ETC_CONFIG 2> /dev/null)

LIVEKIT_SERVER_DEFAULT_CONFIG=/usr/share/livekit-server/livekit.yaml
LIVEKIT_SERVER_ETC_CONFIG=/etc/bigbluebutton/livekit.yaml
if [ -f $LIVEKIT_SERVER_ETC_CONFIG ]; then
    LIVEKIT_SERVER_CONFIG=$(yq eval-all '. as $item ireduce ({}; . * $item )' $LIVEKIT_SERVER_DEFAULT_CONFIG $LIVEKIT_SERVER_ETC_CONFIG 2> /dev/null)
else
    LIVEKIT_SERVER_CONFIG=$(yq e $LIVEKIT_SERVER_DEFAULT_CONFIG 2> /dev/null)
fi


BBB_WEB_CONFIG="$SERVLET_DIR/WEB-INF/classes/bigbluebutton.properties"
BBB_WEB_ETC_CONFIG="/etc/bigbluebutton/bbb-web.properties"

# Properties that have been retired and should no longer be set by administrators.
# bbb-conf --check will warn if any of these are found in $BBB_WEB_ETC_CONFIG.
RETIRED_BBB_WEB_PROPERTIES=(
    breakoutRoomsEnabled              # Removed in BBB 3.0
    learningDashboardEnabled          # Removed in BBB 3.0
    defaultGuestWaitURL               # Removed in BBB 3.0
    pdfToSvgTimeout                   # Removed in BBB 3.0.13
    pngCreationWait                   # Removed in BBB 3.0.13
    maxConversionTime                 # Removed in BBB 3.0.15
    pngCreationExecTimeoutInMs        # Renamed in BBB 3.0.17 (use pngCreationExecTimeout instead)
    thumbnailCreationExecTimeoutInMs  # Renamed in BBB 3.0.17 (use thumbnailCreationExecTimeout instead)
    textFileCreationExecTimeoutInMs   # Renamed in BBB 3.0.17 (use textFileCreationExecTimeout instead)
    insertDocumentSupportedProtocols  # Renamed in BBB 3.0.23 (use fetchUrlSupportedProtocols instead)
    insertDocumentBlockedHosts        # Renamed in BBB 3.0.23 (use fetchUrlBlockedExternalHosts instead)
)
NGINX_IP=$(cat /etc/nginx/sites-available/bigbluebutton | grep -v '#' | sed -n '/server_name/{s/.*server_name[ ]*//;s/;//;p}' | cut -d' ' -f1 | head -n 1)
SIP_CONFIG=/usr/share/bigbluebutton/nginx/sip.nginx
SIP_NGINX_IP=$(cat $SIP_CONFIG |  grep -v '#' | sed -n '/proxy_pass/{s/.*proxy_pass http[s]*:\/\///;s/:.*//;p}' | head -n 1)

NCPU=$(nproc --all)

BBB_USER=bigbluebutton

if [ $EUID == 0 ]; then
  TURN=$SERVLET_DIR/WEB-INF/classes/spring/turn-stun-servers.xml
  TURN_ETC_CONFIG=/etc/bigbluebutton/turn-stun-servers.xml
  if [ -f "$TURN_ETC_CONFIG" ]; then
    TURN=$TURN_ETC_CONFIG
  fi
  STUN="$(xmlstarlet sel -N x="http://www.springframework.org/schema/beans" -t -m '_:beans/_:bean[@class="org.bigbluebutton.web.services.turn.StunTurnService"]/_:property[@name="stunServers"]/_:set/_:ref' -v @bean -nl $TURN)"
fi

PROTOCOL=http
if [ -f $SERVLET_DIR/WEB-INF/classes/bigbluebutton.properties ]; then
    SERVER_URL=$(get_bbb_web_config_value bigbluebutton.web.serverURL | sed -n '{s/.*\///;p}')
    if get_bbb_web_config_value bigbluebutton.web.serverURL | grep -q https; then
        PROTOCOL=https
    fi
fi

#
# We're going to give ^bigbluebutton.web.logoutURL a default value (if undefined) so bbb-conf does not give a warning
#
if [ -f $SERVLET_DIR/WEB-INF/classes/bigbluebutton.properties ]; then
    if [ -z "$(get_bbb_web_config_value bigbluebutton.web.logoutURL)" ]; then
        echo "bigbluebutton.web.logoutURL=default" >> $BBB_WEB_ETC_CONFIG
    fi
fi

#
# Determine IP so it works on multilingual installations
#

### duplicated code: see deb-helper.sh and apply-lib.sh
if [ -e "/sys/class/net/venet0:0" ]; then
    # IP detection for OpenVZ environment
    _dev="venet0:0"
else
    _dev=$(awk '$2 == 00000000 { print $1 }' /proc/net/route | head -1)
fi
_ips=$(LANG=C ip -4 -br address show dev "$_dev" | awk '{ $1=$2=""; print $0 }')
_ips=${_ips/127.0.0.1\/8/}
read -r IP _ <<< "$_ips"
IP=${IP/\/*} # strip subnet provided by ip address
if [ -z "$IP" ]; then
  read -r IP _ <<< "$(hostname -I)"
fi

#
# Calculate total memory on this server
#
MEM=$(grep MemTotal /proc/meminfo | awk '{print $2}')
MEM=$((MEM/1000))

#
# Check if the function has a value and, if not, print an error message
# $1 -- name of value
# $2 -- location of value
# $3 -- value to check
#
check_no_value() {
    if [ -z $3 ]; then
        echo "# Tried to check $1 in"
        echo "#    $2"
        echo "# but value is empty."
        exit 1
    fi
}

check_file() {
    if [ ! -f $1 ]; then
        echo "# File does not exist: $1"
    fi
}

print_header() {
    if [ ! $HEADER ]; then
        echo
        echo "# Potential problems described below"
        HEADER=1
    fi
}

need_root() {
    if [ $EUID != 0 ]; then
        echo "Need to be root to run this option"
        exit 1
    fi
}



usage() {
    echo "BigBlueButton Configuration Utility - Version $BIGBLUEBUTTON_RELEASE"
    echo
    echo "   bbb-conf [options]"
    echo
    echo "Configuration:"
    echo "   --version                        Display BigBlueButton version (packages)"
    echo "   --setip <IP/hostname>            Set IP/hostname for BigBlueButton"
    echo "   --setsecret <secret>             Change the shared secret in /etc/bigbluebutton/bbb-web.properties"
    echo "   --set-port-range MIN-MAX         Change UDP port range used for audio/video/screenshare"
    echo
    echo "Monitoring:"
    echo "   --check                          Check configuration files and processes for problems"
    echo "   --debug                          Scan the log files for error messages"
    echo "   --watch                          Scan the log files for error messages every 2 seconds"
    echo "   --network                        View network connections on 80, 443 and 1935 by IP address. 1935 is deprecated. You will need to modify bbb-conf if you have custom ports."
    echo "   --secret                         View the URL and shared secret for the server"
    echo
    echo "Administration:"
    echo "   --restart                        Restart BigBlueButton"
    echo "   --stop                           Stop BigBlueButton"
    echo "   --start                          Start BigBlueButton"
    echo "   --clean                          Restart and clean all log files"
    echo "   --status                         Display running status of components"
    echo "   --zip                            Zip up log files for reporting an error"
    echo
}

# utility function to make a copy of the conf file
check_and_backup () {
    # can we write to the configuration file?
    if [ ! -w $1 ]; then
        echo "Cannot write to $1!"
        exit 1
    fi

    # let's see if we need a copy
    if [ "$TO_BACKUP" = "Y" ]; then
        cp $1 $1.bak
        TO_BACKUP="N"
    fi
}

# 3 parameter: the file, the variable name, the new value
change_var_value () {
    check_and_backup $1
    sed -i "s<^[[:blank:]#]*\(${2}\).*<\1=${3}<" $1
}

# same as change_var_value but with quotes
change_var_salt() {
    check_and_backup $1
    sed -i "s<^[[:blank:]#]*\(${2}\).*<\1="${3}"<" $1
}

# comment lines matching $2 ($1 is the file)
comment () {
    check_and_backup $1
    sed -i "s<^[[:blank:]]*\(${2}.*\)<#\1<" $1
}

change_yml_value () {
    sed -i "s<^\([[:blank:]#]*\)\(${2}\): .*<\1\2: ${3}<" $1
}


# comment lines matching $2 ($1 is the file)
uncomment () {
    check_and_backup $1
    sed -i "s<^[#[:blank:]]*\(${2}.*\)<\1<" $1
}

stop_bigbluebutton () {
    echo "Stopping BigBlueButton"
    systemctl stop bigbluebutton.target
}

start_bigbluebutton () {
    #
    # Apply any local configuration options (if exists)
    #
    if [ -x /etc/bigbluebutton/bbb-conf/apply-config.sh ]; then
        echo
        echo "Applying updates in /etc/bigbluebutton/bbb-conf/apply-config.sh: "
        /etc/bigbluebutton/bbb-conf/apply-config.sh
        echo
    fi

    if [ -f /opt/freeswitch/var/log/freeswitch/freeswitch.log ]; then
        if grep -q "Failure to connect to CORE_DB sofia_reg_external" /opt/freeswitch/var/log/freeswitch/freeswitch.log; then
            # See: https://docs.bigbluebutton.org/install/install.html#freeswitch-fails-to-bind-to-ipv4
            echo "Clearing the FreeSWITCH database."
            rm -rf /opt/freeswitch/var/lib/freeswitch/db/*
        fi
    fi

    echo "Reloading NginX configuration, restarting if needed"
    systemctl reload-or-restart nginx

    echo "Starting BigBlueButton"

    systemctl restart bigbluebutton.target
}

display_bigbluebutton_status () {
    units="nginx freeswitch $REDIS_SERVICE bbb-apps-akka bbb-fsesl-akka postgresql"

    if [ -f /usr/lib/systemd/system/bbb-graphql-actions.service ]; then
        units="$units bbb-graphql-actions"
    fi

    if [ -f /usr/lib/systemd/system/bbb-graphql-middleware.service ]; then
        units="$units bbb-graphql-middleware"
    fi

    if [ -f /usr/lib/systemd/system/bbb-graphql-server.service ]; then
        units="$units bbb-graphql-server"
    fi

    if [ -f /usr/lib/systemd/system/bbb-webrtc-sfu.service ]; then
        units="$units bbb-webrtc-sfu"
    fi

    if [ -f /usr/lib/systemd/system/bbb-webrtc-recorder.service ]; then
        units="$units bbb-webrtc-recorder"
    fi

    if [ -f /usr/share/etherpad-lite/settings.json ]; then
        units="$units etherpad"
    fi

    if [ -f /usr/lib/systemd/system/bbb-web.service ]; then
        units="$units bbb-web"
    fi

    if [ -f /usr/lib/systemd/system/bbb-webhooks.service ]; then
        units="$units bbb-webhooks"
    fi

    if [ -f /usr/lib/systemd/system/bbb-pads.service ]; then
        units="$units bbb-pads"
    fi

    if [ -f /usr/lib/systemd/system/bbb-export-annotations.service ]; then
        units="$units bbb-export-annotations"
    fi

    if [ -f /usr/lib/systemd/system/bbb-rap-caption-inbox.service ]; then
        units="$units bbb-rap-caption-inbox"
    fi

    if [ -f /usr/lib/systemd/system/bbb-rap-resque-worker.service ]; then
        units="$units bbb-rap-resque-worker"
    fi

    if [ -f /usr/lib/systemd/system/bbb-rap-starter.service ]; then
        units="$units bbb-rap-starter"
    fi

    if [ -f /usr/lib/systemd/system/bbb-transcription-controller.service ]; then
        units="$units bbb-transcription-controller"
    fi

    if [ -f /usr/lib/systemd/system/livekit-server.service ]; then
        units="$units livekit-server"
    fi

    if [ -f /usr/lib/systemd/system/bbb-shared-notes-server.service ]; then
        units="$units bbb-shared-notes-server"
    fi

    line='—————————————————————————————►'
    for unit in $units; do
        status=$(systemctl is-active "$unit")
        if [ "$status" = "active" ]; then
            printf "%s %s [✔ - $status]\n" $unit "${line:${#unit}}"
        else
            printf "%s %s [✘ - $status]\n" $unit "${line:${#unit}}"
        fi
    done
}

if [ $# -eq 0 ]; then
    usage
    exit 1
fi

# Parse the parameters
while [ $# -gt 0 ]; do
    if [ "$1" = "-stop" -o "$1" = "--stop" ]; then
        need_root
        stop_bigbluebutton
        exit 0
    fi

    if [ "$1" = "-start" -o "$1" = "--start" ]; then
        need_root
        start_bigbluebutton
        exit 0
    fi

    if [ "$1" = "-check" -o "$1" = "--check" -o "$1" = "-c" ]; then
        CHECK=1
        shift;shift
        continue
    fi

    if [ "$1" = "--version" -o "$1" = "-version" -o "$1" = "-v" ]; then
        VERSION=1
        shift
        continue
    fi

    if [ "$1" = "--debug" -o "$1" = "-debug" -o "$1" = "-d" ]; then
        DEBUG=1
        shift
        continue
    fi

    if [ "$1" = "--clean" -o "$1" = "-clean" ]; then
        CLEAN=1
        shift
        continue
    fi

    if [ "$1" = "--watch" -o "$1" = "-watch" -o "$1" = "-w" ]; then
        WATCH=1
        shift
        continue
    fi

    if [ "$1" = "--network" -o "$1" = "-network" -o "$1" = "-n" ]; then
        NETWORK=1
        shift
        continue
    fi

    if [ "$1" = "--zip" -o "$1" = "-zip" -o "$1" = "-z" ]; then
        ZIP=1
        shift
        continue
    fi

    if [ "$1" = "--status" -o "$1" = "-status" ]; then
        display_bigbluebutton_status
        exit 0
    fi

    if [ "$1" = "--restart" -o "$1" = "-restart" ]; then
        RESTART=1
        shift
        continue
    fi

    #
    # all other parameters requires at least 1 argument
    #

    if [ "$1" = "-setip" -o "$1" = "--setip" ]; then
        HOST="${2}"
        if [ -z "$HOST" ]; then
            echo "HOST IP=$IP"
        fi

        if echo $HOST|grep -q ":"; then
            HOST=$(echo ${2}|cut -d: -f1)
        fi
        shift; shift
        continue
    fi

    if [ "$1" = "--set-port-range" ]; then
        PORT_RANGE="${2}"
        shift; shift
        continue
    fi

    if [ "$1" = "--salt" -o "$1" = "-salt" -o "$1" = "--setsalt" -o "$1" = "--secret" -o "$1" = "-secret"  -o "$1" = "--setsecret" ]; then
        SECRET="${2}"
        if [ -z "$SECRET" ]; then
            BBB_WEB_URL=$(get_bbb_web_config_value bigbluebutton.web.serverURL)
            SECRET=$(get_bbb_web_config_value securitySalt)
            echo
            echo "    URL: $BBB_WEB_URL/bigbluebutton/"
            echo "    Secret: $SECRET"
            echo
            echo "    Link to the API-Mate:"
            echo "    https://mconf.github.io/api-mate/#server=$BBB_WEB_URL/bigbluebutton/&sharedSecret=$SECRET"
            echo
            exit 0
        fi
        shift; shift
        continue
    fi

    usage
    exit 1
done

print_bigbluebutton_version() {
    echo
    if [ $DISTRIB_ID == "centos" ]; then
        echo "BigBlueButton Server $BIGBLUEBUTTON_RELEASE ($(rpm -qa | grep bbb | grep -v bbb-redis | grep -v freeswitch | sed 's/.*[0-9].[0-9].[0-9]-//g' | sed 's/\..*//g' | awk '{ sum+=$1} END {print sum}'))"
    else
        echo "BigBlueButton Server $BIGBLUEBUTTON_RELEASE ($(dpkg -l | grep bbb | sed -n '/[0-9].[0-9].[0-9]-/{s/.*[0-9].[0-9].[0-9]-//;s/;//;p}' | awk '{ sum+=$1} END {print sum}'))"
    fi
}


#
# Version
#
if [[ $VERSION ]]; then
    print_bigbluebutton_version
    echo
    dpkg -l | grep bbb
    exit 0
fi


#
# Set Shared Secret
#

if [[ $SECRET ]]; then
    need_root

    echo "Assigning secret in $BBB_WEB_ETC_CONFIG"
    if [ -f "$BBB_WEB_ETC_CONFIG" ] && grep "^securitySalt" "$BBB_WEB_ETC_CONFIG" > /dev/null ; then
        change_var_value "$BBB_WEB_ETC_CONFIG" securitySalt "$SECRET"
    else
        echo "securitySalt=$SECRET" >> "$BBB_WEB_ETC_CONFIG"
    fi

    if [ -f /usr/local/bigbluebutton/bbb-webhooks/config/default.yml ]; then
        change_yml_value /usr/local/bigbluebutton/bbb-webhooks/config/default.yml sharedSecret $SECRET
    fi

    if [ -f /usr/local/bigbluebutton/bbb-webhooks/extra/post_catcher.js ]; then
        sed -i "s|\(^[ \t]*var shared_secret[ =]*\)[^;]*|\1\"$SECRET\"|g" /usr/local/bigbluebutton/bbb-webhooks/extra/post_catcher.js
    fi

    if [ -f /etc/bigbluebutton/bbb-apps-akka.conf ]; then
        sed -i "s/sharedSecret[ ]*=[ ]*\"[^\"]*\"/sharedSecret=\"$SECRET\"/g" /etc/bigbluebutton/bbb-apps-akka.conf
    fi

    echo
    echo "BigBlueButton's shared secret is now $SECRET"
    echo
    echo "You must restart BigBlueButton for the changes to take effect"
    echo
    echo "  $SUDO bbb-conf --restart"
    echo
    echo
fi

#
# Set Port Range
#

if [[ $PORT_RANGE ]]; then
    if [[ "$PORT_RANGE" =~ ^([[:digit:]]+)-([[:digit:]]+)$ ]]; then
        START_PORT=${BASH_REMATCH[1]}
        END_PORT=${BASH_REMATCH[2]}

        need_root

        xmlstarlet edit --inplace --update '/configuration/settings/param[@name="rtp-start-port"]/@value' --value $START_PORT $FREESWITCH_SWITCH_CONF
        xmlstarlet edit --inplace --update '/configuration/settings/param[@name="rtp-end-port"]/@value' --value $END_PORT $FREESWITCH_SWITCH_CONF

        if [ ! -f $WEBRTC_SFU_ETC_CONFIG ]; then
            touch $WEBRTC_SFU_ETC_CONFIG
        fi
        yq e -i ".mediasoup.worker.rtcMinPort = \"$START_PORT\"" $WEBRTC_SFU_ETC_CONFIG
        yq e -i ".mediasoup.worker.rtcMaxPort = \"$END_PORT\"" $WEBRTC_SFU_ETC_CONFIG

        yq e -i ".webrtc.rtcMinPort = \"$START_PORT\"" $WEBRTC_RECORDER_DEFAULT_CONFIG
        yq e -i ".webrtc.rtcMaxPort = \"$END_PORT\"" $WEBRTC_RECORDER_DEFAULT_CONFIG

        if [ -f $LIVEKIT_SERVER_ETC_CONFIG ]; then
            yq e -i ".rtc.port_range_start = \"$START_PORT\"" $LIVEKIT_SERVER_ETC_CONFIG
            yq e -i ".rtc.port_range_end = \"$END_PORT\"" $LIVEKIT_SERVER_ETC_CONFIG
        fi

        echo
        echo "BigBlueButton's UDP port range is now $START_PORT-$END_PORT"
        echo
        echo "You must restart BigBlueButton for the changes to take effect"
        echo
        echo "  $SUDO bbb-conf --restart"
        echo
        echo
    else
        echo
        echo "Warning: --set-port-range requires a numerical port range (default is 16384-32768)"
        echo
        echo "Port range remains unchanged"
        echo
    fi
fi

check_configuration() {
    #
    # Check that freeswtich ESL matches the value in bigbluebutton.properties
    #
    if [ -f $FREESWITCH_EVENT_SOCKET ]; then
        FREESWITCH_ESL_IP=$(cat $FREESWITCH_EVENT_SOCKET | grep 'name="listen-ip"' | cut -d\" -f4  | awk '{print $1}')
        check_no_value event_socket $FREESWITCH_EVENT_SOCKET $FREESWITCH_ESL_IP
    fi

    #
    # Check if BigBlueButton is defined in Nginx
    #
    if [ ! -L /etc/nginx/sites-enabled/bigbluebutton ]; then
        echo "# Nginx: BigBlueButton appears to be disabled"
        echo "         - no symbolic link in /etc/nginx/sites-enabled/bigbluebutton to /etc/nginx/sites-available/bigbluebutton "
    fi

    #
    # Look for properties with no values set
    #
    CONFIG_FILES="$SERVLET_DIR/WEB-INF/classes/bigbluebutton.properties"
    ignore_configs_args=()
    ignore_configs_args+=(-e "redis.pass")
    ignore_configs_args+=(-e "redisPassword")
    ignore_configs_args+=(-e "disabledFeatures")
    ignore_configs_args+=(-e "pluginManifests")
    ignore_configs_args+=(-e "fetchUrlBlockedExternalHosts")
    ignore_configs_args+=(-e "fetchUrlAllowedLocalHosts")

    for file in $CONFIG_FILES ; do
        if [ ! -f $file ]; then
            echo "# Error: File not found: $file"
        else
            if cat $file | grep -v "${ignore_configs_args[@]}"  | grep -v ^# | grep -q "^[^=]*=[ ]*$"; then
                echo "# The following properties in $file have no value:"
                echo "#     $(grep '^[^=#]*=[ ]*$' $file | grep -v "${ignore_configs_args[@]}" | sed 's/=//g')"
            fi
        fi
    done

    VARFolder="$(get_bbb_web_config_value imageMagickDir)"
    if [ ! -x $VARFolder/convert ]; then
        echo "# ImageMagick's convert is not installed in $VARFolder"
    fi

    #
    # Check if the IP resolves to a different host
    #
    check_no_value server_name /etc/nginx/sites-available/bigbluebutton $NGINX_IP

    if which host > /dev/null 2>&1; then
        HOSTS=$(which host)
        if [ $HOSTS ]; then
            HOSTS=$($HOSTS $NGINX_IP | awk '{ print $4 }' | head -n 1)
        fi
    fi


    BBB_SECRET="$(get_bbb_web_config_value securitySalt)"


    if [ -f /usr/lib/systemd/system/bbb-webhooks.service ]; then
        WEBHOOKS_CONF=/usr/local/bigbluebutton/bbb-webhooks/config/default.yml
        WEBHOOKS_SECRET=$(yq e '.bbb.sharedSecret' $WEBHOOKS_CONF)

        if [ "$BBB_SECRET" != "$WEBHOOKS_SECRET" ]; then
            echo "# Warning: Webhooks API Shared Secret mismatch: "
            echo "#  ${SERVLET_DIR}/WEB-INF/classes/bigbluebutton.properties = $BBB_SECRET"
            echo "#  $WEBHOOKS_CONF                       = $WEBHOOKS_SECRET"
            echo
        fi

        WEBHOOKS_PROXY_PORT=$(cat /usr/share/bigbluebutton/nginx/webhooks.nginx | grep -v '#' | grep '^[ \t]*proxy_pass[ \t]*' | sed 's|.*http[s]\?://[^:]*:\([^;]*\);.*|\1|g')
        WEBHOOKS_APP_PORT=$(yq e '.modules."../out/webhooks/index.js".config.api.port' $WEBHOOKS_CONF)

        if [ "$WEBHOOKS_PROXY_PORT" != "$WEBHOOKS_APP_PORT" ]; then
            echo "# Warning: Webhooks port mismatch: "
            echo "#  /usr/share/bigbluebutton/nginx/webhooks.nginx                   = $WEBHOOKS_PROXY_PORT"
            echo "#  $WEBHOOKS_CONF = $WEBHOOKS_APP_PORT"
            echo
        fi
    fi

    SIP_PROTOCOL=$(cat "$SIP_CONFIG" | grep -v \# | sed -n '/proxy_pass/{s/.*proxy_pass [ ]*//;s/:.*//;p}' | head -n 1)
    if [[ $SIP_PROTOCOL == "https" ]]; then
        if ! grep wss-binding $FREESWITCH_EXTERNAL > /dev/null; then
            echo "# Warning: Websockets is using HTTPS in $SIP_CONFIG"
            echo "# but no definition for wss-binding found in "
            echo "#"
            echo "#    $FREESWITCH_EXTERNAL"
            echo
        fi
    fi

    if [ "$(ls -ld /var/freeswitch/meetings | cut -d' ' -f3)" != "freeswitch" ]; then
        echo "# Warning: Detected the directory"
        echo "#    /var/freeswitch/meetings"
        echo "# is not owned by freeswitch"
    fi

    if [ "$(ls -ld /var/bigbluebutton | cut -d' ' -f3)" != $BBB_USER ]; then
        echo "# Warning: Detected the directory"
        echo "#    /var/bigbluebutton"
        echo "# is not owned by $BBB_USER"
    fi

    CHECK_STUN=$(xmlstarlet sel -t -m '//X-PRE-PROCESS[@cmd="set" and starts-with(@data, "external_rtp_ip=")]' -v @data $FREESWITCH_VARS | sed 's/external_rtp_ip=stun://g')
    if [ "$CHECK_STUN" == "stun.freeswitch.org" ]; then
       echo
       echo "# Warning: Detected FreeSWITCH is using default stun.freeswitch.org server.  See"
       echo "#"
       echo "#     https://docs.bigbluebutton.org/support/troubleshooting#freeswitch-using-default-stun-server"
       echo "#"
       echo
    fi

    if ! which ufw > /dev/null 2>&1; then
       echo
       echo "# Warning: No firewall detected.  Recommend using setting up a firewall for your server"
       echo "#"
       echo "#     https://docs.bigbluebutton.org/administration/firewall-configuration"
       echo "#"
       echo
    fi

    #
    # Check for retired bbb-web properties that should no longer be used
    #
    RETIRED_FOUND=0
    for prop in "${RETIRED_BBB_WEB_PROPERTIES[@]}"; do
        if grep -q "^${prop}[[:space:]]*=" "$BBB_WEB_ETC_CONFIG" 2>/dev/null; then
            if [ $RETIRED_FOUND -eq 0 ]; then
                echo
                echo "# Warning: The following retired bbb-web properties were found in $BBB_WEB_ETC_CONFIG and should be removed:"
                RETIRED_FOUND=1
            fi
            echo "#   $prop"
        fi
    done
    if [ $RETIRED_FOUND -eq 1 ]; then
        echo
    fi

}

check_state() {
    echo
    print_header
    check_configuration

    #
    # Check for potential problems in the BigBlueButton configuration
    #

    RUNNING_APPS=""
    NOT_RUNNING_APPS=""

    if [[ -a $FREESWITCH_PID ]]; then
        if ! ps aux | grep -v grep | grep '[/]opt/freeswitch/bin/freeswitch' > /dev/null; then
            print_header
            NOT_RUNNING_APPS="${NOT_RUNNING_APPS} freeswitch"
        else
            RUNNING_APPS="${RUNNING_APPS} freeswitch"
        fi
    fi

    if ! ps aux | grep -v grep | grep '[/]usr/sbin/nginx' > /dev/null; then
        print_header
        NOT_RUNNING_APPS="${NOT_RUNNING_APPS} Nginx"
    else
        RUNNING_APPS="${RUNNING_APPS} Nginx"
    fi

    if ! ps aux | grep -v grep | grep '[/]usr/[s]*bin/redis-server' > /dev/null; then
        print_header
        NOT_RUNNING_APPS="${NOT_RUNNING_APPS} redis-server"
    else
        RUNNING_APPS="${RUNNING_APPS} redis-server"
    fi

    if [ "$NOT_RUNNING_APPS" != "" ]; then
        echo "# Not running: ${NOT_RUNNING_APPS}"
    fi


    #
    # Check if running development environment
    #
    if ! grep 8090 /usr/share/bigbluebutton/nginx/web.nginx > /dev/null; then
        echo "# Warning: nginx is not serving BigBlueButton's web application"
        echo "# from port 8090"
        echo "#"
        echo "# (This is OK if you have setup a development environment.) "
        echo
    fi


    #
    # Check FreeSWITCH
    #
    if grep -q "Thread ended for mod_event_socket" /opt/freeswitch/var/log/freeswitch/freeswitch.log; then
        echo
        echo "# Error: Found text in freeswitch.log:"
        echo "#"
        echo "#    Thread ended for mod_event_socket"
        echo "#"
        echo "# FreeSWITCH may not be responding to requests on port 8021 (event socket layer)"
        echo "# and users may have errors joining audio."
        echo "#"
    fi

    #
    # Check FreeSWITCH
    #

    ESL_PASSWORD=$(xmlstarlet sel -t -m 'configuration/settings/param[@name="password"]' -v @value /opt/freeswitch/etc/freeswitch/autoload_configs/event_socket.conf.xml)
    if ! echo "/quit" | timeout -v 5 /opt/freeswitch/bin/fs_cli -p $ESL_PASSWORD - > /dev/null 2>&1; then
        echo
        echo "#"
        echo "# Error: Unable to connect to the FreeSWITCH Event Socket Layer on port 8021"
        echo "#"
    fi

    #
    # Check for required external commands
    #
    COMMANDS="ruby gem pdftocairo"
    for cmd in $COMMANDS ; do
        if ! which $cmd > /dev/null 2>&1; then
            echo "#    $cmd command not found"
        fi
    done

    #
    # Check if ffmpeg is installed, and whether it is a supported version
    #
    FFMPEG_VERSION=$(ffmpeg -version 2>/dev/null | grep ffmpeg | cut -d ' ' -f3 | sed 's/--.*//g' | tr -d '\n')
    case "$FFMPEG_VERSION" in
        4.*.*)
            # This is the current supported version; OK.
            ;;
        '')
            echo "# Warning: No ffmpeg version was found on the system"
            echo "#          Recording processing will not function"
            echo
            ;;
        *)
            echo "# Warning: The installed ffmpeg version '${FFMPEG_VERSION}' is not recommended."
            echo "# Recommend you update to the 4.0.x version of ffmpeg.  To upgrade, do the following"
            echo "#"
            echo "#       $SUDO apt-get install software-properties-common"
            echo "#       $SUDO add-apt-repository ppa:jonathonf/ffmpeg-4"
            echo "#       $SUDO apt-get update"
            echo "#       $SUDO apt-get dist-upgrade"
            echo "#"
            echo
            ;;
    esac

    #
    # Check if the user is running their own bbb-web
    #
    if grep -q 8888 /usr/share/bigbluebutton/nginx/web.nginx; then
        if ! ss -ant | grep '8888' > /dev/null; then
            echo "# Warning: There is no application server listening to port 8888."
            echo
        fi
    fi


    #
    # Check if the local server can access the API.  This is a common problem when setting up BigBlueButton behind
    # a firewall
    #
    BBB_WEB="$(get_bbb_web_config_value bigbluebutton.web.serverURL|sed -n '{s/.*\///;p}')"
    check_no_value server_name /etc/nginx/sites-available/bigbluebutton $BBB_WEB

    COUNT=0
    while [ $COUNT -lt 80 ]; do
        let COUNT=COUNT+1
        timeout 1s curl -sS $PROTOCOL://$BBB_WEB/bigbluebutton/api | grep -q SUCCESS
        if [ $? -eq 0 ]; then
            let COUNT=80
        else
            echo -n "."
            sleep 1
        fi
    done
    echo

    if ! curl -sS $PROTOCOL://$BBB_WEB/bigbluebutton/api | grep -q SUCCESS; then
        echo "# Error: Could not connect to the configured hostname/IP address"
        echo "#"
        echo "#    $PROTOCOL://$BBB_WEB/"
        echo "#"
        echo "# If your BigBlueButton server is behind a firewall, see FAQ."
        echo
    fi

    VARS_IP=$(cat $FREESWITCH_VARS | sed -n '/"local_ip_v4/{s/.*local_ip_v4=//;s/".*//;p}')
    if [[ "$VARS_IP" != "127.0.0.1" ]] && [[ "$VARS_IP" != "auto" ]]; then
        if [ "$VARS_IP" != $IP ]; then
            echo "# Warning: The setting of $VARS_IP for local_ip_v4 in"
            echo "#"
            echo "#    $FREESWITCH_VARS"
            echo "#"
            echo "# does not match the local IP address ($IP)."
            echo "# (This is OK if you've manually changed the values)"
            echo
        fi
    fi

    if (( $MEM < 3940 )); then
        echo "# Warning: You are running BigBlueButton on a server with less than 4G of memory.  Your"
        echo "# performance may suffer."
        echo
    fi

    BBB_WEB="$(get_bbb_web_config_value bigbluebutton.web.serverURL)"

    DEFAULT_PDF="$(get_bbb_web_config_value beans.presentationService.defaultUploadedPresentation)"
    if echo $DEFAULT_PDF | grep -q "bigbluebutton.web.serverURL"; then
        if ! echo "$BBB_WEB$(echo $DEFAULT_PDF | sed 's/${bigbluebutton.web.serverURL}//g')" | xargs curl -sS >/dev/null; then
            echo "# Error: Unable to reach default URL for presentation:"
            echo "#"
            echo "#    $BBB_WEB$(echo $DEFAULT_PDF | sed 's/${bigbluebutton.web.serverURL}//g')"
            echo "#"
            echo "# Check value for beans.presentationService.defaultUploadedPresentation in"
            echo "#   $BBB_WEB_CONFIG and $BBB_WEB_ETC_CONFIG"
        fi
    else
        if ! echo "$DEFAULT_PDF" | xargs curl -sS >/dev/null; then
            echo "# Error: Unable to reach default URL for presentation"
            echo "#"
            echo "#    $DEFAULT_PDF"
            echo "#"
            echo "# Check value for beans.presentationService.defaultUploadedPresentation in"
            echo "#   $BBB_WEB_CONFIG and $BBB_WEB_ETC_CONFIG"
        fi
    fi

    if [ "$(cat /etc/bigbluebutton/bbb-apps-akka.conf | sed -n '/sharedSecret.*/{s/[^"]*"//;s/".*//;p}')" == "changeme" ]; then
        BBB_WEB_IP="$(get_bbb_web_config_value bigbluebutton.web.serverURL|sed -n '{s/.*\///;p}')"
        echo "# Error: Detected that /etc/bigbluebutton/bbb-apps-akka.conf has the default"
        echo "# configuration values.  To update, run"
        echo "#"
        echo "#   $SUDO bbb-conf --setip $BBB_WEB_IP"
        echo "#"
    fi

    if bbb-conf --status | grep -q inactive; then
        if bbb-conf --status | grep inactive; then
            echo "# Error: Detected some processes have not started correctly"
            echo "#"
            echo "#   $(bbb-conf --status | grep inactive)"
            echo "#"
        fi
    fi

    if systemctl status freeswitch | grep -q SETSCHEDULER; then
        echo "# Error: FreeSWITCH failed to start with SETSCHEDULER error, see"
        echo "#"
        echo "#   https://docs.bigbluebutton.org/support/troubleshooting#freeswitch-fails-to-start-with-a-setscheduler-error"
        echo "#"
    fi

    NCPU=$(nproc --all)
    if [ "$NCPU" -lt "4" ]; then
        echo "# Warning: found only $NCPU cores, whereas this server should have (at least) 4 CPU cores"
        echo "# to run BigBlueButton in production."
        echo "#"
        echo "#   https://docs.bigbluebutton.org/administration/install#minimum-server-requirements"
        echo "#"
    fi

    if [ $(echo "$HTML5_CONFIG" | yq e '.public.media.sipjsHackViaWs' -) != "true" ]; then
      if [ "$PROTOCOL" == "https" ]; then
        if ! cat $SIP_CONFIG |  grep -v '#' | grep proxy_pass | head -n 1 | grep -q https; then
          echo "# Warning: You have this server defined for https, but in"
          echo "#"
          echo "#   $SIP_CONFIG"
          echo "#"
          echo "#  did not find the use of https in definition for proxy_pass"
          echo "#"
          echo "#    $(cat $SIP_CONFIG |  grep -v '#' | grep proxy_pass | head -n 1)"
          echo "#"
        fi

      if [ "$SIP_NGINX_IP" != $IP ]; then
        if [ "$SIP_NGINX_IP" != "\$freeswitch_addr" ]; then
          echo "# Warning: The setting of $SIP_NGINX_IP for proxy_pass in"
          echo "#"
          echo "#    $SIP_CONFIG"
          echo "#"
          echo "# does not match the local IP address ($IP)."
          echo "# (This is OK if you've manually changed the values)"
          echo
        fi
      fi

        if ! cat $SIP_CONFIG |  grep -v '#' | grep proxy_pass | head -n 1 | grep -q 7443; then
          echo
          echo "# Warning: You have this server defined for https, but in"
          echo "#"
          echo "#   $SIP_CONFIG"
          echo "#"
          echo "#  did not find the use of port 7443 in definition for proxy_pass"
          echo "#"
          echo "#    $(cat $SIP_CONFIG |  grep -v '#' | grep proxy_pass | head -n 1)"
          echo "#"
        fi
      fi
    fi

    CHECK="$(get_bbb_web_config_value securitySalt|sha1sum |cut -d' ' -f1)"
    if [ "$CHECK" == "55b727b294158a877212570c3c0524c2b902a62c" ]; then
      echo
      echo "#"
      echo "# Warning: Detected you have the default shared secret.  You MUST change your shared"
      echo "# secret NOW for BigBlueButton to finish starting up. Do either"
      echo "#"
      echo "#   sudo bbb-conf --setsecret <secret>"
      echo "#"
      echo "# or, to have openssl generate a strong secret for you (recommended)"
      echo "#"
      echo "#   sudo bbb-conf --setsecret \$(openssl rand -base64 32 | sed 's/=//g' | sed 's/+//g' | sed 's/\///g')"
      echo "#"
      echo "# Be sure to update any integrations with the new shared secret."
      echo "#"
      systemctl stop bbb-web
      exit 1
    fi

    if ! systemctl show-environment | grep LANG= | grep -q UTF-8; then
      echo
      echo "#"
      echo "# Warning: Detected that systemctl does not define a UTF-8 language."
      echo "#"
      echo "# To temporarily correct, run the command "
      echo "#"
      echo "#   sudo systemctl set-environment LANG=en_US.UTF-8"
      echo "#"
      echo "# See https://docs.bigbluebutton.org/administration/install#pre-installation-checks"
      echo "#"
    fi

    if [ "$(stat -c "%U %G" /var/bigbluebutton)" != "bigbluebutton bigbluebutton" ]; then
      echo
      echo "#"
      echo "# Warning: The directory"
      echo "#"
      echo "#  /var/bigbluebutton"
      echo "#"
      echo "# is not owned by bigbluebutton:bigbluebutton.  To fix, run the command"
      echo "#"
      echo "#   sudo chown -R bigbluebutton:bigbluebutton /var/bigbluebutton"
      echo "#"
    fi

    FREESWITCH_SIP=$(ss -anlt4 | grep :5066 | grep -v tcp6 | grep LISTEN | sed 's/ [ ]*/ /g' | cut -d' ' -f4 | sed 's/:5066//g')
    WEBRTC_SFU_SIP_IP=$(echo "$WEBRTC_SFU_CONFIG" | yq e '.freeswitch.sip_ip' -)

    if [ ! -z "$FREESWITCH_SIP" ]; then
      if [ "$FREESWITCH_SIP" != "$WEBRTC_SFU_SIP_IP" ]; then
        echo
        echo "#"
        echo "# bbb-webrtc-sfu will try to connect to $WEBRTC_SFU_SIP_IP but FreeSWITCH is listening on $FREESWITCH_SIP for port 5066"
        echo "#"
        echo "# To fix, run the commands"
        echo "#"
        echo "# sudo yq e -i 'freeswitch.sip_ip' = $FREESWITCH_SIP /etc/bigbluebutton/bbb-webrtc-sfu/production.yml"
        echo "# sudo chown bigbluebutton:bigbluebutton /etc/bigbluebutton/bbb-webrtc-sfu/production.yml"
        echo "#"
      fi
    fi

    if [ ! -z "$STUN" ]; then
      for i in $STUN; do
        STUN_SERVER="$(xmlstarlet sel -N x="http://www.springframework.org/schema/beans" -t -m "_:beans/_:bean[@id=\"$i\"]/_:constructor-arg[@index=\"0\"]" -v @value $TURN | sed 's/stun://g')"

	# stun is from the stun-client package, which is available on both bionic and focal
	# stunclient is from the stuntman-client package, which is available on bionic but was removed from focal
	if which stun > /dev/null 2>&1 && ! which turnutils_stunclient > /dev/null 2>&1; then
	  # stun return codes, from its client.cxx
	  # low nibble: open (0), various STUN combinations (2-9), firewall (a), blocked (c), unknown (e), error (f)
	  # high nibble: hairpin (1)
	  stun $STUN_SERVER > /dev/null
          if (( ($? & 0xf) > 9 )); then
            echo
            echo "#"
            echo "# Warning: Failed to verify STUN server at $STUN_SERVER with command"
            echo "#"
            echo "#    stun $STUN_SERVER"
            echo "#"
          fi
        elif which stunclient > /dev/null 2>&1 && ! which turnutils_stunclient > /dev/null 2>&1; then
          if echo $STUN_SERVER | grep -q ':'; then
            STUN_SERVER="$(echo $STUN_SERVER | sed 's/:.*//g') $(echo $STUN_SERVER | sed 's/.*://g')"
          else
            STUN_SERVER="$STUN_SERVER 3478"
          fi
          if stunclient $STUN_SERVER | grep -q "fail\|Unable\ to\ resolve"; then
            echo
            echo "#"
            echo "# Warning: Failed to verify STUN server at $STUN_SERVER with command"
            echo "#"
            echo "#    stunclient $STUN_SERVER"
            echo "#"
          fi
        elif which turnutils_stunclient > /dev/null 2>&1; then
          # turnutils_stunclient comes from the coturn package, stun-client package uses old stun version which doesn't work with out-of-the-box security settings from coturn
          # (no-rfc5780, no-stun-backward-compatibility, response-origin-only-with-rfc5780)
          turnutils_stunclient $STUN_SERVER > /dev/null 2>&1
          if [ $? -ne 0 ]; then
            echo
            echo "#"
            echo "# Warning: Failed to verify STUN server at $STUN_SERVER with command"
            echo "#"
            echo "#    turnutils_stunclient $STUN_SERVER"
            echo "#"
          fi
        fi
      done
    fi

    BBB_LOG="/var/log/bigbluebutton"
    if [ "$(stat -c "%U %G" $BBB_LOG)" != "bigbluebutton bigbluebutton" ]; then
      echo
      echo "#"
      echo "# Warning: The directory"
      echo "#"
      echo "#  $BBB_LOG"
      echo "#"
      echo "# is not owned by bigbluebutton:bigbluebutton.  To fix, run the command"
      echo "#"
      echo "#   sudo chown bigbluebutton:bigbluebutton $BBB_LOG"
      echo "#"
    fi

    BBB_LOG_FILES="$BBB_LOG/bbb-rap-worker.log $BBB_LOG/bbb-web.log $BBB_LOG/post_publish.log  $BBB_LOG/sanity.log"
    for log_file in $BBB_LOG_FILES; do
      if [ -f "$log_file" ] && [ "$(stat -c "%U %G" $log_file)" != "bigbluebutton bigbluebutton" ]; then
        echo
        echo "#"
        echo "# Warning: The file"
        echo "#"
        echo "#  $log_file"
        echo "#"
        echo "# is not owned by bigbluebutton:bigbluebutton.  To fix, run the command"
        echo "#"
        echo "#   sudo chown bigbluebutton:bigbluebutton $log_file"
        echo "#"
      fi
    done

    if [ -d /var/lib/gems/2.5.0/cache ]; then
      for gem_file in /var/lib/gems/2.5.0/cache/*; do
        if [ ! -s $gem_file ]; then
          echo "#"
          echo "# Warning: Found a zero byte size gem file"
          echo "#"
          echo "#  $gem_file"
          echo "#"
        fi
      done
    fi

		if journalctl -u bbb-rap-* | grep -q 'Nil'; then
			echo
			echo "#"
			echo "# Warning: found 'Nil' message in recording processing logs.  Possible GEM errors"
			echo "#"
			echo "#  https://github.com/bigbluebutton/bigbluebutton/issues/14287"
			echo "#"
		fi

    # check for any maintainer configuration files being ignored
    dpkg_dist_files=$(find /etc/default -type f -name "*.dpkg-dist")
    if [ -n "$dpkg_dist_files" ]; then
      echo "# Warning: found the following configuration files which were ignored when installing."
      echo "# Please inspect those files and consider applying the differences to the similarly"
      echo "# named configuration file in the same directory."
      echo "# When done, please restart BigBlueButton."
      echo "#"
      echo "$dpkg_dist_files"
    fi

    exit 0
}


#
# Print out the status of the current setup and look for configuration issues
#
if [ $CHECK ]; then
    need_root

    print_bigbluebutton_version

    echo "                    Kernel version:" $(uname -r)

    if [ $DISTRIB_ID == "centos" ]; then
        echo -n "                      Distribution: $(cat /etc/centos-release)"
    else
        source /etc/lsb-release
        echo -n "                      Distribution: $DISTRIB_DESCRIPTION "
    fi

    if [ $(uname -m) == "x86_64" ]; then
        echo "(64-bit)"
    elif [ $(uname -m) == "i686" ]; then
        echo "(32-bit)"
    fi

    echo "                            Memory: $MEM MB"
    echo "                         CPU cores: $NCPU"

    echo
    echo "$BBB_WEB_ETC_CONFIG (override for bbb-web)"
    echo "$BBB_WEB_CONFIG (bbb-web)"
    echo "       bigbluebutton.web.serverURL: $(get_bbb_web_config_value bigbluebutton.web.serverURL)"
    echo "                defaultGuestPolicy: $(get_bbb_web_config_value defaultGuestPolicy)"
    echo "              defaultMeetingLayout: $(get_bbb_web_config_value defaultMeetingLayout)"

    echo
    echo "/etc/nginx/sites-available/bigbluebutton (nginx)"
    echo "                       server_name: $NGINX_IP"

    PORT=$(cat /etc/nginx/sites-available/bigbluebutton | grep -v '#' | sed -n '/listen/{s/.*listen[ ]*//;s/;//;p}' | grep -v ssl | tr --delete '\n' | sed 's/\[/, \[/g' | sed 's/0$/0\n/g')
    echo "                              port: $PORT"
    if cat /etc/nginx/sites-available/bigbluebutton | grep -v '#' | sed -n '/listen/{s/.*listen[ ]*//;s/;//;p}' | grep ssl > /dev/null; then
        echo "                              port: 443 ssl"
    fi

    echo
    echo "$FREESWITCH_VARS (FreeSWITCH)"
    echo "                       local_ip_v4: $(xmlstarlet sel -t -m '//X-PRE-PROCESS[@cmd="set" and starts-with(@data, "local_ip_v4=")]' -v @data $FREESWITCH_VARS | sed 's/local_ip_v4=//g')"
    echo "                   external_rtp_ip: $(xmlstarlet sel -t -m '//X-PRE-PROCESS[@cmd="set" and starts-with(@data, "external_rtp_ip=")]' -v @data $FREESWITCH_VARS | sed 's/external_rtp_ip=//g')"
    echo "                   external_sip_ip: $(xmlstarlet sel -t -m '//X-PRE-PROCESS[@cmd="set" and starts-with(@data, "external_sip_ip=")]' -v @data $FREESWITCH_VARS | sed 's/external_sip_ip=//g')"

    echo
    echo "$FREESWITCH_EXTERNAL (FreeSWITCH)"
    echo "                        ext-rtp-ip: $(xmlstarlet sel -t -m 'profile/settings/param[@name="ext-rtp-ip"]' -v @value $FREESWITCH_EXTERNAL)"
    echo "                        ext-sip-ip: $(xmlstarlet sel -t -m 'profile/settings/param[@name="ext-sip-ip"]' -v @value $FREESWITCH_EXTERNAL)"
    echo "                        ws-binding: $(xmlstarlet sel -t -m 'profile/settings/param[@name="ws-binding"]' -v @value $FREESWITCH_EXTERNAL)"
    echo "                       wss-binding: $(xmlstarlet sel -t -m 'profile/settings/param[@name="wss-binding"]' -v @value $FREESWITCH_EXTERNAL)"

    # awk script from https://stackoverflow.com/a/14527886/1493790
    # open issue: a tool like crudini (https://stackoverflow.com/a/25513632/1493790)
    #     would be better for parsing ini files

    echo
    echo "UDP port ranges"
    echo
    echo "                        FreeSWITCH: $(xmlstarlet sel -t -m './configuration/settings/param[@name="rtp-start-port"]' -v @value $FREESWITCH_SWITCH_CONF)-$(xmlstarlet sel -t -m './configuration/settings/param[@name="rtp-end-port"]' -v @value $FREESWITCH_SWITCH_CONF)"

    echo "                    bbb-webrtc-sfu: $(echo "$WEBRTC_SFU_CONFIG" | yq e '.mediasoup.worker.rtcMinPort' -)-$(echo "$WEBRTC_SFU_CONFIG" |yq e '.mediasoup.worker.rtcMaxPort' -)"
    echo "                    bbb-webrtc-recorder: $(echo "$WEBRTC_RECORDER_CONFIG" | yq e '.webrtc.rtcMinPort' -)-$(echo "$WEBRTC_RECORDER_CONFIG" | yq e '.webrtc.rtcMaxPort' -)"
    if [ -n "$LIVEKIT_SERVER_CONFIG" ]; then
        echo "                    livekit.rtc.port_range_start: $(echo "$LIVEKIT_SERVER_CONFIG" | yq e '.rtc.port_range_start' -)"
        echo "                    livekit.rtc.port_range_end: $(echo "$LIVEKIT_SERVER_CONFIG" | yq e '.rtc.port_range_end' -)"
    fi

    if [ -f $RECORD_CONFIG ]; then
        echo
        echo "$RECORD_CONFIG (record and playback)"
        echo "                     playback_host: $(yq e '.playback_host' $RECORD_CONFIG)"
        echo "                 playback_protocol: $(yq e '.playback_protocol' $RECORD_CONFIG)"
        echo "                            ffmpeg: $(ffmpeg -version 2>/dev/null | grep ffmpeg | cut -d ' ' -f3 | sed 's/--.*//g' | tr -d '\n')"
    fi

    if [ -f $SIP_CONFIG ]; then
        echo
        echo "$SIP_CONFIG (sip.nginx)"
        echo "                        proxy_pass: $SIP_NGINX_IP"
        echo "                          protocol: $(cat "$SIP_CONFIG" | grep -v \# | sed -n '/proxy_pass/{s/.*proxy_pass [ ]*//;s/:.*//;p}' | head -n 1)"
    fi

    if [ -n "$WEBRTC_SFU_CONFIG" ]; then
        MEDIASOUP_WEBRTC_IPS=$(echo "$WEBRTC_SFU_CONFIG" | yq e '.mediasoup.webrtc.listenIps.[] | .announcedIp' -)
        MEDIASOUP_PLAINRTP_IPS=$(echo "$WEBRTC_SFU_CONFIG" | yq e '.mediasoup.plainRtp.listenIp | .announcedIp' -)
        echo
        echo "/usr/local/bigbluebutton/bbb-webrtc-sfu/config/default.yml (bbb-webrtc-sfu)"
        echo "/etc/bigbluebutton/bbb-webrtc-sfu/production.yml (bbb-webrtc-sfu - override)"
        echo "    mediasoup.webrtc.*.announcedIp: $(echo "$MEDIASOUP_WEBRTC_IPS" | awk -v ORS=", " '{ print $1 }' | sed 's/, $//')"
        echo "  mediasoup.plainRtp.*.announcedIp: $(echo "$MEDIASOUP_PLAINRTP_IPS" | awk -v ORS=", " '{ print $1 }' | sed 's/, $//')"
        echo "                 freeswitch.sip_ip: $(echo "$WEBRTC_SFU_CONFIG" | yq e '.freeswitch.sip_ip' -)"
        echo "                  recordingAdapter: $(echo "$WEBRTC_SFU_CONFIG" | yq e '.recordingAdapter' -)"
        echo "               recordScreenSharing: $(echo "$WEBRTC_SFU_CONFIG" | yq e '.recordScreenSharing' -)"
        echo "                     recordWebcams: $(echo "$WEBRTC_SFU_CONFIG" | yq e '.recordWebcams' -)"
        echo "                  codec_video_main: $(echo "$WEBRTC_SFU_CONFIG" | yq e '.conference-media-specs.codec_video_main' -)"
        echo "               codec_video_content: $(echo "$WEBRTC_SFU_CONFIG" | yq e '.conference-media-specs.codec_video_content' -)"

    fi

    if [ -n "$WEBRTC_RECORDER_CONFIG" ]; then
        echo
        echo "/etc/bbb-webrtc-recorder/bbb-webrtc-recorder.yml (bbb-webrtc-recorder)"
        echo "/etc/bigbluebutton/bbb-webrtc-recorder.yml (bbb-webrtc-recorder - override)"
        echo "               debug: $(echo "$WEBRTC_RECORDER_CONFIG" | yq e '.debug' -)"
        echo "               recorder.directory: $(echo "$WEBRTC_RECORDER_CONFIG" | yq e '.recorder.directory' -)"
    fi

    if [ -n "$LIVEKIT_SERVER_CONFIG" ]; then
        LIVEKIT_ENABLED_CODECS=$(echo "$LIVEKIT_SERVER_CONFIG" | yq e '.room.enabled_codecs.[] | .mime' -)
        echo
        echo "/etc/bigbluebutton/livekit-server.yml (livekit-server)"
        echo "               log_level: $(echo "$LIVEKIT_SERVER_CONFIG" | yq e '.log_level' -)"
        echo "               port_range_start: $(echo "$LIVEKIT_SERVER_CONFIG" | yq e '.rtc.port_range_start' -)"
        echo "               port_range_end: $(echo "$LIVEKIT_SERVER_CONFIG" | yq e '.rtc.port_range_end' -)"
        echo "               room.enabled_codecs: $(echo "$LIVEKIT_ENABLED_CODECS" | awk -v ORS=", " '{ print $1 }' | sed 's/, $//')"
        echo "               webrtc-sfu.livekit.enabled: $(echo "$WEBRTC_SFU_CONFIG" | yq e '.livekit.enabled' -)"
        echo "               webrtc-sfu.livekit.keyIsSet: $(echo "$WEBRTC_SFU_CONFIG" | yq e '.livekit.key != null' -)"
    fi

    if [ -n "$HTML5_CONFIG" ]; then
    echo
    echo "/usr/share/bigbluebutton/html5-client/private/config/settings.yml (HTML5 client)"
    echo "/etc/bigbluebutton/bbb-html5.yml (HTML5 client config override)"
    echo "                             build: $(echo "$HTML5_CONFIG" | yq e '.public.app.html5ClientBuild' -)"
    echo "                        kurentoUrl: $(echo "$HTML5_CONFIG" | yq e '.public.kurento.wsUrl' -)"
    echo "            defaultFullAudioBridge: $(echo "$HTML5_CONFIG" | yq e '.public.media.audio.defaultFullAudioBridge' -)"
    echo "           defaultListenOnlyBridge: $(echo "$HTML5_CONFIG" | yq e '.public.media.audio.defaultListenOnlyBridge' -)"
    echo "                    sipjsHackViaWs: $(echo "$HTML5_CONFIG" | yq e '.public.media.sipjsHackViaWs' -)"
    fi

    if [ ! -z "$STUN" ]; then
    for i in $STUN; do
        echo
        echo "$TURN (STUN Server)"
        echo "                              stun: $(xmlstarlet sel -N x="http://www.springframework.org/schema/beans" -t -m "_:beans/_:bean[@id=\"$i\"]/_:constructor-arg[@index=\"0\"]" -v @value $TURN | sed 's/stun://g')"
    done
    fi

    check_state
    echo

    exit 0
fi

#
# Zip log files
#
if [ $ZIP ]; then
    need_root

    LOG_FILE="$(date +'%Y%m%d')-$(date +%H).tar"
    TMP_LOG_FILE="/tmp/$LOG_FILE"
    #
    # Check log files
    #
    rm -f "$LOG_FILE.gz"
    rm -f /tmp/a

    touch /tmp/empty
    tar cf  $TMP_LOG_FILE /tmp/empty               > /dev/null 2>&1
    tar rf  $TMP_LOG_FILE /var/log/bigbluebutton/* > /dev/null 2>&1
    tar rf  $TMP_LOG_FILE /var/log/bbb-apps-akka   > /dev/null 2>&1
    tar rf  $TMP_LOG_FILE /var/log/bbb-fsesl-akka         > /dev/null 2>&1
    tar rf  $TMP_LOG_FILE /var/log/bbb-webrtc-sfu         > /dev/null 2>&1
    tar rf  $TMP_LOG_FILE /var/log/redis                > /dev/null 2>&1
    tar rf  $TMP_LOG_FILE /var/log/nginx/error.log*     > /dev/null 2>&1
    tar rf  $TMP_LOG_FILE /var/log/nginx/bigbluebutton.access.log*    > /dev/null 2>&1
    tar rfh $TMP_LOG_FILE /opt/freeswitch/var/log/freeswitch/         > /dev/null 2>&1

    if [ -f /var/log/nginx/html5-client.log ]; then
        tar rf $TMP_LOG_FILE /var/log/nginx/html5-client.log* > /dev/null 2>&1
    fi

    if [ -f /var/log/syslog ]; then
        tar rf $TMP_LOG_FILE /var/log/syslog* > /dev/null 2>&1
    fi

    tar tf $TMP_LOG_FILE
    gzip $TMP_LOG_FILE
    $SUDO mv $TMP_LOG_FILE.gz /root/$LOG_FILE.gz
    echo
    echo "  Created: /root/$LOG_FILE.gz"
    echo
fi

#
# Check current setup
#
if [ $DEBUG ]; then
    need_root
    #
    # Check log files
    #

    rm -rf /tmp/t
    grep --directories=skip ERROR /var/log/bigbluebutton/* > /tmp/t
    if [ -s /tmp/t ]; then
        echo "  -- ERRORS found in /var/log/bigbluebutton/* -- "
        cat /tmp/t
        echo
    fi

    rm -rf /tmp/t
    grep --directories=skip Exception /var/log/bigbluebutton/* | grep -v CacheExceptionHandlerFactory > /tmp/t
    if [ -s /tmp/t ]; then
        echo "  -- ERRORS found in /var/log/bigbluebutton/* -- "
        cat /tmp/t
        echo
    fi

    rm -rf /tmp/t
    if [ -s /var/log/nginx/error.log ]; then
        cat /var/log/nginx/error.log | grep -v "/fcs/ident2" > /tmp/t
        if [ -s /tmp/t ]; then
            echo "   -- Errors found in /var/log/nginx/error.log -- "
            cat /tmp/t
            echo
        fi
    fi

    if [ $DISTRIB_ID == "Ubuntu" ]; then
        rm -rf /tmp/t
        $SUDO grep --directories=skip -i exception /var/log/syslog > /tmp/t
        if [ -s /tmp/t ]; then
            echo "   -- Errors found in /var/log/syslog -- "
            cat /tmp/t
            echo
        fi
    fi

    rm -rf /tmp/t
    if [ -d /var/log/bigbluebutton ]; then
        $SUDO grep --directories=skip ERROR /var/log/bigbluebutton/* > /tmp/t
        if [ -s /tmp/t ]; then
            echo "   -- Errors found in /var/log/bigbluebutton -- "
            cat /tmp/t
            echo
        fi
    fi

    rm -rf /tmp/t
    if [ -d /var/log/bigbluebutton ]; then
        $SUDO grep --directories=skip -i exception /var/log/bigbluebutton/* > /tmp/t
        if [ -s /tmp/t ]; then
            echo "   -- Exceptions found in /var/log/bigbluebutton -- "
            cat /tmp/t
            echo
        fi
    fi

    #
    # Additional checks for record and playback
    #

    if [ -f /usr/local/bigbluebutton/core/scripts/bigbluebutton.yml ]; then
        bbb-record --check
    fi

    exit 0
fi



# if asked to print the version that's all we do
if [ -n "$HOST" ]; then
    need_root

    #
    # Update configuration for BigBlueButton web app
    #
    echo "Assigning $HOST for web application URL in $BBB_WEB_ETC_CONFIG"
    if [ -f "$BBB_WEB_ETC_CONFIG" ] && grep "bigbluebutton.web.serverURL" "$BBB_WEB_ETC_CONFIG" > /dev/null ; then
        change_var_value "$BBB_WEB_ETC_CONFIG" bigbluebutton.web.serverURL "$PROTOCOL://$HOST"
    else
        echo "bigbluebutton.web.serverURL=$PROTOCOL://$HOST" >> "$BBB_WEB_ETC_CONFIG"
    fi

    # Populate /etc/bigbluebutton/bbb-web.properties with the shared secret
    if ! grep -q "^securitySalt" "$BBB_WEB_ETC_CONFIG"; then
        echo "securitySalt=$(get_bbb_web_config_value securitySalt)" >> "$BBB_WEB_ETC_CONFIG"
    fi


    if ! grep -q server_names_hash_bucket_size /etc/nginx/nginx.conf; then
        $SUDO sed -i "s/gzip  on;/gzip  on;\n    server_names_hash_bucket_size  64;/g" /etc/nginx/nginx.conf
    fi

    #
    # Update bbb-apps-akka
    #
    echo "Assigning $HOST for web application URL in /etc/bigbluebutton/bbb-apps-akka.conf"

    if [ -f /etc/bigbluebutton/bbb-apps-akka.conf ]; then
        sed -i  "s/bbbWebAPI[ ]*=[ ]*\"[^\"]*\"/bbbWebAPI=\"${PROTOCOL}:\/\/$HOST\/bigbluebutton\/api\"/g" \
                /etc/bigbluebutton/bbb-apps-akka.conf
        # Fix to ensure bbb-apps-akka.conf has the latest shared secret
        SECRET=$(get_bbb_web_config_value securitySalt)
        sed -i "s/sharedSecret[ ]*=[ ]*\"[^\"]*\"/sharedSecret=\"$SECRET\"/g" \
                /etc/bigbluebutton/bbb-apps-akka.conf
    fi

    if [ -f /usr/local/bigbluebutton/core/scripts/bigbluebutton.yml ]; then
        echo "Assigning $HOST for record and playback in /usr/local/bigbluebutton/core/scripts/bigbluebutton.yml"
        change_yml_value /usr/local/bigbluebutton/core/scripts/bigbluebutton.yml playback_host $HOST
    fi

    if [ -f /usr/local/bigbluebutton/bbb-webhooks/config/default.yml ]; then
        echo "Assigning $HOST for webhooks in /usr/local/bigbluebutton/bbb-webhooks/config/default.yml"
        change_yml_value /usr/local/bigbluebutton/bbb-webhooks/config/default.yml serverDomain $HOST
    fi

    echo -n "Assigning $HOST for playback of recordings: "
    for metadata in $(find -L /var/bigbluebutton/published /var/bigbluebutton/unpublished -name metadata.xml); do
        echo -n "."
        # Ensure we update both types of URLs
        xmlstarlet edit --inplace --update '//link[starts-with(normalize-space(), "https://")]' --expr "concat(\"https://\", \"$HOST/\", substring-after(substring-after(., \"https://\"),\"/\"))" $metadata
        xmlstarlet edit --inplace --update '//link[starts-with(normalize-space(), "http://")]' --expr "concat(\"http://\", \"$HOST/\", substring-after(substring-after(., \"http://\"),\"/\"))" $metadata

        #
        # Update thumbnail links
        #
        xmlstarlet edit --inplace --update '//images/image[starts-with(normalize-space(), "https://")]' --expr "concat(\"https://\", \"$HOST/\", substring-after(substring-after(., \"https://\"),\"/\"))" $metadata
        xmlstarlet edit --inplace --update '//images/image[starts-with(normalize-space(), "http://")]' --expr "concat(\"http://\", \"$HOST/\", substring-after(substring-after(., \"http://\"),\"/\"))" $metadata
    done
    echo

    #
    # Update HTML5 client
    #
    if [ ! -f $HTML5_ETC_CONFIG ]; then
        touch $HTML5_ETC_CONFIG
    fi
    yq e -i ".public.kurento.wsUrl = \"wss://$HOST/bbb-webrtc-sfu\"" $HTML5_ETC_CONFIG
    yq e -i ".public.pads.url = \"$PROTOCOL://$HOST/pad\"" $HTML5_ETC_CONFIG

    #
    # Update ESL passwords in three configuration files
    #
    ESL_PASSWORD=$(cat /etc/bigbluebutton/bbb-fsesl-akka.conf | grep password | head -n 1 | sed 's/.*="//g' | sed 's/"//g')
    if [ "$ESL_PASSWORD" == "ClueCon" ]; then
        ESL_PASSWORD=$(openssl rand -hex 8)
        sed -i "s/ClueCon/$ESL_PASSWORD/g" /etc/bigbluebutton/bbb-fsesl-akka.conf
    fi

    if [ ! -f $WEBRTC_SFU_ETC_CONFIG ]; then
        touch $WEBRTC_SFU_ETC_CONFIG
    fi
    yq e -i ".freeswitch.esl_password = \"$ESL_PASSWORD\"" $WEBRTC_SFU_ETC_CONFIG
    xmlstarlet edit --inplace --update 'configuration/settings//param[@name="password"]/@value' --value $ESL_PASSWORD /opt/freeswitch/etc/freeswitch/autoload_configs/event_socket.conf.xml
    if [ -f /usr/local/bigbluebutton/bbb-transcription-controller/config/default.yml ]; then
        yq e -i ".freeswitch.password = \"$ESL_PASSWORD\"" /usr/local/bigbluebutton/bbb-transcription-controller/config/default.yml
    fi

    echo "Restarting BigBlueButton $BIGBLUEBUTTON_RELEASE ..."
    stop_bigbluebutton
    start_bigbluebutton

    exit 0
fi


if [ $RESTART ]; then
    need_root
    check_configuration

    echo "Restarting BigBlueButton $BIGBLUEBUTTON_RELEASE ..."

    stop_bigbluebutton
    start_bigbluebutton
    check_state
fi

if [ $CLEAN ]; then
    need_root
    check_configuration

    echo "Restarting BigBlueButton $BIGBLUEBUTTON_RELEASE (and cleaning out all log files) ..."

    stop_bigbluebutton

    #
    # Clean log files
    #

    echo " ... cleaning log files"
    rm -f /var/log/bigbluebutton/*.log

    rm -f /opt/freeswitch/var/log/freeswitch/*.log
    rm -f /opt/freeswitch/var/log/freeswitch/*.log.*

    #
    # Clean out the log files for record and playback
    #
    rm -f /var/log/bigbluebutton/bbb-rap-worker.log*
    rm -f /var/log/bigbluebutton/bbb-rap-resque.log*
    rm -f /var/log/bigbluebutton/archive.log*
    if [ -d /var/log/bigbluebutton/html5 ]; then
        rm -f /var/log/bigbluebutton/html5/*
    fi

    if [ -d /var/log/bigbluebutton/podcast ]; then
        rm -f /var/log/bigbluebutton/podcast/*
    fi

    if [ -d /var/log/bigbluebutton/presentation ]; then
        rm -f /var/log/bigbluebutton/presentation/*
    fi

    # Check if we are storing HTML5 logs in the server
    HTML5_SERVER_LOG=0
    if [[ -f /var/log/nginx/html5-client.log ]]; then
        HTML5_SERVER_LOG=1
    fi

    rm -rf /var/log/nginx/*

    # Revert HTML5 client logs to their original permissions
    if [ $HTML5_SERVER_LOG ]; then
        touch /var/log/nginx/html5-client.log
        chown www-data:adm /var/log/nginx/html5-client.log
        chmod 640 /var/log/nginx/html5-client.log
    fi

    if [ -d /var/log/bbb-fsesl-akka ]; then
        rm -f /var/log/bbb-fsesl-akka/*
    fi

  if [ -d /var/log/bbb-apps-akka ]; then
        rm -f /var/log/bbb-apps-akka/*
    fi

    if [ -d /var/log/bbb-webrtc-sfu ]; then
        rm -f /var/log/bbb-webrtc-sfu/*
    fi

    if [ -d /var/log/redis ]; then
        rm -f /var/log/redis/*
    fi

    if [ -d /var/log/mongodb ]; then
        rm -f /var/log/mongodb/*
    fi

    start_bigbluebutton
    check_state
fi

if [ $NETWORK ]; then
    ss -ant | egrep ":80|:443\ " | egrep -v ":::|0.0.0.0" > /tmp/t_net
    REMOTE=$(cat /tmp/t_net | cut -c 45-68 | cut -d ":" -f1 | sort | uniq)

    if [ "$REMOTE" != "" ]; then
        echo -e "ss\t\t\t80\t443"
        for IP in $REMOTE ; do
            PORT_80=$(cat /tmp/t_net | grep :80 | cut -c 45-68 | cut -d ":" -f1 | grep $IP | wc -l )
            PORT_443=$(cat /tmp/t_net | grep :443 | cut -c 45-68 | cut -d ":" -f1 | grep $IP | wc -l )

            echo -e "$IP\t\t$PORT_80\t$PORT_443"
        done
    fi
    rm /tmp/t_net
fi

if [ $WATCH ]; then
    need_root
    watch -n 2 "top -n 1 -b | head -n 5; echo; bbb-conf --network; bbb-conf --debug"
fi
