#!/bin/bash
#
# Transparent Proxy Script for Gateway (192.168.1.100)
# Routes traffic from LAN clients (192.168.1.111) through Clash proxy
#
# Usage:
#   ./tproxy.sh on      # Enable transparent proxy
#   ./tproxy.sh off     # Disable transparent proxy
#   ./tproxy.sh status  # Check status
#
# Prerequisites:
#   - Clash running with allow-lan: true
#   - This machine is the gateway for 192.168.1.111
#

set -e

# ============================================
# Configuration
# ============================================
# Clash proxy ports
CLASH_HTTP_PORT="${CLASH_HTTP_PORT:-7890}"
CLASH_SOCKS_PORT="${CLASH_SOCKS_PORT:-7891}"
CLASH_REDIR_PORT="${CLASH_REDIR_PORT:-7892}"
CLASH_TPROXY_PORT="${CLASH_TPROXY_PORT:-7893}"
CLASH_DNS_PORT="${CLASH_DNS_PORT:-1053}"

# Network configuration
LAN_INTERFACE="${LAN_INTERFACE:-eth0}"
LAN_SUBNET="${LAN_SUBNET:-192.168.1.0/24}"
GATEWAY_IP="${GATEWAY_IP:-192.168.1.100}"

# Clients to proxy (space-separated)
PROXY_CLIENTS="${PROXY_CLIENTS:-192.168.1.111}"

# Bypass destinations (don't proxy these)
BYPASS_IPS="127.0.0.0/8 10.0.0.0/8 172.16.0.0/12 192.168.0.0/16 224.0.0.0/4 240.0.0.0/4"

# iptables chain name
CHAIN_NAME="CLASH_TPROXY"

# Colors
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'

log_info() { echo -e "${GREEN}[INFO]${NC} $1"; }
log_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; }
log_error() { echo -e "${RED}[ERROR]${NC} $1"; }

# ============================================
# Check Prerequisites
# ============================================
check_root() {
    if [ "$EUID" -ne 0 ]; then
        log_error "This script must be run as root"
        exit 1
    fi
}

check_clash() {
    # Check for any clash process (clash, clash-linux-amd64, etc.)
    if ! pgrep -f "clash" > /dev/null 2>&1; then
        log_error "Clash is not running"
        log_info "Please start Clash first"
        exit 1
    fi

    # Check if Clash is listening on redir port
    if ! ss -tlnp | grep -q ":$CLASH_REDIR_PORT"; then
        log_warn "Clash redir port ($CLASH_REDIR_PORT) not listening"
        log_info "Make sure your Clash config has:"
        echo "  redir-port: $CLASH_REDIR_PORT"
        echo "  allow-lan: true"
    fi
}

