#!/usr/bin/env bash
set -euo pipefail

SCRIPT_DIR="/data/bbr"
JOEY_REPO="$SCRIPT_DIR/joey-bbr-kernel"
WORKDIR="$SCRIPT_DIR/kernel-build"
KERNEL_SRC="$WORKDIR/linux-7.1.8"
KERNEL_VERSION="7.1.8"
KERNEL_ARCH="${1:-x86_64}"
BUILD_MAX="${2:-false}"

case "$KERNEL_ARCH" in
    x86_64)   DEB_ARCH="amd64"  ; CROSS="" ;;
    arm64)    DEB_ARCH="arm64"  ; CROSS="ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu-" ;;
    *) echo "Bad arch"; exit 1 ;;
esac

BRANCH="7.1"
PATCH_FILE="$JOEY_REPO/patches/bbrv3-linux-$BRANCH.patch"

if [ "$BUILD_MAX" = "true" ]; then
    LOCALVERSION="-joeyblog-bbrv3-max"
else
    LOCALVERSION="-joeyblog-bbrv3"
fi

echo "=== Joey BBRv3 Kernel Build ==="
echo "Version: $KERNEL_VERSION  Arch: $KERNEL_ARCH  Max: $BUILD_MAX"

# Init git repo in source (needed for git apply)
cd "$KERNEL_SRC"
if [ ! -f .git/index ]; then
    git init
    git add -A
    git commit -m "base" --no-gpg-sign 2>/dev/null
fi

# Apply BBRv3 patch
echo "[1/5] Applying BBRv3 patch..."
if git apply --check "$PATCH_FILE" 2>/dev/null; then
    git apply "$PATCH_FILE"
else
    patch -p1 --forward --fuzz=3 < "$PATCH_FILE" || { echo "PATCH FAILED"; exit 1; }
fi
grep -q 'BBR_VERSION.*3' net/ipv4/tcp_bbr.c || { echo "BBR VERIFY FAIL"; exit 1; }
echo "  OK"

# Max profile
if [ "$BUILD_MAX" = "true" ]; then
    echo "[2/5] Max profile..."
    bash "$JOEY_REPO/scripts/apply-bbrv3-max-profile.sh"
fi

# Config
echo "[3/5] Config with L2TP+VPN..."
case "$KERNEL_ARCH" in
    arm64) cp "$JOEY_REPO/arm64.config" .config ;;
    x86_64) cp "$JOEY_REPO/x86-64.config" .config ;;
esac

kc() { scripts/config "$@"; }

kc --disable SYSTEM_TRUSTED_KEYS
kc --disable SYSTEM_REVOCATION_KEYS
kc --enable TCP_CONG_BBR && kc --disable DEFAULT_CUBIC
kc --enable DEFAULT_BBR && kc --set-str DEFAULT_TCP_CONG bbr
kc --enable NET_SCH_DEFAULT && kc --enable NET_SCH_FQ
kc --module NET_SCH_FQ_CODEL && kc --module NET_SCH_PIE
kc --module NET_SCH_FQ_PIE && kc --module NET_SCH_CAKE
kc --disable DEFAULT_FQ_CODEL && kc --disable DEFAULT_PFIFO_FAST
kc --enable DEFAULT_FQ && kc --set-str DEFAULT_NET_SCH fq
kc --module NETFILTER_XTABLES && kc --enable NETFILTER_XTABLES_LEGACY
kc --module IP_NF_IPTABLES_LEGACY && kc --module IP_NF_FILTER
kc --module IP_NF_NAT && kc --module IP_NF_TARGET_MASQUERADE
kc --module IP_NF_MANGLE && kc --module IP_NF_RAW
kc --module IP6_NF_IPTABLES_LEGACY && kc --module IP6_NF_FILTER
kc --module IP6_NF_NAT && kc --module IP6_NF_MANGLE && kc --module IP6_NF_RAW
kc --disable DEBUG_INFO && kc --enable DEBUG_INFO_NONE
kc --disable DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT
kc --disable DEBUG_INFO_DWARF4 && kc --disable DEBUG_INFO_DWARF5
kc --disable DEBUG_INFO_REDUCED && kc --disable DEBUG_INFO_COMPRESSED
kc --disable DEBUG_INFO_SPLIT && kc --disable DEBUG_INFO_BTF
kc --disable DEBUG_INFO_BTF_MODULES && kc --disable MODULE_ALLOW_BTF_MISMATCH
kc --disable AFS_FS && kc --disable AF_RXRPC && kc --disable RXKAD

