#!/bin/bash

# ==========================================================
# Cavisson Unified Tuning Script (Fresh + Upgrade Safe)
# ==========================================================

KEYWORD_FILE="/home/cavisson/work/etc/KeywordDefinition.dat"
HPD_CONF="/home/cavisson/work/hpd/conf/hpd.conf"
HPD_ROOT="/home/cavisson/work/hpd"
NS_WDIR="/home/cavisson/work"

echo "========================================="
echo "Cavisson Tuning Started"
echo "========================================="

# ----------------------------------------------------------
# UPDATE KEYWORD (column 8)
# ----------------------------------------------------------
update_keyword() {
    KEY="$1"
    VALUE="$2"

    if grep -q "^$KEY[[:space:]]*\|" "$KEYWORD_FILE"; then

        CURRENT_VAL=$(awk -F'|' -v key="$KEY" '$1==key {print $8}' "$KEYWORD_FILE")

        if [ "$CURRENT_VAL" == "$VALUE" ]; then
            echo "✔ $KEY already set → $VALUE"
        else
            echo "➜ Updating $KEY → $VALUE"

            awk -F'|' -v OFS='|' -v key="$KEY" -v val="$VALUE" '
            {
                if ($1 == key) {
                    $8 = val
                }
                print
            }' "$KEYWORD_FILE" > "$KEYWORD_FILE.tmp" && mv -f "$KEYWORD_FILE.tmp" "$KEYWORD_FILE"
        fi

    else
        echo "➜ $KEY not found → Skipping"
    fi
}


# ----------------------------------------------------------
# SYSCTL UPDATE (only if needed)
apply_sysctl() {
    PARAM="$1"
    VALUE="$2"

    # Get value from sysctl.conf
    CONFIG=$(grep -E "^[#]*\s*$PARAM\s*=" /etc/sysctl.conf | tail -1 | awk -F= '{print $2}' | tr -d ' ')

    if [ "$EUID" -eq 0 ]; then
        # =========================
        # ROOT MODE (CHECK + FIX)
        # =========================

        RUNTIME=$(sysctl -n $PARAM 2>/dev/null)

        if [ "$CONFIG" == "$VALUE" ] && [ "$RUNTIME" == "$VALUE" ]; then
            echo "✔ $PARAM already set (config + runtime) → $VALUE"
        else
            echo "➜ Updating $PARAM → $VALUE"

            # Fix sysctl.conf
            if grep -Eq "^[#]*\s*$PARAM\s*=" /etc/sysctl.conf; then
                sed -i "s|^[#]*\s*$PARAM\s*=.*|$PARAM=$VALUE|" /etc/sysctl.conf
            else
                echo "$PARAM=$VALUE" >> /etc/sysctl.conf
            fi
        fi

    else
        # =========================
        # NON-ROOT MODE (CHECK ONLY)
        # =========================

        if [ "$CONFIG" == "$VALUE" ]; then
            echo "✔ $PARAM correctly set in sysctl.conf → $VALUE"
        else
            echo  "$PARAM in sysctl.conf is $CONFIG (expected: $VALUE)"
            echo  "Run with sudo to fix:"
            echo  " sudo sed -i 's|^$PARAM.*|$PARAM=$VALUE|' /etc/sysctl.conf"
        fi
    fi
}

