#!/bin/bash

BASE_URL="https://autoscript.interflazz.my.id/v2"
BRAND="INTERFLAZZ.MY.ID"
WHATSAPP="https://wa.me/6285956131443"
TELEGRAM="https://t.me/interflazz"

green="\e[38;5;82m"
red="\e[38;5;196m"
yellow="\e[38;5;226m"
cyan="\e[38;5;51m"
white="\e[97m"
orange="\e[38;5;130m"
bold_white="\e[1;37m"
reset="\e[0m"

INTERVAL_MINUTES="${1:-1}"

TMP_LOGIN="/tmp/ssh_log_limit"
TMP_SSH="/tmp/login-db-ssh.txt"
TMP_DROPBEAR="/tmp/login-db-dropbear.txt"
TMP_SSH_PID="/tmp/login-db-pid-ssh.txt"
TMP_DROPBEAR_PID="/tmp/login-db-pid-dropbear.txt"
STATE_DIR="/tmp/interflazz_limitipssh"

update_box_width() {
    local cols

    cols=$(tput cols 2>/dev/null || echo 80)

    if [ "$cols" -gt 72 ]; then
        BOX_WIDTH=72
    elif [ "$cols" -lt 30 ]; then
        BOX_WIDTH=30
    else
        BOX_WIDTH=$((cols - 2))
    fi

    BOX_INNER=$((BOX_WIDTH - 4))
}

repeat_char() {
    local count="$1"
    local char="$2"
    local line

    printf -v line '%*s' "$count" ""
    printf '%s' "${line// /$char}"
}

box_top() {
    update_box_width

    printf "%b┌" "$orange"
    repeat_char $((BOX_WIDTH - 2)) "─"
    printf "┐%b\n" "$reset"
}

box_middle() {
    update_box_width

    printf "%b├" "$orange"
    repeat_char $((BOX_WIDTH - 2)) "─"
    printf "┤%b\n" "$reset"
}

box_bottom() {
    update_box_width

    printf "%b└" "$orange"
    repeat_char $((BOX_WIDTH - 2)) "─"
    printf "┘%b\n" "$reset"
}

