#!/bin/bash

source /etc/iplimit/db.sh
json_file="/usr/local/x-ui/bin/config.json"
ports=($(jq -r '.inbounds[].port' "$json_file"))


echo_help() {
	echo "Usage: $0 [-p PORT] [-l LIMITS] [-s SPEED] [-i] [-gt GT_VALUE] [-eq EQ_VALUE] [-lt LT_VALUE] [-c] [-h]"
	echo "Options:"
	echo "  -p, --p, -P, --P	Port (Optional)			Port number to work on"
	echo "  -l, --l, -L, --L	Limit (Optional)			Set maximum connection limit for this port"
	echo "  -s, --s, -S, --S	Speed (Optional)			Set maximum speed for this port (e.g., 1mbps)"
	echo "  -i, --i, -I, --I	Ignore (Optional)			Set no limit to this port"
	echo "  -d, --d, -D, --D	Delete (Optional)			Delete this port"
	echo "  -v, --v, -V, --V	Delete (Optional)			View the limit tabble"
	echo "  -gt, --gt, -GT, --GT Greater than (Optional)	Find ports with connected IPs count greater than given value"
	echo "  -eq, --eq, -EQ, --EQ Equal (Optional)			Find ports with connected IPs count equal to given value"
	echo "  -lt, --lt, -LT, --LT Lower than (Optional)		Find ports with connected IPs count lower than given value"
	echo "  -c, --c, -C, --C	Search type (Optional)		Display total counts instead of each port"
	echo "  -h, --h, -H, --H	Help						Show this help screen"
}

convert_speed() {
  local input="$1"
  # Extract numeric value
  local numeric_value="${input%%[a-zA-Z]*}"
  # Extract the first letter after the numeric part
  local first_letter="${input:${#numeric_value}:1}"
  converted_value=$((numeric_value * 8))
  echo "${converted_value}${first_letter}bit"
}


ignore_flag=0
count_flag=0
delete_flag=0
view_flag=0
search_type="eq"
search_value=""

while [[ $# -gt 0 ]]; do
    case "$1" in
        -p|--p|-P|--P)
            if [[ -n $2 && $2 =~ ^[0-9]+$ ]]; then
                port="$2"
                shift 2
            else
                echo "Error: Port option requires a valid port number."
                exit 1
            fi
            ;;
        -l|--l|-L|--L)
            if [[ -n $2 && $2 =~ ^[0-9]+$ ]]; then
                limit="$2"
                shift 2
            else
                echo "Error: Limits option requires a valid number."
                exit 1
            fi
            ;;
        -s|--s|-S|--S)
            if [[ -n $2 && $2 =~ ^[1-9]+[0-9]*[kmgtp](bit|bps)$ ]]; then
				if [[ -n $2 && $2 =~ ^[1-9]+[0-9]*[kmgtp](bps)$ ]]; then
					speed=$(convert_speed "$2")
					
				else
					speed="$2"
				fi
				shift 2
            else
                echo "Error: Speed option requires a valid speed format (e.g., 1mbps)."
                exit 1
            fi
            ;;
        -i|--i|-I|--I)
            ignore_flag=1
            shift
            ;;
        -d|--d|-D|--D)
            delete_flag=1
            shift
            ;;
        -v|--v|-V|--V)
            view_flag=1
            shift
            ;;
        -gt|--gt|-GT|--GT)
            if [[ -n $2 && $2 =~ ^[0-9]+$ ]]; then
				search_type="gt"
                search_value="$2"
                shift 2
            else
                echo "Error: Greater than option requires a valid numeric value."
                exit 1
            fi
            ;;
        -eq|--eq|-EQ|--EQ)
            if [[ -n $2 && $2 =~ ^[0-9]+$ ]]; then
				search_type="eq"
                search_value="$2"
                shift 2
            else
                echo "Error: Equal option requires a valid numeric value."
                exit 1
            fi
            ;;
        -lt|--lt|-LT|--LT)
            if [[ -n $2 && $2 =~ ^[0-9]+$ ]]; then
				search_type="lt"
                search_value="$2"
                shift 2
            else
                echo "Error: Lower than option requires a valid numeric value."
                exit 1
            fi
            ;;
        -c|--c|-C|--C)
            count_flag=1
            shift
            ;;
        -h|--h|-H|--H)
			echo_help
			exit 0
			;;
        *)
            echo "Error: Unknown option $1"
			echo_help
            exit 1
            ;;
    esac
done

# Use the parsed values as needed, for example:
if [ -n "$port" ]; then
	if [ "$count_flag" -eq 1 ]; then
		connections=$(netstat -tn | awk '{split($4, lparts, ":"); split($5, rparts, ":"); ip=rparts[1] ":" lparts[2]; if (!seen[ip]++) print ip;}')
		connected_ips=$(echo "$connections" | grep ":$port")
		count=$(echo "$connected_ips" | wc -l)
		echo $connected_ips
		echo "Total: $count"
		exit 0;
	fi
	
	if [ "$view_flag" -eq 1 ]; then
		view_ports $port
		exit 0;
	fi

	port_info=$(add_port "$port")
	if [ -n "$limit" ]; then
		update_port $port "'limit'='$limit'"
	fi

	if [ -n "$speed" ]; then
		update_port $port "'speed'='$speed'"
		
	fi

	if [ "$ignore_flag" -eq 1 ]; then
		current_ignore=$(echo "$port_info" | awk -F',' '{print $NF}' | tr -d '[:space:]')
		if [ "$current_ignore" -eq 0 ]; then
			#port_info=$(update_port "$port" "'ignore'='1'")
			update_port "$port" "'ignore'='1'"
		else
			#port_info=$(update_port "$port" "'ignore'='0'")
			update_port "$port" "'ignore'='0'"
		fi
	fi

	view_ports $port

	if [ "$delete_flag" -eq 1 ]; then
		delete_port $port
		exit 0;
	fi
else
	if [ -n "$search_value" ]; then
		connections=$(netstat -tn | awk '{split($4, lparts, ":"); split($5, rparts, ":"); ip=rparts[1] ":" lparts[2]; if (!seen[ip]++) print ip;}')
		#connections=$(netstat -tn)
		#connections=$(ss -tna)
		total_connections=$(echo "$connections" | wc -l)
		echo "Checking against ${#ports[@]} ports with $total_connections (IP) connections..."
		if [ "$count_flag" -eq 1 ]; then
			count_ports=0
			for port in "${ports[@]}"; do
				count=$(echo "$connections" | grep ":$port" | wc -l)
				if [ "$count" "-$search_type" "$search_value" ]; then
					((count_ports++))
				fi
			done
			echo $count_ports;
		else
			for port in "${ports[@]}"; do
				count=$(echo "$connections" | grep ":$port" | wc -l)
				if [ "$count" "-$search_type" "$search_value" ]; then
					echo "$port ($count)"
				fi
			done
		fi
	else
		if [ "$view_flag" -eq 1 ]; then
			view_ports
			exit 0;
		else
			echo_help
		fi
	fi
fi