#!/bin/bash

export LC_ALL=C

# Set variables
servers_list="/etc/openvpn-server/servers.conf"
management_host="127.0.0.1"
management_port="7505"
ssh_key="/var/lib/openvpn-server/openssl/ssh-keys/id_rsa"
temp_file="/tmp/openvpn_clients.txt"
delay=1
ssh_timeout=10
max_retries=3

# Read the management password from the file
management_password=$(cat /var/lib/openvpn-server/openssl/management.pw)

# Format and print the table header
printf "%-20s %-20s %-20s %-20s %-20s %-20s %-30s\n" "Server" "Common Name" "Public IP" "VPN IP" "Bytes Received" "Bytes Sent" "Connected Since"

for server in `cat $servers_list`
do
    if [[ ! "${server}" =~ ^\s*# ]] && [[ -n "${server}" ]]; then
        success=0
        retries=0

        while [[ ${success} -eq 0 ]] && [[ ${retries} -lt ${max_retries} ]]; do
            ssh -i "${ssh_key}" -o ConnectTimeout="${ssh_timeout}" admin@"${server}" "(
                exec 3<>/dev/tcp/${management_host}/${management_port}
                printf 'auth-pass\n%s\n' '${management_password}' >&3
                sed -u '/ENTER PASSWORD:/q' <&3
                printf 'status 3\nquit\n' >&3
                cat <&3
                exec 3<&-
            )" > "${temp_file}"

            # Check if there are clients connected to the server
            if grep -q "^CLIENT_LIST" "${temp_file}"; then
                success=1
            else
                retries=$((retries + 1))
                sleep ${delay}
            fi
        done

        if [[ ${success} -eq 1 ]]; then
            # Parse and format the output
            grep "^CLIENT_LIST" "${temp_file}" | awk -v server_name="${server}" '{
                gsub(/:[0-9]+$/, "", $3)  # Remove the port from the public IP
                friendly_time = strftime("%Y-%m-%d %H:%M:%S", $9)
                time_diff = systime() - $9
                days = int(time_diff / 86400)
                hours = int((time_diff % 86400) / 3600)
                minutes = int((time_diff % 3600) / 60)
                seconds = int(time_diff % 60)
                relative_time = sprintf("%dd %dh %dm %ds ago", days, hours, minutes, seconds)
                printf "%-20s %-20s %-20s %-20s %-20s %-20s %-30s\n", server_name, $2, $3, $4, $5, $6, relative_time
            }'
        else
            # Print "No clients connected" if there are no clients
            printf "%-20s %-20s %-20s %-20s %-20s %-20s %-30s\n" "${server}" "No clients connected" "" "" "" "" ""
        fi

        # Wait for the specified delay before processing the next server
        sleep ${delay}
    fi
done

# Remove the temporary file
rm "${temp_file}"