box_center() {
    update_box_width

    local text="$1"
    local color="${2:-$white}"
    local length=${#text}
    local available="$BOX_INNER"

    if [ "$length" -gt "$available" ]; then
        box_left "$text" "$color"
        return
    fi

    local left=$(((available - length) / 2))
    local right=$((available - length - left))

    printf "%b│%b " "$orange" "$reset"
    printf "%*s" "$left" ""
    printf "%b%s%b" "$color" "$text" "$reset"
    printf "%*s" "$right" ""
    printf " %b│%b\n" "$orange" "$reset"
}

box_left() {
    update_box_width

    local text="$1"
    local color="${2:-$white}"
    local available="$BOX_INNER"
    local length=${#text}
    local offset=0
    local part
    local part_length
    local right

    if [ "$length" -eq 0 ]; then
        printf "%b│%b" "$orange" "$reset"
        printf "%*s" $((BOX_WIDTH - 2)) ""
        printf "%b│%b\n" "$orange" "$reset"
        return
    fi

    while [ "$offset" -lt "$length" ]; do
        part="${text:$offset:$available}"
        part_length=${#part}
        right=$((available - part_length))

        printf "%b│%b " "$orange" "$reset"
        printf "%b%s%b" "$color" "$part" "$reset"
        printf "%*s" "$right" ""
        printf " %b│%b\n" "$orange" "$reset"

        offset=$((offset + available))
    done
}

show_access_denied() {
    local reason="$1"

    clear

    box_top
    box_center "$BRAND" "$green"
    box_center "AUTOSCRIPT PREMIUM" "$bold_white"
    box_middle
    box_center "AKSES DITOLAK!" "$red"
    box_middle
    box_left "IP VPS : $vps_ip" "$yellow"
    box_left "$reason" "$yellow"
    box_middle
    box_center "HUBUNGI ADMIN" "$bold_white"
    box_left "WhatsApp ~ $WHATSAPP" "$green"
    box_left "Telegram ~ $TELEGRAM" "$cyan"
    box_bottom

    exit 1
}

cleanup_temp() {
    rm -f \
        "$TMP_LOGIN" \
        "$TMP_SSH" \
        "$TMP_DROPBEAR" \
        "$TMP_SSH_PID" \
        "$TMP_DROPBEAR_PID"
}

send_telegram() {
    local user="$1"
    local ip_count="$2"
    local ip_limit="$3"
    local ip_list="$4"
    local message

    if [ -z "${bot_token:-}" ] || [ -z "${telegram_id:-}" ]; then
        return
    fi

    message="<b>━━━━━━━━━━━━━━━━━━</b>
<b>🔔 INTERFLAZZ.MY.ID</b>
<b>🚫 SSH MULTI LOGIN</b>
<b>━━━━━━━━━━━━━━━━━━</b>
<b>👤 Username :</b> <code>${user}</code>
<b>📊 Total IP :</b> <code>${ip_count}</code>
<b>🔒 Batas IP :</b> <code>${ip_limit}</code>
<b>🌐 Daftar IP :</b>
<code>${ip_list}</code>
<b>━━━━━━━━━━━━━━━━━━</b>"

    curl -s \
        --max-time 15 \
        -X POST \
        "https://api.telegram.org/bot${bot_token}/sendMessage" \
        --data-urlencode "chat_id=${telegram_id}" \
        --data-urlencode "parse_mode=HTML" \
        --data-urlencode "text=${message}" \
        >/dev/null 2>&1
}

detect_log_file() {
    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
        LOG_FILE=""
    fi
}

tampilkan_info_pengguna() {
    local file="$1"
    local user
    local ip_count
    local ip_limit
    local ip_list
    local state_file
    local current_state
    local previous_state

    if [ ! -f "/etc/ssh/.ssh.db" ]; then
        return
    fi

    mapfile -t user_list < <(
        grep '^### ' /etc/ssh/.ssh.db 2>/dev/null |
            awk '{print $2}' |
            sort -u
    )

    if [ ! -s "$file" ]; then
        return
    fi

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

        ip_count=$(
            awk -v target="$user" '$2 == target {print $3}' "$file" |
                sort -u |
                grep -c .
        )

        ip_limit=$(cat "/etc/ssh/${user}" 2>/dev/null)

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

        state_file="${STATE_DIR}/${user}"

        if [ "$ip_limit" -ne 0 ] && [ "$ip_count" -gt "$ip_limit" ]; then
            ip_list=$(
                awk -v target="$user" '$2 == target {print $3}' "$file" |
                    sort -u
            )

            current_state="${ip_count}:${ip_limit}:$(echo "$ip_list" | tr '\n' ',')"
            previous_state=$(cat "$state_file" 2>/dev/null)

            echo "$(date '+%Y-%m-%d %H:%M:%S') | SSH | ${user} | IP ${ip_count}/${ip_limit} | $(echo "$ip_list" | tr '\n' ' ')" \
                >>/var/log/xray/ip_limit.log

            if [ "$current_state" != "$previous_state" ]; then
                send_telegram "$user" "$ip_count" "$ip_limit" "$ip_list"
                printf '%s\n' "$current_state" >"$state_file"
            fi
        else
            rm -f "$state_file"
        fi
    done
}

tampilkan_info_ssh_dropbear() {
    local ssh_pid
    local ssh_user
    local ssh_ip
    local dropbear_pid
    local dropbear_user
    local dropbear_ip

    cleanup_temp

    touch "$TMP_LOGIN"

    grep -i "sshd" "$LOG_FILE" 2>/dev/null |
        grep -i "Accepted password for" \
        >"$TMP_SSH"

    grep -i "dropbear" "$LOG_FILE" 2>/dev/null |
        grep -i "Password auth succeeded" \
        >"$TMP_DROPBEAR"

    mapfile -t ssh_pids < <(
        pgrep sshd 2>/dev/null
    )

    mapfile -t dropbear_pids < <(
        pgrep dropbear 2>/dev/null
    )

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

        if grep -q "sshd\[$ssh_pid\]" "$TMP_SSH" 2>/dev/null; then
            grep "sshd\[$ssh_pid\]" "$TMP_SSH" >"$TMP_SSH_PID"

            ssh_user=$(
                sed -nE 's/.*Accepted password for ([^ ]+) from.*/\1/p' \
                    "$TMP_SSH_PID" |
                    tail -1
            )

            ssh_ip=$(
                sed -nE 's/.* from ([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+).*/\1/p' \
                    "$TMP_SSH_PID" |
                    tail -1
            )

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

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

        if grep -q "dropbear\[$dropbear_pid\]" "$TMP_DROPBEAR" 2>/dev/null; then
            grep "dropbear\[$dropbear_pid\]" "$TMP_DROPBEAR" >"$TMP_DROPBEAR_PID"

            dropbear_user=$(
                sed -nE "s/.*Password auth succeeded for '([^']+)'.*/\1/p" \
                    "$TMP_DROPBEAR_PID" |
                    tail -1
            )

            dropbear_ip=$(
                sed -nE "s/.* from ([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+).*/\1/p" \
                    "$TMP_DROPBEAR_PID" |
                    tail -1
            )

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

    if [ -s "$TMP_LOGIN" ]; then
        sort -u "$TMP_LOGIN" -o "$TMP_LOGIN"
    fi

    tampilkan_info_pengguna "$TMP_LOGIN"
}

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

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

if [ -z "$vps_ip" ]; then
    vps_ip="Tidak diketahui"
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_date=$(date +%s)

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

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

if ! [[ "$INTERVAL_MINUTES" =~ ^[0-9]+$ ]] || [ "$INTERVAL_MINUTES" -lt 1 ]; then
    INTERVAL_MINUTES=1
fi

detect_log_file

if [ -z "$LOG_FILE" ]; then
    clear

    box_top
    box_center "$BRAND" "$green"
    box_center "LIMIT IP SSH" "$bold_white"
    box_middle
    box_center "FILE LOG TIDAK DITEMUKAN" "$red"
    box_middle
    box_left "Tidak ditemukan /var/log/auth.log atau /var/log/secure." "$yellow"
    box_bottom

    exit 1
fi

mkdir -p "$STATE_DIR"
mkdir -p /var/log/xray
touch /var/log/xray/ip_limit.log

if [ ! -f "/root/.vars" ]; then
    clear

    box_top
    box_center "$BRAND" "$green"
    box_center "LIMIT IP SSH" "$bold_white"
    box_middle
    box_center "KONFIGURASI BOT BELUM TERSEDIA" "$yellow"
    box_middle
    box_left "File /root/.vars tidak ditemukan." "$white"
    box_left "Silakan konfigurasi Telegram Bot terlebih dahulu." "$white"
    box_middle
    box_left "WhatsApp ~ $WHATSAPP" "$green"
    box_left "Telegram ~ $TELEGRAM" "$cyan"
    box_bottom

    exit 1
fi

source /root/.vars

if [ -z "${bot_token:-}" ] || [ -z "${telegram_id:-}" ]; then
    clear

    box_top
    box_center "$BRAND" "$green"
    box_center "LIMIT IP SSH" "$bold_white"
    box_middle
    box_center "KONFIGURASI TELEGRAM TIDAK LENGKAP" "$red"
    box_middle
    box_left "bot_token atau telegram_id belum dikonfigurasi." "$yellow"
    box_bottom

    exit 1
fi

trap cleanup_temp EXIT INT TERM

while true; do
    tampilkan_info_ssh_dropbear
    cleanup_temp
    sleep "${INTERVAL_MINUTES}m"
done