#!/bin/bash

# Exit immediately if a command exits with a non-zero status
set -e

export DEBIAN_FRONTEND=noninteractive

# Text colors for console output
GREEN='\033[0;32m'
CYAN='\033[0;36m'
YELLOW='\033[1;33m'
RED='\033[0;31m'
NC='\033[0m'

# Helper function to read input interactively even when script is executed via curl pipe
prompt_read() {
    local prompt_text="$1"
    local var_name="$2"
    if [ -t 0 ]; then
        read -r -p "$prompt_text" "$var_name"
    elif [ -e /dev/tty ]; then
        read -r -p "$prompt_text" "$var_name" < /dev/tty
    else
        read -r -p "$prompt_text" "$var_name"
    fi
}

echo -e "${CYAN}======================================================${NC}"
echo -e "${CYAN}    Oracle Cloud Native WireGuard VPN Installer       ${NC}"
echo -e "${CYAN}======================================================${NC}"
echo ""

# 1. Root Check
if [[ $EUID -ne 0 ]]; then
   echo -e "${RED}[ERROR] This script must be run as root or with sudo.${NC}"
   exit 1
fi

# 2. Network Discovery
echo -e "${YELLOW}Gathering network information...${NC}"
DETECTED_IP=$(curl -s ifconfig.me || wget -qO- ifconfig.me)
prompt_read "Enter your server's Public IP address [$DETECTED_IP]: " PUBLIC_IP
PUBLIC_IP=${PUBLIC_IP:-$DETECTED_IP}

DETECTED_IFACE=$(ip -4 route show default 2>/dev/null | awk '{for(i=1;i<=NF;i++) if($i=="dev") print $(i+1)}' | head -n 1)
prompt_read "Enter your primary network interface [$DETECTED_IFACE]: " IFACE
IFACE=${IFACE:-$DETECTED_IFACE}

echo -e "${GREEN}[OK] Public IP: $PUBLIC_IP${NC}"
echo -e "${GREEN}[OK] Interface: $IFACE${NC}"
echo ""

# 3. Install Dependencies
echo -e "${YELLOW}Installing system utilities...${NC}"
apt-get update -y
DEBIAN_FRONTEND=noninteractive apt-get install -y wireguard qrencode netcat-openbsd
echo -e "${GREEN}[OK] Dependencies installed.${NC}"
echo ""

# 4. Firewall Configuration (Force Position 1 ACCEPT)
echo -e "${YELLOW}Applying Firewall Rules...${NC}"

# Clear any duplicate rules from previous attempts
while iptables -C INPUT -p udp --dport 51820 -j ACCEPT 2>/dev/null; do
    iptables -D INPUT -p udp --dport 51820 -j ACCEPT
done

# CRITICAL: Force rule to Position 1 in INPUT chain to bypass default REJECT lines
iptables -I INPUT 1 -p udp --dport 51820 -j ACCEPT

# Ensure forwarding rules are enabled
if ! iptables -C FORWARD -j ACCEPT 2>/dev/null; then
    iptables -I FORWARD 1 -j ACCEPT
fi

# Integrate with UFW if active
if command -v ufw >/dev/null 2>&1 && ufw status 2>/dev/null | grep -q "Status: active"; then
    ufw allow 51820/udp
    ufw route allow in on wg0 out on ${IFACE} 2>/dev/null || true
    ufw route allow in on ${IFACE} out on wg0 2>/dev/null || true
    if [ -f /etc/default/ufw ]; then
        sed -i 's/DEFAULT_FORWARD_POLICY="DROP"/DEFAULT_FORWARD_POLICY="ACCEPT"/' /etc/default/ufw
    fi
    ufw reload
fi
echo -e "${GREEN}[OK] Firewall rules applied.${NC}"
echo ""

# 5. Kernel Packet Forwarding
echo -e "${YELLOW}Enabling kernel packet forwarding...${NC}"
sysctl -w net.ipv4.ip_forward=1
sed -i 's/#net.ipv4.ip_forward=1/net.ipv4.ip_forward=1/' /etc/sysctl.conf
if ! grep -q "net.ipv4.ip_forward=1" /etc/sysctl.conf; then
    echo "net.ipv4.ip_forward=1" >> /etc/sysctl.conf
fi
sysctl -p
echo -e "${GREEN}[OK] Kernel forwarding enabled.${NC}"
echo ""

