#!/bin/bash

MAX_INSTANCES=2

# Function to increment IP address
increment_ip() {
    local ip="$1"
    IFS='.' read -r -a parts <<< "$ip"
    
    ((parts[3]++))
    if [ ${parts[3]} -gt 255 ]; then
        parts[3]=0
        ((parts[2]++))
        if [ ${parts[2]} -gt 255 ]; then
            parts[2]=0
            ((parts[1]++))
            if [ ${parts[1]} -gt 255 ]; then
                parts[1]=0
                ((parts[0]++))
            fi
        fi
    fi
    
    echo "${parts[0]}.${parts[1]}.${parts[2]}.${parts[3]}"
}

# Convert an IPv4 address to an integer for numeric comparison
ip_to_int() {
    local ip="$1"
    IFS='.' read -r -a octets <<< "$ip"
    echo $(( (octets[0] << 24) | (octets[1] << 16) | (octets[2] << 8) | octets[3] ))
}

ip_less() {
    local a=$(ip_to_int "$1")
    local b=$(ip_to_int "$2")
    (( a < b ))
}

ip_greater() {
    local a=$(ip_to_int "$1")
    local b=$(ip_to_int "$2")
    (( a > b ))
}

# Start SNMP daemon instances for testing (IP iteration)
# Usage: start_snmpd_instances [count] [base_ip] [port] [directory]
start_snmpd_instances() {
    local count="${1:-2}"
    local base_ip="${2:-127.0.0.1}"
    local port="${3:-10161}"
    local dir="${4:-/tmp/snmpd_ip}"

    mkdir -p "$dir"

    local current_ip="$base_ip"
    
    for i in $(seq 1 "$count"); do
        local conf="$dir/snmpd_$i.conf"

        cat > "$conf" << EOF
agentaddress udp:$current_ip:$port
rocommunity public
createUser testuser SHA "authpass123456" AES "privpass123456"
rwuser testuser priv
sysLocation "Test device $i"
sysContact "test@test.com"
sysName "device-$i"
EOF

        snmpd -C -c "$conf" \
              -p "$dir/snmpd_$i.pid" \
              -Lf "$dir/snmpd_$i.log" \
              -I -smux
        
        # Increment IP for next instance
        current_ip=$(increment_ip "$current_ip")
    done

    echo "Started $count snmpd instances starting from IP $base_ip port $port"
    echo "snmpwalk -v3 -u testuser -A authpass123456 -a SHA -X privpass123456 -x AES -l authPriv $base_ip:$port 1.3.6.1.2.1.1"
    echo "snmpwalk -v2c -c public $base_ip:$port 1.3.6.1.2.1.1"
}

# Start SNMP daemon instances with unique users/passwords for each instance (IP iteration)
# Usage: start_snmpd_instances_unique [count] [base_ip] [port] [directory]
start_snmpd_instances_unique() {
    local count="${1:-2}"
    local base_ip="${2:-127.0.0.1}"
    local port="${3:-10161}"
    local dir="${4:-/tmp/snmpd_ip}"

    mkdir -p "$dir"

    # Mark this as unique mode for status display
    touch "$dir/unique_mode"

    local current_ip="$base_ip"
    
    for i in $(seq 1 "$count"); do
        local conf="$dir/snmpd_$i.conf"
        local user="usersingle"
        local authpass="authpass$i"
        local privpass="privpass$i"

        cat > "$conf" << EOF
agentaddress udp:$current_ip:$port
rocommunity public
createUser $user MD5 "$authpass" DES "$privpass"
rwuser $user priv
sysLocation "Test device $i"
sysContact "test@test.com"
sysName "device-$i"
EOF

        snmpd -C -c "$conf" \
              -p "$dir/snmpd_$i.pid" \
              -Lf "$dir/snmpd_$i.log" \
              -I -smux
        
        # Increment IP for next instance
        current_ip=$(increment_ip "$current_ip")
    done

    echo "Started $count snmpd instances starting from IP $base_ip port $port"
    echo ""
    echo "Unique credentials for each instance:"
    local temp_ip="$base_ip"
    for i in $(seq 1 "$count"); do
        local user="usersingle"
        local authpass="authpass$i"
        local privpass="privpass$i"
        echo "Instance $i (IP $temp_ip): snmpwalk -v3 -u $user -A $authpass -a MD5 -X $privpass -x DES -l authPriv $temp_ip:$port 1.3.6.1.2.1.1"
        temp_ip=$(increment_ip "$temp_ip")
    done
    echo "or for SNMPv2c:"
    echo "  snmpwalk -v2c -c public $base_ip:$port 1.3.6.1.2.1.1"
}