# ============================================
# Enable Transparent Proxy
# ============================================
enable_tproxy() {
    check_root
    check_clash

    log_info "Enabling transparent proxy..."

    # Enable IP forwarding
    log_info "Enabling IP forwarding..."
    echo 1 > /proc/sys/net/ipv4/ip_forward
    sysctl -w net.ipv4.ip_forward=1 > /dev/null

    # Make IP forwarding persistent
    if ! grep -q "net.ipv4.ip_forward=1" /etc/sysctl.conf; then
        echo "net.ipv4.ip_forward=1" >> /etc/sysctl.conf
    fi

    # Create NAT chain for transparent proxy
    log_info "Creating iptables rules..."

    # Remove existing rules if any
    iptables -t nat -D PREROUTING -j $CHAIN_NAME 2>/dev/null || true
    iptables -t nat -F $CHAIN_NAME 2>/dev/null || true
    iptables -t nat -X $CHAIN_NAME 2>/dev/null || true

    # Create new chain
    iptables -t nat -N $CHAIN_NAME

    # Bypass local and private networks
    for ip in $BYPASS_IPS; do
        iptables -t nat -A $CHAIN_NAME -d $ip -j RETURN
    done

    # Bypass traffic to this gateway itself
    iptables -t nat -A $CHAIN_NAME -d $GATEWAY_IP -j RETURN

    # Only proxy traffic from specified clients
    for client in $PROXY_CLIENTS; do
        log_info "Adding proxy rule for client: $client"
        # Redirect HTTP/HTTPS traffic to Clash redir port
        iptables -t nat -A $CHAIN_NAME -s $client -p tcp --dport 80 -j REDIRECT --to-ports $CLASH_REDIR_PORT
        iptables -t nat -A $CHAIN_NAME -s $client -p tcp --dport 443 -j REDIRECT --to-ports $CLASH_REDIR_PORT
        # Redirect all other TCP traffic
        iptables -t nat -A $CHAIN_NAME -s $client -p tcp -j REDIRECT --to-ports $CLASH_REDIR_PORT
    done

    # Apply the chain to PREROUTING
    iptables -t nat -A PREROUTING -j $CHAIN_NAME

    # Setup DNS redirect (optional - redirect DNS to Clash DNS)
    if ss -ulnp | grep -q ":$CLASH_DNS_PORT"; then
        log_info "Setting up DNS redirect to Clash DNS..."
        for client in $PROXY_CLIENTS; do
            iptables -t nat -A PREROUTING -s $client -p udp --dport 53 -j REDIRECT --to-ports $CLASH_DNS_PORT
        done
    fi

    # Ensure MASQUERADE for forwarded traffic
    iptables -t nat -A POSTROUTING -s $LAN_SUBNET -o $LAN_INTERFACE -j MASQUERADE 2>/dev/null || true

    log_info "Transparent proxy enabled!"
    log_info ""
    log_info "Proxied clients: $PROXY_CLIENTS"
    log_info "Clash redir port: $CLASH_REDIR_PORT"
    log_info ""
    log_info "Test from client (192.168.1.111):"
    log_info "  curl -I https://www.google.com"
}

# ============================================
# Disable Transparent Proxy
# ============================================
disable_tproxy() {
    check_root

    log_info "Disabling transparent proxy..."

    # Remove DNS redirect rules
    for client in $PROXY_CLIENTS; do
        iptables -t nat -D PREROUTING -s $client -p udp --dport 53 -j REDIRECT --to-ports $CLASH_DNS_PORT 2>/dev/null || true
    done

    # Remove the chain from PREROUTING
    iptables -t nat -D PREROUTING -j $CHAIN_NAME 2>/dev/null || true

    # Flush and delete the chain
    iptables -t nat -F $CHAIN_NAME 2>/dev/null || true
    iptables -t nat -X $CHAIN_NAME 2>/dev/null || true

    log_info "Transparent proxy disabled!"
    log_info ""
    log_info "Clients will now access internet directly (through NAT only)"
}

# ============================================
# Check Status
# ============================================
show_status() {
    echo ""
    echo "============================================"
    echo "Transparent Proxy Status"
    echo "============================================"
    echo ""

    # Check IP forwarding
    echo "IP Forwarding:"
    if [ "$(cat /proc/sys/net/ipv4/ip_forward)" = "1" ]; then
        echo -e "  Status: ${GREEN}Enabled${NC}"
    else
        echo -e "  Status: ${RED}Disabled${NC}"
    fi
    echo ""

    # Check Clash
    echo "Clash Process:"
    if pgrep -f "clash" > /dev/null 2>&1; then
        echo -e "  Status: ${GREEN}Running${NC}"
        echo "  PID: $(pgrep -f clash | head -1)"
    else
        echo -e "  Status: ${RED}Not Running${NC}"
    fi
    echo ""

    # Check Clash ports
    echo "Clash Ports:"
    echo -n "  HTTP ($CLASH_HTTP_PORT): "
    ss -tlnp | grep -q ":$CLASH_HTTP_PORT" && echo -e "${GREEN}Listening${NC}" || echo -e "${RED}Not Listening${NC}"
    echo -n "  SOCKS ($CLASH_SOCKS_PORT): "
    ss -tlnp | grep -q ":$CLASH_SOCKS_PORT" && echo -e "${GREEN}Listening${NC}" || echo -e "${RED}Not Listening${NC}"
    echo -n "  Redir ($CLASH_REDIR_PORT): "
    ss -tlnp | grep -q ":$CLASH_REDIR_PORT" && echo -e "${GREEN}Listening${NC}" || echo -e "${RED}Not Listening${NC}"
    echo -n "  DNS ($CLASH_DNS_PORT): "
    ss -ulnp | grep -q ":$CLASH_DNS_PORT" && echo -e "${GREEN}Listening${NC}" || echo -e "${RED}Not Listening${NC}"
    echo ""

    # Check iptables rules
    echo "iptables Transparent Proxy Chain:"
    if iptables -t nat -L $CHAIN_NAME > /dev/null 2>&1; then
        echo -e "  Status: ${GREEN}Active${NC}"
        echo "  Rules:"
        iptables -t nat -L $CHAIN_NAME -n --line-numbers 2>/dev/null | head -20
    else
        echo -e "  Status: ${YELLOW}Not Active${NC}"
    fi
    echo ""

    # Check PREROUTING
    echo "PREROUTING Chain (first 10 rules):"
    iptables -t nat -L PREROUTING -n --line-numbers | head -12
    echo ""
}