# L2TP + VPN additions (all modules)
echo "  Adding L2TP+VPN..."
for mod in XFRM_USER XFRM_ALGO XFRM_ESP INET_ESP INET6_ESP XFRM_IPCOMP \
    INET_XFRM_MODE_TRANSPORT INET_XFRM_MODE_TUNNEL INET_XFRM_MODE_BEET \
    INET6_XFRM_MODE_TRANSPORT INET6_XFRM_MODE_TUNNEL INET6_XFRM_MODE_BEET \
    XFRM_STATISTICS INET_AH INET6_AH \
    L2TP L2TP_DEBUGFS L2TP_V3 L2TP_IP L2TP_ETH \
    PPP PPP_ASYNC PPP_SYNC_TTY PPP_DEFLATE PPP_BSDCOMP \
    PPP_MPPE PPPOE PPTP PPPOL2TP PPPOLAC PPPOPNS PPP_MULTILINK \
    TUN TAP WIREGUARD \
    NET_IPGRE_DEMUX NET_IPGRE NET_IPGRE_BROADCAST NET_IPIP \
    IPV6_TUNNEL IPV6_GRE NET_FOU NET_FOU_IP_TUNNELS GENEVE VXLAN \
    NET_KEY NET_KEY_MIGRATE \
    CRYPTO_CBC CRYPTO_CTR CRYPTO_SHA256 CRYPTO_SHA512 \
    CRYPTO_AES CRYPTO_DES CRYPTO_HMAC CRYPTO_ARC4 CRYPTO_SHA1 \
    CRYPTO_AEAD CRYPTO_GCM CRYPTO_AUTHENC \
    BRIDGE BRIDGE_NETFILTER VLAN_8021Q \
    NET_SCH_MULTIQ NET_SCH_HTB NET_SCH_HFSC NET_SCH_PRIO \
    NF_CONNTRACK NF_CONNTRACK_FTP NF_CONNTRACK_SIP NF_CONNTRACK_PPTP \
    NF_NAT NF_NAT_FTP NF_NAT_SIP NF_NAT_PPTP \
    IP_NF_TARGET_REDIRECT \
    NETFILTER_XT_MATCH_CONNTRACK NETFILTER_XT_MATCH_STATE \
    NETFILTER_XT_MATCH_MULTIPORT NETFILTER_XT_MATCH_TCPMSS \
    NETFILTER_XT_TARGET_TCPMSS NETFILTER_XT_MATCH_OWNER; do
    kc --module "$mod" 2>/dev/null || true
done

# olddefconfig x2
echo "  olddefconfig pass 1..."
eval "timeout 300 make $CROSS olddefconfig < /dev/null"
kc --enable TCP_CONG_BBR && kc --enable DEFAULT_BBR
kc --enable DEFAULT_FQ && kc --enable NET_SCH_FQ
kc --disable DEBUG_INFO && kc --enable DEBUG_INFO_NONE
kc --disable DEBUG_INFO_BTF
kc --module L2TP && kc --module PPPOL2TP && kc --module PPTP && kc --module PPPOE
kc --module PPP_MPPE && kc --module WIREGUARD && kc --module TUN
kc --module XFRM_ESP && kc --module INET_ESP && kc --module INET6_ESP
kc --module NET_KEY
echo "  olddefconfig pass 2..."
eval "timeout 300 make $CROSS olddefconfig < /dev/null"

# Validate
echo "  Validating..."
for pair in \
    'CONFIG_TCP_CONG_BBR=y:BBR' \
    'CONFIG_L2TP=m:L2TP' \
    'CONFIG_PPPOL2TP=m:PPPoL2TP' \
    'CONFIG_PPTP=m:PPTP' \
    'CONFIG_WIREGUARD=m:WireGuard' \
    'CONFIG_TUN=m:TUN' \
    'CONFIG_XFRM_ESP=m:ESP' \
    'CONFIG_INET_ESP=m:IPv4ESP'; do
    pat="${pair%%:*}"; desc="${pair##*:}"
    grep -q "$pat" .config && echo "    [OK] $desc" || echo "    [WARN] $desc MISSING"
done

mkdir -p "$WORKDIR/build-configs"
cp .config "$WORKDIR/build-configs/${KERNEL_ARCH}-${KERNEL_VERSION}.config"

# Build
echo "[4/5] Building kernel... (logging to $WORKDIR/build-${KERNEL_ARCH}.log)"
eval "make $CROSS bindeb-pkg -j$(nproc) LOCALVERSION=$LOCALVERSION KDEB_COMPRESS=gzip skipdbg=true" > "$WORKDIR/build-${KERNEL_ARCH}.log" 2>&1 &
BUILD_PID=$!
echo "  Build PID: $BUILD_PID"

# Monitor build progress
echo "  Monitoring build..."
while kill -0 $BUILD_PID 2>/dev/null; do
    tail -1 "$WORKDIR/build-${KERNEL_ARCH}.log" 2>/dev/null | tr '\n' '\r'
    sleep 5
done

wait $BUILD_PID
BUILD_RC=$?

if [ $BUILD_RC -ne 0 ]; then
    echo "BUILD FAILED (exit code: $BUILD_RC)"
    tail -30 "$WORKDIR/build-${KERNEL_ARCH}.log"
    exit 1
fi

echo "[5/5] Done!"
find "$WORKDIR" -maxdepth 2 -name 'linux-*.deb' | sort
echo ""
echo "Config: $WORKDIR/build-configs/${KERNEL_ARCH}-${KERNEL_VERSION}.config"