# ----------------------------------------------------------
# UPDATE HPD CONF
# ----------------------------------------------------------
update_hpd_conf() {
  
    echo ""
    echo "---- Updating hpd.conf ----"
    echo ""

    update_param() {
        KEY="$1"
        VALUE="$2"

        if grep -q "^$KEY " "$HPD_CONF"; then
            CURRENT=$(grep "^$KEY " "$HPD_CONF")

            if echo "$CURRENT" | grep -q "$VALUE"; then
                echo "✔ $KEY already set → $VALUE"
            else
                echo "➜ Updating $KEY → $VALUE"
                sed -i "s|^$KEY .*|$KEY $VALUE|" "$HPD_CONF"
            fi
        else
            echo "➜ Adding $KEY → $VALUE"
            echo "$KEY $VALUE" >> "$HPD_CONF"
        fi
    }

    update_ports() {
        KEY="$1"
        PORT="$2"

        if grep -q "^$KEY " "$HPD_CONF"; then
            LINE=$(grep "^$KEY " "$HPD_CONF")
            PORTS=$(echo "$LINE" | awk '{print $2}')

            if echo "$PORTS" | grep -w "$PORT" >/dev/null; then
                echo "✔ $KEY already contains $PORT"
            else
                echo "➜ Adding $PORT to $KEY"
                sed -i "s|^$KEY .*|$KEY $PORTS,$PORT|" "$HPD_CONF"
            fi
        else
            echo "➜ Adding $KEY $PORT"
            echo "$KEY $PORT" >> "$HPD_CONF"
        fi
    }

    # Apply changes
    update_param "HPD_EXCLUDE_SAMPLE_DIR" "0"
    update_ports "HPD_PORT" "80"
    update_ports "HPD_SPORT" "443"

    # IPv6 handling
    if grep -q "^HPD6_" "$HPD_CONF"; then
        echo "➜ Commenting IPv6 entries"
        sed -i 's/^HPD6_/#HPD6_/' "$HPD_CONF"
    else
        echo "✔ IPv6 already commented"
    fi
}

# ==========================================================
# 1. KEYWORD CHANGES
# ==========================================================
echo ""
echo "---- Keyword Updates ----"
echo ""

update_keyword "PROGRESS_MSECS" "10000"
update_keyword "G_NO_VALIDATION" "ALL 1"
update_keyword "NUM_NVM" "1 CPU 10"
update_keyword "G_REPORTING" "ALL 1 0"

# ==========================================================
# 2. SYSCTL TUNING
# ==========================================================
echo ""
echo "---- TCP Tuning ----"
echo ""

    apply_sysctl net.ipv4.tcp_tw_reuse 1
    apply_sysctl net.ipv4.tcp_timestamps 1
    apply_sysctl net.ipv4.tcp_fin_timeout 10

# ==========================================================
# 3. HPD CONFIG
# ==========================================================
update_hpd_conf

# ==========================================================
# 4. HPD CAPABILITY
# ==========================================================
echo ""
echo "---- HPD Setup ----"
echo "" 

if command -v setcap >/dev/null 2>&1; then
    sudo setcap 'cap_net_bind_service+ep' $HPD_ROOT/bin/nsu_hpd
    sudo setcap 'cap_net_bind_service+ep' $HPD_ROOT/bin/nsu_hpd.debug
    echo "✔ HPD capability applied"
else
    echo "➜ setcap not available"
fi

if ls /usr/lib/x86_64-linux-gnu/libduktape* >/dev/null 2>&1; then
    echo "✔ duktape already present"
else
    echo "➜ Copying duktape libs"
    sudo cp -aP $NS_WDIR/thirdparty/lib/libduktape* /usr/lib/x86_64-linux-gnu/
fi

check_and_fix_owner() {

    echo ""
    echo "---- Ownership Check ----"
    echo ""

    FILES=(
        "$KEYWORD_FILE"
        "$HPD_CONF"
    )

    for FILE in "${FILES[@]}"; do
        if [ -f "$FILE" ]; then
            OWNER=$(stat -c "%U:%G" "$FILE")

            if [ "$OWNER" == "root:root" ]; then
                echo "➜ $FILE owned by root → fixing to cavisson:cavisson"
                chown cavisson:cavisson "$FILE"
            else
                echo "✔ $FILE ownership → $OWNER"
            fi
        else
            echo "⚠ $FILE not found"
        fi
    done

    # Special handling for sysctl.conf
    SYSCTL_FILE="/etc/sysctl.conf"

    if [ -f "$SYSCTL_FILE" ]; then
        OWNER=$(stat -c "%U:%G" "$SYSCTL_FILE")
        echo "✔ $SYSCTL_FILE ownership → $OWNER (no change required)"
    fi
}
check_and_fix_owner

# ==========================================================
# COMPLETE
# ==========================================================

echo ""
echo "========================================="
echo "Tuning Completed"
echo "========================================="
echo ""

