#!/bin/bash
set -e

# ============================================================================
# SOCKS5 Proxy Setup Script (microsocks)
# ============================================================================
# Configures a SOCKS5 proxy server using microsocks on Debian-based systems
# ============================================================================

# ----------------------------------------------------------------------------
# Default Configuration
# ----------------------------------------------------------------------------
DEFAULT_ROOT_PASSWORD=""
DEFAULT_SOCKS5_PASSWORD="rYr2g40sSvepLmgy"
DEFAULT_SOCKS5_PORT=80
DEFAULT_SOCKS5_USER="admin"

# ----------------------------------------------------------------------------
# Configuration Variables
# ----------------------------------------------------------------------------
root_password="${DEFAULT_ROOT_PASSWORD}"
socks5_password="${DEFAULT_SOCKS5_PASSWORD}"

# ----------------------------------------------------------------------------
# Parse Command Line Arguments
# ----------------------------------------------------------------------------
parse_arguments() {
    while [[ $# -gt 0 ]]; do
        case "$1" in
            -rootpass)
                if [[ -z "$2" ]]; then
                    echo "Error: -rootpass requires a value"
                    exit 1
                fi
                root_password="$2"
                shift 2
                ;;
            -s5pass)
                if [[ -z "$2" ]]; then
                    echo "Error: -s5pass requires a value"
                    exit 1
                fi
                socks5_password="$2"
                shift 2
                ;;
            -h|--help)
                show_usage
                exit 0
                ;;
            *)
                echo "Error: Unknown parameter '$1'"
                show_usage
                exit 1
                ;;
        esac
    done
}

# ----------------------------------------------------------------------------
# Display Usage Information
# ----------------------------------------------------------------------------
show_usage() {
    cat << EOF
Usage: $0 [OPTIONS]

OPTIONS:
    -rootpass PASSWORD    Set root user password
    -s5pass PASSWORD      Set SOCKS5 proxy password (default: ${DEFAULT_SOCKS5_PASSWORD})
    -h, --help            Display this help message

EXAMPLE:
    $0 -rootpass myRootPass -s5pass myS5Pass
EOF
}

# ----------------------------------------------------------------------------
# Verify System Compatibility
# ----------------------------------------------------------------------------
verify_system() {
    if [[ ! -f /etc/debian_version ]]; then
        echo "Error: This script requires a Debian-based system"
        exit 1
    fi
}

# ----------------------------------------------------------------------------
# Update Package Repository
# ----------------------------------------------------------------------------
update_package_index() {
    echo "[*] Updating package repository index..."
    apt-get update -y
}

# ----------------------------------------------------------------------------
# Install Required Packages
# ----------------------------------------------------------------------------
install_microsocks() {
    echo "[*] Installing microsocks..."
    apt-get install -y microsocks
}

# ----------------------------------------------------------------------------
# Detect External Network Interface
# ----------------------------------------------------------------------------
detect_network_interface() {
    local interface
    interface=$(ip route get 8.8.8.8 2>/dev/null | awk '{print $5; exit}')
    
    if [[ -z "$interface" ]]; then
        echo "[!] Warning: Unable to detect external interface, using 'eth0' as fallback"
        echo "eth0"
    else
        echo "$interface"
    fi
}

# ----------------------------------------------------------------------------
# Get Interface IPv4 Address
# ----------------------------------------------------------------------------
get_interface_ipv4() {
    local interface="$1"
    ip -4 addr show "$interface" 2>/dev/null | \
        awk '/inet /{print $2}' | \
        cut -d/ -f1 | \
        head -n1
}

# ----------------------------------------------------------------------------
# Update Root Password
# ----------------------------------------------------------------------------
update_root_password() {
    local password="$1"
    
    if [[ -n "$password" ]]; then
        echo "root:${password}" | chpasswd
        echo "[*] Root password updated successfully"
        return 0
    fi
    return 1
}

# ----------------------------------------------------------------------------
# Generate Systemd Service Configuration
# ----------------------------------------------------------------------------
create_systemd_service() {
    local service_file="/etc/systemd/system/microsocks.service"
    local bind_ip="$1"
    local password="$2"
    local exec_start
    
    echo "[*] Creating systemd service: ${service_file}"
    
    # Build command line with optional bind IP
    if [[ -n "$bind_ip" ]]; then
        exec_start="/usr/bin/microsocks -i 0.0.0.0 -p ${DEFAULT_SOCKS5_PORT} -u ${DEFAULT_SOCKS5_USER} -P ${password} -b ${bind_ip}"
    else
        exec_start="/usr/bin/microsocks -i 0.0.0.0 -p ${DEFAULT_SOCKS5_PORT} -u ${DEFAULT_SOCKS5_USER} -P ${password}"
    fi
    
    # Generate service file
    cat > "$service_file" <<EOF
[Unit]
Description=MicroSocks SOCKS5 Proxy Service
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
User=root
ExecStart=${exec_start}
Restart=always
RestartSec=2
LimitNOFILE=65535

[Install]
WantedBy=multi-user.target
EOF
}

# ----------------------------------------------------------------------------
# Enable and Start Service
# ----------------------------------------------------------------------------
activate_service() {
    echo "[*] Reloading systemd daemon..."
    systemctl daemon-reload
    
    echo "[*] Enabling and starting microsocks service..."
    systemctl enable --now microsocks
}

# ----------------------------------------------------------------------------
# Display Configuration Summary
# ----------------------------------------------------------------------------
show_summary() {
    local password="$1"
    local root_updated="$2"
    
    cat << EOF

========================================
SOCKS5 Proxy Setup Complete
========================================
Service:  microsocks
Listen:   0.0.0.0:${DEFAULT_SOCKS5_PORT}
Username: ${DEFAULT_SOCKS5_USER}
Password: ${password}
EOF
    
    if [[ "$root_updated" == "true" ]]; then
        echo "Root:     Password updated"
    fi
    
    echo "========================================"
}

# ----------------------------------------------------------------------------
# Main Execution
# ----------------------------------------------------------------------------
main() {
    local external_interface
    local bind_ip
    local root_password_updated="false"
    
    # Parse command line arguments
    parse_arguments "$@"
    
    # Verify system compatibility
    verify_system
    
    # Update package index
    update_package_index
    
    # Install microsocks
    install_microsocks
    
    # Detect network configuration
    external_interface=$(detect_network_interface)
    bind_ip=$(get_interface_ipv4 "$external_interface")
    
    if [[ -n "$bind_ip" ]]; then
        echo "[*] Detected external interface: ${external_interface} (${bind_ip})"
    else
        echo "[*] Detected external interface: ${external_interface} (no bind IP)"
    fi
    
    # Update root password if provided
    if update_root_password "$root_password"; then
        root_password_updated="true"
    fi
    
    # Create and configure systemd service
    create_systemd_service "$bind_ip" "$socks5_password"
    
    # Activate the service
    activate_service
    
    # Display summary
    show_summary "$socks5_password" "$root_password_updated"
}

# Execute main function with all arguments
main "$@"