# 6. Keys Generation
echo -e "${YELLOW}Generating cryptographic key pairs...${NC}"
mkdir -p /etc/wireguard/keys
chmod 700 /etc/wireguard/keys
cd /etc/wireguard/keys

wg genkey | tee server_private.key | wg pubkey > server_public.key
wg genkey | tee client_private.key | wg pubkey > client_public.key

SERVER_PRIV=$(cat server_private.key)
SERVER_PUB=$(cat server_public.key)
CLIENT_PRIV=$(cat client_private.key)
CLIENT_PUB=$(cat client_public.key)
echo -e "${GREEN}[OK] Key pairs generated.${NC}"
echo ""

# 7. Write Server Config
echo -e "${YELLOW}Writing server configuration (/etc/wireguard/wg0.conf)...${NC}"
cat <<EOF > /etc/wireguard/wg0.conf
[Interface]
Address = 10.0.0.1/24
SaveConfig = false
ListenPort = 51820
PrivateKey = ${SERVER_PRIV}

PostUp = iptables -I INPUT 1 -p udp --dport 51820 -j ACCEPT; iptables -I FORWARD 1 -i wg0 -j ACCEPT; iptables -I FORWARD 1 -o wg0 -m state --state RELATED,ESTABLISHED -j ACCEPT; iptables -t nat -A POSTROUTING -o ${IFACE} -j MASQUERADE; iptables -t mangle -A POSTROUTING -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu
PostDown = iptables -D INPUT -p udp --dport 51820 -j ACCEPT 2>/dev/null || true; iptables -D FORWARD -i wg0 -j ACCEPT 2>/dev/null || true; iptables -D FORWARD -o wg0 -m state --state RELATED,ESTABLISHED -j ACCEPT 2>/dev/null || true; iptables -t nat -D POSTROUTING -o ${IFACE} -j MASQUERADE 2>/dev/null || true; iptables -t mangle -D POSTROUTING -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu 2>/dev/null || true

[Peer]
PublicKey = ${CLIENT_PUB}
AllowedIPs = 10.0.0.2/32
EOF
chmod 600 /etc/wireguard/wg0.conf
echo -e "${GREEN}[OK] Server configuration saved.${NC}"
echo ""

# 8. Write Client Config
echo -e "${YELLOW}Writing client configuration (android-client.conf)...${NC}"
cat <<EOF > /etc/wireguard/android-client.conf
[Interface]
Address = 10.0.0.2/24
PrivateKey = ${CLIENT_PRIV}
DNS = 1.1.1.1, 1.0.0.1

[Peer]
PublicKey = ${SERVER_PUB}
Endpoint = ${PUBLIC_IP}:51820
AllowedIPs = 0.0.0.0/0
PersistentKeepalive = 25
EOF
echo -e "${GREEN}[OK] Client configuration saved.${NC}"
echo ""

# 9. Start WireGuard Service
echo -e "${YELLOW}Starting WireGuard service...${NC}"
systemctl enable --now wg-quick@wg0
systemctl restart wg-quick@wg0
echo -e "${GREEN}[OK] WireGuard service started.${NC}"
echo ""

# 10. Compact QR Code Output
echo -e "${CYAN}======================================================${NC}"
echo -e "${CYAN}    Deployment Stable! Scan QR Code via WireGuard App ${NC}"
echo -e "${CYAN}======================================================${NC}"
echo ""
qrencode -t ansiutf8 -l L -m 1 < /etc/wireguard/android-client.conf
echo ""
echo -e "${YELLOW}To view runtime statistics and handshakes, execute:${NC}"
echo -e "${CYAN}sudo wg show${NC}"
echo ""

# 11. Cloud Firewall Reminder (at the very end)
echo -e "${CYAN}------------------------------------------------------${NC}"
echo -e "${YELLOW}[REMINDER] OCI / Cloud Console Ingress Rule Required:${NC}"
echo -e "Ensure your Cloud Provider VCN Ingress Rules allow:"
echo -e "  - Source: ${GREEN}0.0.0.0/0${NC}"
echo -e "  - Protocol: ${GREEN}UDP${NC}"
echo -e "  - Destination Port: ${GREEN}51820${NC}"
echo -e "${CYAN}------------------------------------------------------${NC}"