#!/usr/bin/env bash

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

green="\e[38;5;82m"
red="\e[38;5;196m"
neutral="\e[0m"
orange="\e[38;5;130m"
blue="\e[38;5;39m"
yellow="\e[38;5;226m"
white="\e[38;5;255m"
bold_white="\e[1;37m"

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" "$neutral"
}

box_middle() {
    update_box_width

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

box_bottom() {
    update_box_width

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

box_center() {
    update_box_width

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

    if [ "$length" -gt "$available" ]; then
        printf "%b│%b %b%s%b %b│%b\n" \
            "$orange" \
            "$neutral" \
            "$color" \
            "$text" \
            "$neutral" \
            "$orange" \
            "$neutral"
        return
    fi

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

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

box_left() {
    update_box_width

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

    if [ "$length" -gt "$available" ]; then
        printf "%b│%b %b%s%b %b│%b\n" \
            "$orange" \
            "$neutral" \
            "$color" \
            "$text" \
            "$neutral" \
            "$orange" \
            "$neutral"
        return
    fi

    local right=$((available - length))

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

print_color() {
    local color_code="$1"
    local message="$2"

    printf "\033[1;%sm%b\033[0m\n" "$color_code" "$message"
}

_info() {
    print_color "32" "[INFO] $1"
}

_warn() {
    print_color "33" "[PERINGATAN] $1"
}

_error() {
    print_color "31" "[ERROR] $1"
    exit 1
}

_exists() {
    command -v "$1" >/dev/null 2>&1
}

_os() {
    [ -f "/etc/os-release" ] &&
        source /etc/os-release &&
        echo "${ID}"
}

_os_full() {
    [ -f /etc/os-release ] &&
        awk -F'[= "]' '/PRETTY_NAME/{print $3,$4,$5}' /etc/os-release
}

_os_ver() {
    local main_ver

    main_ver="$(echo "$(_os_full)" | grep -oE "[0-9.]+" | head -1)"

    echo "${main_ver%%.*}"
}

_error_detect() {
    _info "$1"

    eval "$1"

    if [ $? -ne 0 ]; then
        _error "Perintah ($1) gagal dijalankan. Silakan periksa dan coba kembali."
    fi
}

_is_64bit() {
    [ "$(getconf LONG_BIT)" = "64" ]
}

_version_ge() {
    test "$(echo "$@" | tr " " "\n" | sort -rV | head -n 1)" == "$1"
}

get_latest_version() {
    latest_version=(
        $(
            wget -qO- https://kernel.ubuntu.com/~kernel-ppa/mainline/ |
                awk -F'\"v' '/v[4-9]./{print $2}' |
                cut -d/ -f1 |
                grep -v - |
                sort -V
        )
    )

    if [ ${#latest_version[@]} -eq 0 ]; then
        _error "Gagal mendapatkan versi kernel terbaru."
    fi

    kernel_arr=()

    for i in "${latest_version[@]}"; do
        if _version_ge "$i" 5.15; then
            kernel_arr+=("$i")
        fi
    done

    if [ ${#kernel_arr[@]} -eq 0 ]; then
        _error "Kernel versi 5.15 atau lebih baru tidak ditemukan."
    fi

    kernel="${kernel_arr[-1]}"

    _info "Kernel terbaru yang ditemukan: $kernel"

    if _is_64bit; then
        deb_name=$(
            wget -qO- \
                "https://kernel.ubuntu.com/~kernel-ppa/mainline/v${kernel}/" |
                grep "linux-image" |
                grep "generic" |
                awk -F'\">' '/amd64.deb/{print $2}' |
                cut -d'<' -f1 |
                head -1
        )

        deb_kernel_url="https://kernel.ubuntu.com/~kernel-ppa/mainline/v${kernel}/${deb_name}"
        deb_kernel_name="linux-image-${kernel}-amd64.deb"

        modules_deb_name=$(
            wget -qO- \
                "https://kernel.ubuntu.com/~kernel-ppa/mainline/v${kernel}/" |
                grep "linux-modules" |
                grep "generic" |
                awk -F'\">' '/amd64.deb/{print $2}' |
                cut -d'<' -f1 |
                head -1
        )

        deb_kernel_modules_url="https://kernel.ubuntu.com/~kernel-ppa/mainline/v${kernel}/${modules_deb_name}"
        deb_kernel_modules_name="linux-modules-${kernel}-amd64.deb"
    else
        deb_name=$(
            wget -qO- \
                "https://kernel.ubuntu.com/~kernel-ppa/mainline/v${kernel}/" |
                grep "linux-image" |
                grep "generic" |
                awk -F'\">' '/i386.deb/{print $2}' |
                cut -d'<' -f1 |
                head -1
        )

        deb_kernel_url="https://kernel.ubuntu.com/~kernel-ppa/mainline/v${kernel}/${deb_name}"
        deb_kernel_name="linux-image-${kernel}-i386.deb"

        modules_deb_name=$(
            wget -qO- \
                "https://kernel.ubuntu.com/~kernel-ppa/mainline/v${kernel}/" |
                grep "linux-modules" |
                grep "generic" |
                awk -F'\">' '/i386.deb/{print $2}' |
                cut -d'<' -f1 |
                head -1
        )

        deb_kernel_modules_url="https://kernel.ubuntu.com/~kernel-ppa/mainline/v${kernel}/${modules_deb_name}"
        deb_kernel_modules_name="linux-modules-${kernel}-i386.deb"
    fi

    if [ -z "${deb_name}" ]; then
        _error "Gagal mendapatkan paket binary kernel Linux. Kemungkinan proses build kernel gagal."
    fi

    if [ -z "${modules_deb_name}" ]; then
        _error "Gagal mendapatkan paket modul kernel Linux."
    fi
}

check_bbr_status() {
    [ "$(sysctl net.ipv4.tcp_congestion_control 2>/dev/null | awk '{print $3}')" == "bbr" ]
}

check_kernel_version() {
    _version_ge "$(uname -r | cut -d- -f1)" 4.9
}

check_os() {
    local os

    os=$(_os)

    if [ -z "$os" ]; then
        _error "Sistem operasi tidak didukung."
    fi

    case "$os" in
        ubuntu)
            if [ "$(_os_ver)" -lt 16 ]; then
                _error "Ubuntu tidak didukung. Gunakan Ubuntu 16 atau lebih baru."
            fi
            ;;
        debian)
            if [ "$(_os_ver)" -lt 8 ]; then
                _error "Debian tidak didukung. Gunakan Debian 8 atau lebih baru."
            fi
            ;;
        *)
            _error "Sistem operasi tidak didukung."
            ;;
    esac
}

sysctl_config() {
    _info "Mengatur konfigurasi TCP BBR..."

    sed -i '/net.core.default_qdisc/d' /etc/sysctl.conf
    sed -i '/net.ipv4.tcp_congestion_control/d' /etc/sysctl.conf

    echo "net.core.default_qdisc = fq" >>/etc/sysctl.conf
    echo "net.ipv4.tcp_congestion_control = bbr" >>/etc/sysctl.conf

    sysctl -p >/dev/null 2>&1

    if check_bbr_status; then
        _info "TCP BBR berhasil diaktifkan."
    else
        _warn "Konfigurasi BBR telah ditambahkan tetapi BBR belum aktif."
    fi
}

install_kernel() {
    case "$(_os)" in
        ubuntu|debian)
            _info "Mencari versi kernel terbaru..."

            get_latest_version

            _info "Mengunduh modul kernel ${kernel}..."

            _error_detect "wget -c -t3 -T60 -O '${deb_kernel_modules_name}' '${deb_kernel_modules_url}'"

            _info "Mengunduh kernel ${kernel}..."

            _error_detect "wget -c -t3 -T60 -O '${deb_kernel_name}' '${deb_kernel_url}'"

            _info "Memasang kernel ${kernel}..."

            _error_detect "dpkg -i '${deb_kernel_modules_name}' '${deb_kernel_name}'"

            rm -f \
                "${deb_kernel_modules_name}" \
                "${deb_kernel_name}"

            _info "Memperbarui konfigurasi GRUB..."

            _error_detect "/usr/sbin/update-grub"

            _info "Kernel baru berhasil dipasang."
            ;;
    esac
}

install_bbr() {
    if check_bbr_status; then
        _info "TCP BBR sudah aktif. Tidak ada perubahan yang diperlukan."
        return 0
    fi

    check_os

    if check_kernel_version; then
        _info "Versi kernel sudah mendukung TCP BBR."

        sysctl_config

        if check_bbr_status; then
            _info "Pengaktifan TCP BBR selesai."
            return 0
        fi

        _warn "BBR belum aktif pada kernel saat ini."
    fi

    _warn "Kernel saat ini belum dapat mengaktifkan BBR secara langsung."

    install_kernel

    sysctl_config

    _warn "Kernel baru telah dipasang. Reboot server diperlukan untuk menggunakan kernel terbaru."
}

if [[ $EUID -ne 0 ]]; then
    clear

    box_top
    box_center "INTERFLAZZ.MY.ID" "$green"
    box_center "AUTOSCRIPT PREMIUM" "$bold_white"
    box_middle
    box_center "AKSES DITOLAK" "$red"
    box_middle
    box_center "Script harus dijalankan sebagai root." "$yellow"
    box_bottom

    exit 1
fi

opsy=$(_os_full)
arch=$(uname -m)
lbit=$(getconf LONG_BIT)
kern=$(uname -r)

clear

box_top
box_center "INTERFLAZZ.MY.ID" "$green"
box_center "AUTOSCRIPT PREMIUM" "$bold_white"
box_middle
box_center "OPTIMASI TCP BBR" "$yellow"
box_middle
box_left "Sistem Operasi : $opsy" "$white"
box_left "Arsitektur      : $arch ($lbit Bit)" "$white"
box_left "Kernel          : $kern" "$white"
box_middle
box_center "Mengaktifkan TCP BBR secara otomatis" "$blue"
box_middle
box_left "WhatsApp ~ https://wa.me/6285956131443" "$green"
box_left "Telegram ~ https://t.me/interflazz" "$blue"
box_bottom

echo ""

install_bbr 2>&1 | tee /etc/xray/install_bbr.log

echo ""

if check_bbr_status; then
    box_top
    box_center "INTERFLAZZ.MY.ID" "$green"
    box_middle
    box_center "TCP BBR BERHASIL DIAKTIFKAN" "$green"
    box_middle
    box_left "Congestion Control : bbr" "$green"
    box_left "Queue Discipline   : fq" "$green"
    box_left "Kernel              : $(uname -r)" "$white"
    box_middle
    box_center "Optimasi jaringan telah selesai." "$white"
    box_bottom
else
    box_top
    box_center "INTERFLAZZ.MY.ID" "$green"
    box_middle
    box_center "KERNEL BARU TELAH DIPASANG" "$yellow"
    box_middle
    box_center "Reboot diperlukan untuk mengaktifkan" "$white"
    box_center "kernel baru dan TCP BBR." "$white"
    box_middle
    box_left "Kernel Saat Ini : $(uname -r)" "$white"
    box_left "WhatsApp ~ https://wa.me/6285956131443" "$green"
    box_left "Telegram ~ https://t.me/interflazz" "$blue"
    box_bottom
fi