#!/bin/bash

# Function to remove all changes
uninstall() {
    echo "Uninstalling ndppd and reverting changes..."

    remove_route
    reset_sysctl
    remove_ndppd_package
    remove_ndppd_config
    remove_ndppd_directory
    remove_service

    echo "Uninstallation complete."
    exit 0
}

# Function to remove route
remove_route() {
    get_ipv6_params || exit 1
    ip route del local "$subnet::/$subnet_len"
    echo "Local route removed."
}

# Function to reset sysctl parameter
reset_sysctl() {
    sysctl net.ipv6.ip_nonlocal_bind=0 > /dev/null 2>&1
    echo "Reverted net.ipv6.ip_nonlocal_bind to 0."
}

# Function to remove ndppd
remove_ndppd_package() {
    if command -v ndppd &> /dev/null; then
        apt-get remove -y ndppd > /dev/null 2>&1
        echo "Removed ndppd package."
    fi
}

# Function to remove ndppd configuration
remove_ndppd_config() {
    local ndppd_conf="/etc/ndppd.conf"
    if [ -f "$ndppd_conf" ]; then
        rm -f "$ndppd_conf"
        echo "Removed \"/etc/ndppd.conf\"."
    fi
}

# Function to remove ndppd directory
remove_ndppd_directory() {
    if [ -d "$NDPPD_DIR" ]; then
        rm -rf "$NDPPD_DIR"
        echo "Removed \"$NDPPD_DIR\"."
    fi
}

# Function to remove systemd service
remove_service() {
    local service_file="/etc/systemd/system/ndppd_ipv6.service"
    if [ -f "$service_file" ]; then
        systemctl stop ndppd_ipv6.service
        if systemctl disable ndppd_ipv6.service &> /dev/null; then
            rm -f "$service_file"
            echo "Removed \"/etc/systemd/system/ndppd_ipv6.service\"."
        else
            echo "Failed to disable systemd service."
            return 1
        fi
    fi
}

# Function to process arguments
process_args() {
    while [[ $# -gt 0 ]]; do
        case "$1" in
            uninstall)
                uninstall
                ;;
            reboot)
                setup_ipv6
                exit 0
                ;;
            --cidr)
                if [[ -n "$2" ]]; then
                    CUSTOM_CIDR="$2"
                    shift
                else
                    echo "Error: --cidr requires a value"
                    exit 1
                fi
                ;;
            *)
                echo "Invalid argument: $1"
                echo "Usage: $0 [uninstall|reboot] [--cidr IPv6_CIDR]"
                exit 1
                ;;
        esac
        shift
    done
}

