#!/bin/bash

################################################################################
# Script Name: User IP Analyzer
# Description: Analyze connected IPs for different users in Xray access logs.
# Author: Eko Linggar
# Version: 4.1
################################################################################

clear

# Function to print a stylish header
print_header() {
    echo "**************************************************"
    echo "*                                                *"
    echo "*             User IP Analyzer                   *"
    echo "*                                                *"
    echo "**************************************************"
    echo ""
}

# Function to print a stylish line
print_line() {
    echo "------------------------"
}

# Function to get the count of log entries for a user
get_user_log_count() {
    local username="$1"
    local log_file="/var/lib/marzban/assets/access.log"

    # Get the count of log entries for the specified username
    log_count=$(grep -c -E "$username" "$log_file")

    echo "$log_count"
}

# Function to get log data for a user
get_user_log_data() {
    local username="$1"
    local log_file="/var/lib/marzban/assets/access.log"

    # Get the count of log entries for the user
    log_count=$(get_user_log_count "$username")

    if [ "$log_count" -eq 0 ]; then
        datalog="No log data available for this user."
    else
        datalog="User appears in log \033[0;33m$log_count times.\033[0m"
    fi

    echo -e "$datalog"
}

# Function to convert API's Online At to WIB with offset
convert_api_online_at_to_wib() {
    local api_time="$1"
    local offset_hours=7
    local wib_time

    # Tambahkan offset waktu langsung ke waktu API jika api_time tidak null
    if [ "$api_time" != "null" ]; then
        wib_time=$(date --date="${api_time} WIB+${offset_hours} hours" +"%Y-%m-%d %H:%M:%S")
    else
        wib_time="null"
    fi

    echo "$wib_time"
}

# Get domain and token from files
    domain=$(cat /root/domain)
    token=$(cat /root/token.json | jq -r .access_token)

# Function to get user IPs from API and match with log file
get_user_ips() {
local protocol="$1"
local log_file="/var/lib/marzban/assets/access.log"

# Counter for numbering users
counter=1

# Total connected IPs counter
total_ips=0

# Get all usernames and online_at from API
user_data=$(curl -sX GET "https://${domain}/api/users" -H "accept: application/json" -H "Authorization: Bearer ${token}")

# Extract usernames and online_at based on protocol
usernames=$(echo "$user_data" | jq -r --arg protocol "$protocol" '.users[] | select(.proxies | has($protocol)) | .username')
online_at_values=$(echo "$user_data" | jq -r --arg protocol "$protocol" '.users[] | select(.proxies | has($protocol)) | .online_at')

# Combine usernames and online_at values
mapfile -t usernames_array < <(echo "$usernames")
mapfile -t online_at_array < <(echo "$online_at_values")

# Loop through each username and find connected IPs
    for ((i = 0; i < ${#usernames_array[@]}; i++)); do
    account="${usernames_array[i]}"
    online_at="${online_at_array[i]}"

# Convert Online At from API to WIB
    online_at_wib=$(convert_api_online_at_to_wib "$online_at")

    echo "$counter. User: $account (Protocol: $protocol)"

    if [ "$online_at_wib" == "null" ]; then
        echo "   No data available for this user."
    else
        echo -e "   Data login terakhir (WIB): \e[94m$online_at_wib\e[0m"

        # Get user IPs from log file
        connected_ips=$(grep -E "$account" "$log_file" | awk '{print $4}' | awk -F: '{print $1}' | grep -Eo "([0-9]{1,3}\.){3}[0-9]{1,3}" | sort -n -u)

        if [ -z "$connected_ips" ]; then
            echo "   No connected IPs for this user."
        else
            echo "   Connected IPs:"
            # Loop through each connected IP and add numbering
            ip_counter=1
    while read -r ip; do
        echo "      $ip_counter. $ip"

    # Check if the IP is not a local address (e.g., 127.0.0.1)
        if [[ $ip != "127.0.0.1" ]]; then
        # Get ASN and ISP information using ipinfo.io
        asn_isp_info=$(curl -s "http://ipinfo.io/$ip/org" | tr -d '"')

        echo "         ASN/ISP: $asn_isp_info"
        else
        echo "         ASN/ISP: N/A (Local Address)"
        fi

            ((ip_counter++))
            done <<< "$connected_ips"

            # Increment the total_ips counter
            ((total_ips += ip_counter - 1))
        fi

        # Get log data for the user
        datalog=$(get_user_log_data "$account")
        echo "   Log data pada user ini: $datalog"
    fi

    # Increment the counter
    ((counter++))

    # Print a stylish line
    print_line
done
    # Print total connected IPs
    echo "Total Connected IPs for $protocol: $total_ips"
}

# Main menu
print_header
echo "Select an option:"
echo "1. Check Trojan IPs"
echo "2. Check VMess IPs"
echo "3. Check VLess IPs"
echo "4. Check ShadowSocks IPs"
echo "5. Exit"

read -rp "Enter your choice (1-4): " choice

case $choice in
    1)
        protocol="trojan"
        get_user_ips "$protocol"
        ;;
    2)
        protocol="vmess"
        get_user_ips "$protocol"
        ;;
    3)
        protocol="vless"
        get_user_ips "$protocol"
        ;;
    4)
        protocol="shadowsocks"
        get_user_ips "$protocol"
        ;;
    5)
        echo "Exiting..."
        exit 0
        ;;
    *)
        echo "Invalid choice. Exiting..."
        exit 1
        ;;
esac