# Start SNMP daemon instances with unique users AND passwords for each instance (IP iteration)
# Usage: start_snmpd_instances_unique_users [count] [base_ip] [port] [directory]
start_snmpd_instances_unique_users() {
    local count="${1:-2}"
    local base_ip="${2:-127.0.0.1}"
    local port="${3:-10161}"
    local dir="${4:-/tmp/snmpd_ip}"

    mkdir -p "$dir"

    # Mark this as unique mode for status display
    touch "$dir/unique_mode"
    touch "$dir/unique_users_mode"

    local current_ip="$base_ip"
    
    for i in $(seq 1 "$count"); do
        local conf="$dir/snmpd_$i.conf"
        local user="user$i"
        local authpass="authpass$i"
        local privpass="privpass$i"

        cat > "$conf" << EOF
agentaddress udp:$current_ip:$port
rocommunity public
createUser $user MD5 "$authpass" DES "$privpass"
rwuser $user priv
sysLocation "Test device $i"
sysContact "test@test.com"
sysName "device-$i"
EOF

        snmpd -C -c "$conf" \
              -p "$dir/snmpd_$i.pid" \
              -Lf "$dir/snmpd_$i.log" \
              -I -smux
        
        # Increment IP for next instance
        current_ip=$(increment_ip "$current_ip")
    done

    echo "Started $count snmpd instances starting from IP $base_ip port $port"
    echo ""
    echo "Unique users and credentials for each instance:"
    local temp_ip="$base_ip"
    for i in $(seq 1 "$count"); do
        local user="user$i"
        local authpass="authpass$i"
        local privpass="privpass$i"
        echo "Instance $i (IP $temp_ip): snmpwalk -v3 -u $user -A $authpass -a MD5 -X $privpass -x DES -l authPriv $temp_ip:$port 1.3.6.1.2.1.1"
        temp_ip=$(increment_ip "$temp_ip")
    done
    echo "or for SNMPv2c:"
    echo "  snmpwalk -v2c -c public $base_ip:$port 1.3.6.1.2.1.1"
}

# Stop SNMP daemon instances
# Usage: stop_snmpd_instances [directory]
stop_snmpd_instances() {
    local dir="${1:-/tmp/snmpd_ip}"

    if [ ! -d "$dir" ]; then
        echo "Directory $dir does not exist"
        return 1
    fi

    local count=0
    for pidfile in "$dir"/snmpd_*.pid; do
        if [ -f "$pidfile" ]; then
            local pid=$(cat "$pidfile")
            if kill "$pid" 2>/dev/null; then
                echo "Stopped snmpd process $pid"
                ((count++))
            fi
        fi
    done

    # Clean up files
    rm -f "$dir"/snmpd_*.conf "$dir"/snmpd_*.pid "$dir"/snmpd_*.log
    rm -f "$dir/unique_mode" "$dir/unique_users_mode"

    echo "Stopped $count snmpd instances"
    return 0
}