# ============================================
# Test Proxy from Client
# ============================================
test_proxy() {
    echo ""
    echo "============================================"
    echo "Proxy Test Instructions"
    echo "============================================"
    echo ""
    echo "Run these commands on 192.168.1.111 to test:"
    echo ""
    echo "1. Test Google (requires proxy):"
    echo "   curl -I --connect-timeout 5 https://www.google.com"
    echo ""
    echo "2. Test external IP:"
    echo "   curl -s https://ipinfo.io/ip"
    echo ""
    echo "3. Test Docker Hub:"
    echo "   curl -I --connect-timeout 5 https://registry-1.docker.io/v2/"
    echo ""
    echo "4. Test GitHub:"
    echo "   curl -I --connect-timeout 5 https://github.com"
    echo ""
}

# ============================================
# Show Required Clash Configuration
# ============================================
show_clash_config() {
    echo ""
    echo "============================================"
    echo "Required Clash Configuration"
    echo "============================================"
    echo ""
    echo "Add these settings to your Clash config.yaml:"
    echo ""
    cat << 'EOF'
# Enable LAN access
allow-lan: true
bind-address: "*"

# Proxy ports
port: 7890           # HTTP proxy
socks-port: 7891     # SOCKS5 proxy
redir-port: 7892     # Transparent proxy (Linux only)
tproxy-port: 7893    # TProxy port (optional)

# DNS settings (optional but recommended)
dns:
  enable: true
  listen: 0.0.0.0:1053
  enhanced-mode: fake-ip
  fake-ip-range: 198.18.0.1/16
  nameserver:
    - 223.5.5.5
    - 119.29.29.29
  fallback:
    - 8.8.8.8
    - 1.1.1.1
EOF
    echo ""
    echo "After modifying, restart Clash:"
    echo "  systemctl restart clash"
    echo "  # or"
    echo "  killall clash && clash -d /path/to/config &"
    echo ""
}

# ============================================
# Main
# ============================================
case "${1:-}" in
    on|enable|start)
        enable_tproxy
        ;;
    off|disable|stop)
        disable_tproxy
        ;;
    status)
        show_status
        ;;
    test)
        test_proxy
        ;;
    config)
        show_clash_config
        ;;
    *)
        echo "Transparent Proxy Manager for Clash"
        echo ""
        echo "Usage: $0 {on|off|status|test|config}"
        echo ""
        echo "Commands:"
        echo "  on      - Enable transparent proxy for LAN clients"
        echo "  off     - Disable transparent proxy"
        echo "  status  - Show current status"
        echo "  test    - Show test commands for clients"
        echo "  config  - Show required Clash configuration"
        echo ""
        echo "Environment Variables:"
        echo "  CLASH_REDIR_PORT  - Clash redir port (default: 7892)"
        echo "  CLASH_DNS_PORT    - Clash DNS port (default: 1053)"
        echo "  LAN_INTERFACE     - LAN interface (default: eth0)"
        echo "  PROXY_CLIENTS     - Space-separated client IPs (default: 192.168.1.111)"
        echo ""
        echo "Example:"
        echo "  sudo $0 on                           # Enable with defaults"
        echo "  sudo PROXY_CLIENTS='192.168.1.111 192.168.1.112' $0 on  # Multiple clients"
        echo "  sudo $0 off                          # Disable"
        echo ""
        exit 1
        ;;
esac