# Function to get IPv6 parameters
get_ipv6_params() {
    if [[ -n "$CUSTOM_CIDR" ]]; then
        # Parse custom CIDR by splitting on ::/
        subnet=${CUSTOM_CIDR%::/[0-9]*}
        subnet_len=${CUSTOM_CIDR#*::/}
        # Still need to get interface
        ipv6_output=$(ip -6 addr show scope global)
        interface=$(echo "$ipv6_output" | awk '/^[0-9]+: [^ ]+:/ {sub(/:/, "", $2); print $2; exit}')
    else
        # Original automatic detection
        ipv6_output=$(ip -6 addr show scope global)
        interface=$(echo "$ipv6_output" | awk '/^[0-9]+: [^ ]+:/ {sub(/:/, "", $2); print $2; exit}')
        # Этот вариант вытаскивает основной интерфейс, если вдруг установлены несколько интерфейсов через ip -6 addr add
        # ip -6 addr show scope global | awk '/inet6 .*/ {split($2, a, "/"); split(a[1], b, "::"); if (length(b) > 1) { print b[1]; } else { split(a[1], c, ":"); print c[1] ":" c[2] ":" c[3] ":" c[4]; } exit}'
        subnet=$(echo "$ipv6_output" | awk '/inet6 .*/ {split($2, a, "::"); print a[1]; exit}')
        subnet_len=$(echo "$subnet" | awk -F':' '{print NF * 16}')
    fi

    if [ -z "$interface" ] || [ -z "$subnet" ]; then
        echo "Error: Could not determine interface or subnet."
        return 1
    fi
    return 0
}

# Function to setup IPv6
setup_ipv6() {
    get_ipv6_params || exit 1

    echo "Interface: $interface"
    echo "Subnet: $subnet"
    echo "Subnet Length: $subnet_len"

    ip route add local "$subnet::/$subnet_len" dev "$interface"
    sysctl net.ipv6.ip_nonlocal_bind=1
}

# Function to install ndppd
install_ndppd() {
    echo -e "\e[34mUpdating package list and upgrading installed packages...\e[0m"    # apt update  > /dev/null 2>&1 && apt upgrade -y > /dev/null 2>&1
    export DEBIAN_FRONTEND=noninteractive
    apt update && apt upgrade -y

    if ! command -v ndppd &> /dev/null; then
        echo -e "\e[34mndppd is not installed. Installing...\e[0m"
        # apt-get install -y ndppd > /dev/null 2>&1
        apt-get install -y ndppd
    fi
}

# Function to configure ndppd
configure_ndppd() {
    local ndppd_conf="/etc/ndppd.conf"
    if [ -f "$ndppd_conf" ]; then
        echo -e "\e[34mCreating backup of existing ndppd configuration.\e[0m"
        mv "$ndppd_conf" "$ndppd_conf.bak"
    fi

    cat <<EOL >"$ndppd_conf"
route-ttl 30000

proxy $interface {
    router no
    timeout 500
    ttl 30000

    rule $subnet::/$subnet_len {
        static
    }
}
EOL

    systemctl restart ndppd
    if systemctl status ndppd &> /dev/null; then
        echo -e "\e[34mndppd restarted successfully.\e[0m"
    else
        echo "Error restarting ndppd."
        exit 1
    fi
}

# Function to verify ndppd operation
verify_ndppd() {
    if curl --max-time 5 --interface "$subnet::666" ipv6.ip.sb &> /dev/null; then
        echo -e "\e[32mndppd is working!\e[0m"
    else
        echo -e "\e[31mndppd is not working!\e[0m"
    fi
}

# Function to create systemd service
create_service() {
    local service_file="/etc/systemd/system/ndppd_ipv6.service"
    if [ ! -f "$service_file" ]; then
        echo -e "\e[34mCreating systemd service...\e[0m"
        cat <<EOF >"$service_file"
[Unit]
Description=NDPPD IPV6
After=network.target

[Service]
ExecStart=/bin/bash $NDPPD_DIR/install.sh reboot
Restart=on-failure
RestartSec=5

[Install]
WantedBy=multi-user.target
EOF

        systemctl enable ndppd_ipv6.service
        systemctl start ndppd_ipv6.service

        if systemctl status ndppd_ipv6.service &> /dev/null; then
            echo -e "\e[34mndppd_ipv6.service started successfully.\e[0m"
        else
            echo "Error starting ndppd_ipv6.service."
            exit 1
        fi
    fi
}

# Creating directory and downloading script
NDPPD_DIR="/root/.ndppd"
if [ ! -d "$NDPPD_DIR" ]; then
    mkdir -p "$NDPPD_DIR"
    echo -e "\e[34mCreated directory $NDPPD_DIR\e[0m"

    # Downloading and saving script
    curl -fsSL https://ndppd.pages.dev > "$NDPPD_DIR/install.sh"
    chmod +x "$NDPPD_DIR/install.sh"
fi

# Main execution flow
CUSTOM_CIDR=""
if [[ $# -gt 0 ]]; then
    process_args "$@"
fi

setup_ipv6
install_ndppd
configure_ndppd
verify_ndppd
create_service

exit 0