# Show status of SNMP daemon instances
# Usage: status_snmpd_instances [directory]
status_snmpd_instances() {
    local dir="${1:-/tmp/snmpd_ip}"

    if [ ! -d "$dir" ]; then
        echo "Directory $dir does not exist"
        return 1
    fi

    echo "SNMP Daemon Instances Status:"
    echo "================================"
    echo "Directory: $dir"
    echo ""

    local running=0
    local stopped=0

    for pidfile in "$dir"/snmpd_*.pid; do
        if [ -f "$pidfile" ]; then
            local pid=$(cat "$pidfile")
            local num=$(basename "$pidfile" .pid | sed 's/snmpd_//')
            local logfile="$dir/snmpd_$num.log"

            if kill -0 "$pid" 2>/dev/null; then
                echo "✓ Instance $num (PID: $pid) - RUNNING"
                ((running++))

                # Show credentials for unique mode
                if [ -f "$dir/unique_users_mode" ]; then
                    echo "  Credentials: user${num}/authpass${num}/privpass${num}"
                    # Get IP from config file
                    local conf="$dir/snmpd_$num.conf"
                    if [ -f "$conf" ]; then
                        local ip_port=$(grep "agentaddress" "$conf" | sed 's/.*udp:\([^)]*\).*/\1/')
                        echo "  snmpwalk command: snmpwalk -v3 -u user${num} -A authpass${num} -a MD5 -X privpass${num} -x DES -l authPriv $ip_port 1.3.6.1.2.1.1"
                    fi
                elif [ -f "$dir/unique_mode" ]; then
                    echo "  Credentials: usersingle/authpass${num}/privpass${num}"
                    # Get IP from config file
                    local conf="$dir/snmpd_$num.conf"
                    if [ -f "$conf" ]; then
                        local ip_port=$(grep "agentaddress" "$conf" | sed 's/.*udp:\([^)]*\).*/\1/')
                        echo "  snmpwalk command: snmpwalk -v3 -u usersingle -A authpass${num} -a MD5 -X privpass${num} -x DES -l authPriv $ip_port 1.3.6.1.2.1.1"
                    fi
                fi
            else
                echo "✗ Instance $num (PID: $pid) - STOPPED"
                ((stopped++))
            fi

            if [ -f "$logfile" ]; then
                echo "  Log: $logfile"
            fi
        fi
    done

    # Calculate IP range and total count for summary
    local total_instances=0
    local min_ip=""
    local max_ip=""
    local port=""

    for pidfile in "$dir"/snmpd_*.pid; do
        if [ -f "$pidfile" ]; then
            local num=$(basename "$pidfile" .pid | sed 's/snmpd_//')
            local conf="$dir/snmpd_$num.conf"

            if [ -f "$conf" ]; then
                local ip_port=$(grep "agentaddress" "$conf" | sed 's/.*udp:\([^)]*\).*/\1/')
                if [ -n "$ip_port" ]; then
                    local ip=$(echo "$ip_port" | cut -d: -f1)
                    local current_port=$(echo "$ip_port" | cut -d: -f2)

                    if [ -z "$port" ]; then
                        port="$current_port"
                    fi

                    if [ -z "$min_ip" ] || ip_less "$ip" "$min_ip"; then
                        min_ip="$ip"
                    fi
                    if [ -z "$max_ip" ] || ip_greater "$ip" "$max_ip"; then
                        max_ip="$ip"
                    fi
                fi
            fi
            ((total_instances++))
        fi
    done

    echo ""
    echo "Summary: $running running, $stopped stopped"

    if [ $total_instances -gt 0 ]; then
        echo "Total instances: $total_instances"
        if [ -n "$min_ip" ] && [ -n "$max_ip" ]; then
            echo "IP range: $min_ip-$max_ip"
        fi
        if [ -n "$port" ]; then
            echo "Port: $port"
        fi
    fi

    echo ""
    echo "Usage: $0 {start|stop|status|unique|unique-users} [options]"
    echo "  start [count] [base_ip] [port] [directory]         # Same credentials for all instances"
    echo "  unique [count] [base_ip] [port] [directory]        # Same username, unique passwords per instance"
    echo "  unique-users [count] [base_ip] [port] [directory]  # Unique username and passwords per instance"
    echo "  stop [directory]"
    echo "  status [directory]"
    echo ""

    if [ $running -eq 0 ] && [ -z "$(ls "$dir"/snmpd_*.pid 2>/dev/null)" ]; then
        echo "No instances found"
        return 1
    fi

    if [ -f "$dir/unique_users_mode" ]; then
        echo "Example snmpwalk commands (UNIQUE USERS MODE - different username and credentials per instance):"
        echo "  Instance 1: snmpwalk -v3 -u user1 -A authpass1 -a MD5 -X privpass1 -x DES -l authPriv 127.0.0.1:10161 1.3.6.1.2.1.1"
        echo "  Instance 2: snmpwalk -v3 -u user2 -A authpass2 -a MD5 -X privpass2 -x DES -l authPriv 127.0.0.2:10161 1.3.6.1.2.1.1"
        echo "  Instance N: snmpwalk -v3 -u userN -A authpassN -a MD5 -X privpassN -x DES -l authPriv IP:10161 1.3.6.1.2.1.1"
    elif [ -f "$dir/unique_mode" ]; then
        echo "Example snmpwalk commands (UNIQUE MODE - different credentials per instance):"
        echo "  Instance 1: snmpwalk -v3 -u usersingle -A authpass1 -a MD5 -X privpass1 -x DES -l authPriv 127.0.0.1:10161 1.3.6.1.2.1.1"
        echo "  Instance 2: snmpwalk -v3 -u usersingle -A authpass2 -a MD5 -X privpass2 -x DES -l authPriv 127.0.0.2:10161 1.3.6.1.2.1.1"
        echo "  Instance N: snmpwalk -v3 -u usersingle -A authpassN -a MD5 -X privpassN -x DES -l authPriv IP:10161 1.3.6.1.2.1.1"
    else
        echo "Example snmpwalk command (STANDARD MODE - same credentials for all instances):"
        echo "  snmpwalk -v3 -u testuser -A authpass123456 -a SHA -X privpass123456 -x AES -l authPriv 127.0.0.1:10161 1.3.6.1.2.1.1"
    fi

    echo "or for SNMPv2c:"
    echo "  snmpwalk -v2c -c public 127.0.0.1:10161 1.3.6.1.2.1.1"
    echo ""

    return 0
}

# Main
case "${1:-status}" in
    start)
        start_snmpd_instances "${2:-$MAX_INSTANCES}" "${3:-127.0.0.1}" "${4:-10161}" "${5:-/tmp/snmpd_ip}"
        ;;
    unique)
        start_snmpd_instances_unique "${2:-$MAX_INSTANCES}" "${3:-127.0.0.1}" "${4:-10161}" "${5:-/tmp/snmpd_ip}"
        ;;
    unique-users)
        start_snmpd_instances_unique_users "${2:-$MAX_INSTANCES}" "${3:-127.0.0.1}" "${4:-10161}" "${5:-/tmp/snmpd_ip}"
        ;;
    stop)
        stop_snmpd_instances "${2:-/tmp/snmpd_ip}"
        ;;
    status)
        status_snmpd_instances "${2:-/tmp/snmpd_ip}"
        ;;
    *)
        echo "Usage: $0 {start|stop|status|unique|unique-users} [options]"
        echo "  start [count] [base_ip] [port] [directory]         # Same credentials for all instances"
        echo "  unique [count] [base_ip] [port] [directory]        # Same username, unique passwords per instance"
        echo "  unique-users [count] [base_ip] [port] [directory]  # Unique username and passwords per instance"
        echo "  stop [directory]"
        echo "  status [directory]"
        exit 1
        ;;
esac