# Check if process ID is valid
function checkpid() {
    if [ -f "$1" ]; then 
        out=$(cat "$1")
        if [ -z "$(ps -ef | awk -v pid="$out" '{if ($2 == pid) {print $2}}')" ]; then
            exit 1
        fi
    else 
        exit 1
    fi 
    echo "$out"
}

# Kill a service
function kill_service() {
    if [ "$1" -ne 0 ]; then 
        echo "$2 not running"
    else 
        kill "$4" "$3" > /dev/null 2>&1
    fi 
}

# Remove Apache built-in modules
function removeapachebuildinmodules() {
    "$2" -l | grep -v "Compiled in modules" | sed "s|\.c$|.so|g" | while read -r line; do
        sed -i "/^LoadModule.*\/${line}$/d" "$1"
    done  
}

# Get PandaBot configuration from YAML
function getpandabotconf() {
    out=$(echo "$1@@$2" | php -R '
        $in=explode("@@", $argn); 
        $config = yaml_parse_file($in[0]);
        if (array_key_exists($in[1], $config)) {
            echo $config[$in[1]];
        } else {
            exit(1);
        }
    ')
    if [ $? -ne 0 ]; then
        exit 1
    fi
    echo "$out"
}

# Get the path of the HTTP daemon (httpd or apache2)
function httpdbin() {
    out=$(which httpd 2> /dev/null)
    if [ $? -ne 0 ]; then
        out=$(which apache2 2> /dev/null)
        if [ $? -ne 0 ]; then
            exit 1
        fi
    fi 
    echo "$out"
}

# Find PHP-FPM binary
function phpfpmbin() {
    out=$(find /usr/sbin/ -name php-fpm* 2> /dev/null | head -1)
    if [ -z "$out" ]; then
        exit 1
    fi
    echo "$out"
}

# Find Apache mod_mpm_event.so path
function apachemod() {
    out=$(find /usr -name "mod_mpm_event.so" 2> /dev/null | awk -F / '{for (i=1;i<NF;i++) {printf ("%s/",$i)}}')
    if [ -z "$out" ]; then
        exit 1
    fi
    echo "$out"
}

# Check if the service is running
function checkservice() {
    out=$(echo "$2" | while read -d "|" arg; do
        if [ "$arg" = "$1" ]; then 
            echo "$1"
            break
        fi
    done) 
    if [ -z "$out" ]; then
        echo "$1"
        exit 1
    fi
    echo "$out"
}

# Prepare web server environment variables
function prepare_web() {
    apache_serverroot="$bot_root"
    apache_start=$(getpandabotconf "$pandabotconf" "apache_start")
    
    if [ $? -ne 0 ]; then
        echo "ERR: apache_start not configured @ $pandabotconf"
        exit 1
    fi

    if [ "$apache_start" != "1" ]; then
        echo "apache_start is not set yes @ $pandabotconf"
        exit 1
    fi 

    if [ "$(id -u)" -eq 0 ]; then 
        apache_user="nobody"
        apache_group="nobody"
    else 
        apache_user=$(id -un)
        apache_group=$(id -gn)
    fi 

    apache_port=$(getpandabotconf "$pandabotconf" "apache_port")
    if [ $? -ne 0 ]; then
        echo "ERR: apache_port not configured @ $pandabotconf"
        exit 1
    fi

    if [ "$apache_port" -lt 1025 ]; then
        echo "ERR: apache_port must be greater than 1024 @ $pandabotconf"
        exit 1
    fi 
}

# Start PHP-FPM service
function start_fpm() {
    prepare_web
    php_fpm_bin=$(phpfpmbin)
    
    if [ $? -ne 0 ]; then
        echo "ERR: php-fpm installation not found"
        exit 1
    fi

    cat "${apache_serverroot}/conf/templates/template.php-fpm.conf" | \
        sed "s|@@apache_serverroot@@|$apache_serverroot|g" \
            | sed "s|@@apache_user@@|$apache_user|g" \
            | sed "s|@@apache_group@@|$apache_group|g" \
            | sed "s|@@apache_port@@|$apache_port|g" \
        > "${apache_serverroot}/conf/php-fpm.conf"

    "$php_fpm_bin" -y "${apache_serverroot}/conf/php-fpm.conf" 2> /dev/null
    if [ $? -ne 0 ]; then
        echo "php-fpm already running"
        out=$(checkpid "$fpm_pid")
        kill "$out" > /dev/null 2>&1
        "$php_fpm_bin" -y "${apache_serverroot}/conf/php-fpm.conf" 2> /dev/null
        echo "php-fpm restarted"
    else 
        echo "php-fpm started"
    fi 
}

# Start Apache service
function start_apache() {
    prepare_web
    apachebin=$(httpdbin)
    
    if [ $? -ne 0 ]; then
        echo "ERR: apache installation not found"
        exit 1
    fi

    apache_modules=$(apachemod)
    
    if [ $? -ne 0 ]; then
        echo "ERR: no apache modules path found"
        exit 1
    fi

    rm -rf "${apache_serverroot}/log/access_log" > /dev/null 2>&1 # clear access_log file...

    apache_pid="${apache_serverroot}/log/tmp/httpd.pid"
    apache_documentroot="${apache_serverroot}/pb-web"

    cat "${apache_serverroot}/conf/templates/template.httpd.conf" | \
        sed "s|@@apache_modules@@|$apache_modules|g" \
            | sed "s|@@apache_serverroot@@|$apache_serverroot|g" \
            | sed "s|@@apache_user@@|$apache_user|g" \
            | sed "s|@@apache_group@@|$apache_group|g" \
            | sed "s|@@apache_port@@|$apache_port|g" \
            | sed "s|@@apache_documentroot@@|$apache_documentroot|g" \
            | sed "s|@@apache_pid@@|$apache_pid|g" \
        > "${apache_serverroot}/conf/httpd.conf"

    removeapachebuildinmodules "${apache_serverroot}/conf/httpd.conf" "$apachebin"

    chmod -R a+rwx "$apache_documentroot" 2>&1 /dev/null
    chmod -R a+rwx "${apache_serverroot}/log" 2>&1 /dev/null

    "$apachebin" -f "${apache_serverroot}/conf/httpd.conf" -k restart > /dev/null 2>&1
    if [ $? -eq 0 ]; then 
        echo "Apache (re)started @ port: $apache_port"
    else 
        echo "ERR: Apache not started, something is wrong..."
    fi 
}

# Start the bot
function start_bot() {
    out=$(checkpid "$bot_pid")
    if [ -n "$out" ]; then
        echo "Bot already running, exit!"
        exit 1
    fi

    cp conf/channels.conf "log/conf/${startDate}_channels.conf"
    cp conf/pandabot.conf "log/conf/${startDate}_pandabot.conf"

    # Clean up old log files
    ls -r1 log/*_pandabot.app.log | awk 'NR >= 10' | xargs -n1 rm -f
    ls -r1 log/conf/*pandabot.conf | awk 'NR >= 10' | xargs -n1 rm -f
    ls -r1 log/conf/*channels.conf | awk 'NR >= 10' | xargs -n1 rm -f

    if [ "$(id -u)" -eq 0 ]; then 
        chown -R nobody *
        su nobody -c "nohup bin/pandabot.php 2>&1 | tee log.pandabot.log 2>&1 | tee log/${startDate}_pandabot.app.log > /dev/null &"
        if [ $? -ne 0 ]; then
            echo "Change user nobody from nologin to bash"
            usermod -s /usr/bin/bash nobody
            su nobody -c "nohup bin/pandabot.php 2>&1 | tee log.pandabot.log 2>&1 | tee log/${startDate}_pandabot.app.log > /dev/null &"
            if [ $? -ne 0 ]; then
                echo "ERR: Change user nobody manually from /sbin/nologin to /bin/bash @ /etc/passwd, or start bot in user context" 
                exit 1
            fi
        fi
    else  
        nohup bin/pandabot.php 2>&1 | tee log.pandabot.log 2>&1 | tee log/${startDate}_pandabot.app.log > /dev/null &
    fi
}

# Start a specific service
function start_service() {
    echo "Start $1"
    case "$1" in
        "bot") start_bot ;;
        "apache") 
            start_apache
            sleep 2
            status_service "apache"
            ;;
        "fpm") start_fpm ;;
        "web") 
            start_service "apache"
            start_service "fpm"
            ;;
        "all") 
            start_service "bot"
            start_service "web"
            ;;
    esac
}

# Stop a specific service
function stop_service() {
    echo "Stop $1"
    case "$1" in
        "bot")
            out=$(checkpid "$bot_pid")
            kill_service "$?" "$1" "$out" "-9"
            ;;
        "apache")
            out=$(checkpid "$apache_pid")
            kill_service "$?" "$1" "$out" ""
            ;;
        "fpm")
            out=$(checkpid "$fpm_pid")
            kill_service "$?" "$1" "$out" ""
            ;;
        "madeline")
            kill_service "0" "$1" "$madeline_pid" "-9"
            ;;
        "web")
            stop_service "apache"
            stop_service "fpm"
            ;;
        "all")
            stop_service "web"
            stop_service "bot"
            stop_service "madeline"
            ;;
    esac
}

# Get the status of a service
function status_service() {
    case "$1" in
        "bot")
            out=$(checkpid "$bot_pid")
            if [ $? -eq 0 ]; then
                echo "$1 running"
            else
                echo "$1 not running"
            fi
            ;;
        "apache")
            out=$(checkpid "$apache_pid")
            if [ $? -eq 0 ]; then 
                apache_ip_running=$(ip -br address | grep -iwv lo | awk '{print $3}' | awk -F / '{print $1}')
                apache_port=$(getpandabotconf "$pandabotconf" "apache_port")
                echo "$1 running on: http://$apache_ip_running:$apache_port/"
            else 
                echo "$1 not running"
            fi 
            ;;
        "fpm")
            out=$(checkpid "$fpm_pid")
            if [ $? -eq 0 ]; then
                echo "$1 running"
            else
                echo "$1 not running"
            fi
            ;;
        "madeline")
            if [ $? -eq 0 ]; then
                echo "$1 running"
            else
                echo "$1 not running"
            fi
            ;;
        "web")
            echo "Status $1"
            status_service "apache"
            status_service "fpm"
            ;;
        "all")
            echo "Status $1"
            status_service "web"
            status_service "bot"
            status_service "madeline"
            ;;
    esac
}

# Bot script usage guide
function bot_sh_usage() {
    echo "Usage: 
./bot.sh start
./bot.sh stop
./bot.sh restart
./bot.sh status 
-
./bot.sh setuptg 

./bot.sh start   -s [bot|web]
./bot.sh stop    -s [bot|web]
./bot.sh restart -s [bot|web]
./bot.sh status  -s [bot|web]
Example:
./bot.sh restart -s bot
./bot.sh restart -s web
"
}
