#!/bin/bash

BASE_URL="https://autoscript.interflazz.my.id/v2"

WHATSAPP="https://wa.me/6285956131443"
TELEGRAM="https://t.me/interflazz"
BRAND="INTERFLAZZ.MY.ID"

json_escape() {
    local value="$1"

    value=${value//\\/\\\\}
    value=${value//\"/\\\"}
    value=${value//$'\n'/\\n}
    value=${value//$'\r'/\\r}
    value=${value//$'\t'/\\t}

    printf '%s' "$value"
}

show_access_denied() {
    local reason="$1"

    printf '{\n'
    printf '  "status": "error",\n'
    printf '  "brand": "%s",\n' "$(json_escape "$BRAND")"
    printf '  "message": "AKSES DITOLAK!",\n'
    printf '  "detail": "%s",\n' "$(json_escape "$reason")"
    printf '  "ip_vps": "%s",\n' "$(json_escape "$vps_ip")"
    printf '  "suggestion": "Silakan beli izin akses script untuk menggunakan layanan ini.",\n'
    printf '  "contact": {\n'
    printf '    "WhatsApp": "%s",\n' "$(json_escape "$WHATSAPP")"
    printf '    "Telegram": "%s"\n' "$(json_escape "$TELEGRAM")"
    printf '  }\n'
    printf '}\n'

    exit 1
}

convert_size() {
    local size="${1:-0}"

    if ! [[ "$size" =~ ^[0-9]+$ ]]; then
        size=0
    fi

    if [[ "$size" -lt 1024 ]]; then
        echo "${size} B"
    elif [[ "$size" -lt 1048576 ]]; then
        echo "$(((size + 1023) / 1024)) KB"
    elif [[ "$size" -lt 1073741824 ]]; then
        echo "$(((size + 1048575) / 1048576)) MB"
    else
        echo "$(((size + 1073741823) / 1073741824)) GB"
    fi
}

vps_ip=$(wget -qO- ipv4.icanhazip.com)

if [ -z "$vps_ip" ]; then
    vps_ip=$(curl -4 -s ipv4.icanhazip.com)
fi

data_acc=$(
    curl -s "${BASE_URL}/access" |
        grep "### $vps_ip " |
        awk '{print $3}'
)

if [ -z "$data_acc" ]; then
    show_access_denied "VPS belum memiliki izin akses script."
fi

expiry_date=$(date -d "$data_acc" +%s 2>/dev/null)
current_timestamp_access=$(date +%s)

if [ -z "$expiry_date" ]; then
    show_access_denied "Data masa aktif VPS tidak valid."
fi

if [ "$expiry_date" -le "$current_timestamp_access" ]; then
    show_access_denied "Masa aktif akses script telah berakhir."
fi

remaining_days=$(((expiry_date - current_timestamp_access) / 86400))

public_ip=$(curl -4 -s ipv4.icanhazip.com)

if [ -z "$public_ip" ]; then
    public_ip="$vps_ip"
fi

server_date=$(curl -s -I https://google.com 2>/dev/null | grep -i '^date:' | cut -d' ' -f2-)

if [ -n "$server_date" ]; then
    current_date=$(date +"%Y-%m-%d" -d "$server_date" 2>/dev/null)
else
    current_date=$(date +"%Y-%m-%d")
fi

current_time=$(date +%T)

apissh() {
    local log_file
    local objects=""
    local first=1

    rm -f \
        /tmp/ssh_login_user \
        /tmp/login-db-ssh.txt \
        /tmp/login-db-dropbear.txt \
        /tmp/login-db-pid-ssh.txt \
        /tmp/login-db-pid-dropbear.txt

    if [ -e "/var/log/auth.log" ]; then
        log_file="/var/log/auth.log"
    elif [ -e "/var/log/secure" ]; then
        log_file="/var/log/secure"
    else
        printf '{\n'
        printf '  "status": "error",\n'
        printf '  "brand": "%s",\n' "$BRAND"
        printf '  "message": "File log autentikasi SSH tidak ditemukan.",\n'
        printf '  "data": []\n'
        printf '}\n'
        exit 1
    fi

    grep -i "sshd" "$log_file" |
        grep -i "Accepted password for" \
        >/tmp/login-db-ssh.txt 2>/dev/null

    grep -i "dropbear" "$log_file" |
        grep -i "Password auth succeeded" \
        >/tmp/login-db-dropbear.txt 2>/dev/null

    mapfile -t ssh_pids < <(
        ps aux |
            grep "\[priv\]" |
            awk '{print $2}'
    )

    mapfile -t dropbear_pids < <(
        ps aux |
            grep -i "[d]ropbear" |
            awk '{print $2}'
    )

    for ssh_pid in "${ssh_pids[@]}"; do
        [ -z "$ssh_pid" ] && continue

        if grep -q "sshd\[$ssh_pid\]" /tmp/login-db-ssh.txt 2>/dev/null; then
            grep "sshd\[$ssh_pid\]" \
                /tmp/login-db-ssh.txt \
                >/tmp/login-db-pid-ssh.txt

            ssh_user=$(
                grep -oP '(?<=for )\w+' \
                    /tmp/login-db-pid-ssh.txt |
                    tail -1
            )

            ssh_ip=$(
                grep -oP '(?<=from )\d+\.\d+\.\d+\.\d+' \
                    /tmp/login-db-pid-ssh.txt |
                    tail -1
            )

            if [ -n "$ssh_user" ] && [ -n "$ssh_ip" ]; then
                echo "$ssh_pid $ssh_user $ssh_ip" >>/tmp/ssh_login_user
            fi
        fi
    done

    for dropbear_pid in "${dropbear_pids[@]}"; do
        [ -z "$dropbear_pid" ] && continue

        if grep -q "dropbear\[$dropbear_pid\]" /tmp/login-db-dropbear.txt 2>/dev/null; then
            grep "dropbear\[$dropbear_pid\]" \
                /tmp/login-db-dropbear.txt \
                >/tmp/login-db-pid-dropbear.txt

            dropbear_user=$(
                grep -oP "(?<=for ')\w+(?=' from)" \
                    /tmp/login-db-pid-dropbear.txt |
                    tail -1 |
                    sed "s/'//g"
            )

            dropbear_ip=$(
                grep -oP '(?<=from )\d+\.\d+\.\d+\.\d+' \
                    /tmp/login-db-pid-dropbear.txt |
                    tail -1 |
                    cut -d ':' -f1
            )

            if [ -n "$dropbear_user" ] && [ -n "$dropbear_ip" ]; then
                echo "$dropbear_pid $dropbear_user $dropbear_ip" >>/tmp/ssh_login_user
            fi
        fi
    done

    if [ -f /etc/ssh/.ssh.db ]; then
        mapfile -t ssh_users < <(
            grep '^###' /etc/ssh/.ssh.db |
                cut -d ' ' -f2 |
                sort -u
        )
    else
        ssh_users=()
    fi

    for user in "${ssh_users[@]}"; do
        [ -z "$user" ] && continue

        user_count=$(
            grep -w "$user" /tmp/ssh_login_user 2>/dev/null |
                wc -l
        )

        if [ "$user_count" -gt 0 ]; then
            if [ -e "/etc/ssh/${user}" ]; then
                ip_limit=$(cat "/etc/ssh/${user}" 2>/dev/null)
            else
                ip_limit="0"
            fi

            if [ -z "$ip_limit" ] || [ "$ip_limit" = "0" ]; then
                ip_limit="Tanpa Batas"
            fi

            total_ip_connect=$(
                grep -w "$user" /tmp/ssh_login_user 2>/dev/null |
                    awk '{print $3}' |
                    sort -u |
                    wc -l
            )

            if [ "$first" -eq 0 ]; then
                objects+=","
            fi

            objects+="
    {
      \"user\": \"$(json_escape "$user")\",
      \"ip_limit\": \"$(json_escape "$ip_limit")\",
      \"total_ip_connect\": \"${total_ip_connect}\"
    }"

            first=0
        fi
    done

    printf '{\n'
    printf '  "status": "success",\n'
    printf '  "brand": "%s",\n' "$BRAND"
    printf '  "protocol": "ssh",\n'
    printf '  "ip_vps": "%s",\n' "$(json_escape "$public_ip")"
    printf '  "masa_aktif_script": "%s hari",\n' "$remaining_days"

    if [ "$first" -eq 0 ]; then
        printf '  "message": "Pengecekan akun SSH berhasil.",\n'
        printf '  "data": [%s\n  ]\n' "$objects"
    else
        printf '  "message": "Tidak ada koneksi SSH aktif saat ini.",\n'
        printf '  "data": []\n'
    fi

    printf '}\n'

    rm -f \
        /tmp/ssh_login_user \
        /tmp/login-db-ssh.txt \
        /tmp/login-db-dropbear.txt \
        /tmp/login-db-pid-ssh.txt \
        /tmp/login-db-pid-dropbear.txt
}

apicheck() {
    local protocol="$1"
    local log_file="/var/log/xray/access.log"
    local db_file="/etc/xray/${protocol}/.${protocol}.db"
    local rotation_file="/tmp/rotation_${protocol}"
    local objects=""
    local first=1

    if [ ! -f "$db_file" ]; then
        printf '{\n'
        printf '  "status": "error",\n'
        printf '  "brand": "%s",\n' "$BRAND"
        printf '  "protocol": "%s",\n' "$(json_escape "$protocol")"
        printf '  "message": "Database akun %s tidak ditemukan.",\n' "$(json_escape "$protocol")"
        printf '  "data": []\n'
        printf '}\n'
        return 1
    fi

    if [ ! -f "$log_file" ]; then
        printf '{\n'
        printf '  "status": "error",\n'
        printf '  "brand": "%s",\n' "$BRAND"
        printf '  "protocol": "%s",\n' "$(json_escape "$protocol")"
        printf '  "message": "Log akses Xray tidak ditemukan.",\n'
        printf '  "data": []\n'
        printf '}\n'
        return 1
    fi

    mapfile -t users < <(
        grep '^###' "$db_file" |
            cut -d ' ' -f2 |
            sort -u
    )

    : >"$rotation_file"

    declare -A user_ips
    declare -A user_times
    declare -A user_log_counts

    for email in "${users[@]}"; do
        [ -z "$email" ] && continue

        user_logs=$(
            tail -n 150 "$log_file" |
                grep -w "email: ${email}" |
                grep -v "127.0.0.1"
        )

        user_log_counts["$email"]=$(
            grep -w "email: ${email}" "$log_file" 2>/dev/null |
                grep -v "127.0.0.1" |
                wc -l
        )

        while IFS= read -r log_entry; do
            [ -z "$log_entry" ] && continue

            read -r _ log_time log_ip _ <<<"$log_entry"

            if [[ "$log_ip" =~ ^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+(:[0-9]+)?$ ]]; then
                log_ip=${log_ip%%:*}

                log_timestamp=$(date -d "$log_time" +%s 2>/dev/null)
                current_timestamp=$(date +%s)

                [ -z "$log_timestamp" ] && continue

                time_diff=$((current_timestamp - log_timestamp))

                if [ "$time_diff" -ge 0 ] && [ "$time_diff" -lt 60 ]; then
                    if [ -n "${user_ips[$log_ip]:-}" ] &&
                        [ "${user_ips[$log_ip]}" != "$email" ]; then
                        continue
                    fi

                    user_ips["$log_ip"]="$email"
                    user_times["${email}:${log_ip}"]="$log_time"
                fi
            fi
        done <<<"$user_logs"
    done

    for log_ip in "${!user_ips[@]}"; do
        email="${user_ips[$log_ip]}"
        log_time="${user_times["${email}:${log_ip}"]}"

        echo "${email} ${log_ip} ${log_time}"
    done |
        sort -k1,1 -k3,3r \
            >"$rotation_file"

    declare -A processed_users

    if [ -s "$rotation_file" ]; then
        while IFS= read -r log_entry; do
            [ -z "$log_entry" ] && continue

            read -r email log_ip log_time <<<"$log_entry"

            [ -z "$email" ] && continue

            if [ -n "${processed_users[$email]:-}" ]; then
                continue
            fi

            processed_users["$email"]=1

            quota_file="/etc/xray/${protocol}/${email}"
            usage_file="/etc/xray/${protocol}/usage/${email}"
            ip_file="/etc/xray/${protocol}/${email}IP"

            if [ -f "$usage_file" ]; then
                usage=$(cat "$usage_file" 2>/dev/null)
            else
                usage=0
            fi

            if [ -f "$quota_file" ]; then
                quota=$(cat "$quota_file" 2>/dev/null)
            else
                quota=0
            fi

            if [ -f "$ip_file" ]; then
                ip_limit=$(cat "$ip_file" 2>/dev/null)
            else
                ip_limit=0
            fi

            usage=${usage:-0}
            quota=${quota:-0}
            ip_limit=${ip_limit:-0}

            usage_size=$(convert_size "$usage")

            if [ "$quota" = "0" ]; then
                quota_size="Tanpa Batas"
            else
                quota_size=$(convert_size "$quota")
            fi

            if [ "$ip_limit" = "0" ]; then
                ip_limit_display="Tanpa Batas"
            else
                ip_limit_display="$ip_limit"
            fi

            ip_count=$(
                awk -v target="$email" '$1 == target {print $2}' "$rotation_file" |
                    sort -u |
                    wc -l
            )

            log_count="${user_log_counts[$email]:-0}"

            if [ "$first" -eq 0 ]; then
                objects+=","
            fi

            objects+="
    {
      \"user\": \"$(json_escape "$email")\",
      \"usage\": \"$(json_escape "$usage_size")\",
      \"quota\": \"$(json_escape "$quota_size")\",
      \"ip_limit\": \"$(json_escape "$ip_limit_display")\",
      \"ip_count\": \"${ip_count}\",
      \"log_count\": \"${log_count}\"
    }"

            first=0
        done <"$rotation_file"
    fi

    printf '{\n'
    printf '  "status": "success",\n'
    printf '  "brand": "%s",\n' "$BRAND"
    printf '  "protocol": "%s",\n' "$(json_escape "$protocol")"
    printf '  "ip_vps": "%s",\n' "$(json_escape "$public_ip")"
    printf '  "tanggal": "%s",\n' "$(json_escape "$current_date")"
    printf '  "waktu": "%s",\n' "$(json_escape "$current_time")"
    printf '  "masa_aktif_script": "%s hari",\n' "$remaining_days"

    if [ "$first" -eq 0 ]; then
        printf '  "message": "Pengecekan akun %s berhasil.",\n' "$(json_escape "$protocol")"
        printf '  "data": [%s\n  ]\n' "$objects"
    else
        printf '  "message": "Tidak ada koneksi aktif saat ini.",\n'
        printf '  "data": []\n'
    fi

    printf '}\n'

    rm -f "$rotation_file"
}

case "${1:-}" in
    ssh)
        apissh
        ;;
    vmess)
        apicheck "vmess"
        ;;
    vless)
        apicheck "vless"
        ;;
    trojan)
        apicheck "trojan"
        ;;
    shadowsocks)
        apicheck "shadowsocks"
        ;;
    *)
        printf '{\n'
        printf '  "status": "error",\n'
        printf '  "brand": "%s",\n' "$BRAND"
        printf '  "message": "Perintah tidak dikenal.",\n'
        printf '  "usage": {\n'
        printf '    "ssh": "cek ssh",\n'
        printf '    "vmess": "cek vmess",\n'
        printf '    "vless": "cek vless",\n'
        printf '    "trojan": "cek trojan",\n'
        printf '    "shadowsocks": "cek shadowsocks"\n'
        printf '  },\n'
        printf '  "contact": {\n'
        printf '    "WhatsApp": "%s",\n' "$WHATSAPP"
        printf '    "Telegram": "%s"\n' "$TELEGRAM"
        printf '  }\n'
        printf '}\n'
        exit 1
        ;;
esac