#!/bin/sh
# bee-tui: interactive text menu for debug LiveCD operations.

set -u

pause() {
    echo
    printf 'Press Enter to continue... '
    read -r _
}

header() {
    clear
    echo "=============================================="
    echo " bee TUI (debug)"
    echo "=============================================="
    echo
}

list_ifaces() {
    ip -o link show \
        | awk -F': ' '{print $2}' \
        | grep -v '^lo$' \
        | grep -vE '^(docker|virbr|veth|tun|tap|br-|bond|dummy)' \
        | sort
}

show_network_status() {
    header
    echo "Network interfaces"
    echo
    for iface in $(list_ifaces); do
        state=$(ip -o link show "$iface" | awk '{print $9}')
        ipv4=$(ip -o -4 addr show dev "$iface" | awk '{print $4}' | paste -sd ',')
        [ -n "$ipv4" ] || ipv4="(no IPv4)"
        echo "- $iface: state=$state ip=$ipv4"
    done
    echo
    ip route | sed 's/^/  route: /'
    pause
}

choose_interface() {
    ifaces="$(list_ifaces)"
    if [ -z "$ifaces" ]; then
        echo "No physical interfaces found"
        return 1
    fi

    echo "$ifaces" | nl -w2 -s'. '
    echo
    printf 'Select interface number: '
    read -r idx
    iface=$(echo "$ifaces" | sed -n "${idx}p")
    if [ -z "$iface" ]; then
        echo "Invalid interface selection"
        return 1
    fi
    CHOSEN_IFACE="$iface"
    return 0
}

network_dhcp_one() {
    header
    echo "DHCP on one interface"
    echo
    choose_interface || { pause; return; }

    iface="$CHOSEN_IFACE"
    echo
    echo "Starting DHCP on $iface..."
    ip link set "$iface" up 2>/dev/null || true
    udhcpc -i "$iface" -t 5 -T 3
    pause
}

network_dhcp_all() {
    header
    echo "Restarting DHCP on all physical interfaces..."
    echo
    /usr/local/bin/bee-net-restart
    pause
}

network_static_one() {
    header
    echo "Static IPv4 setup"
    echo
    choose_interface || { pause; return; }

    iface="$CHOSEN_IFACE"
    echo
    printf 'IPv4 address (example 192.168.1.10): '
    read -r ip
    if [ -z "$ip" ]; then
        echo "IP address is required"
        pause
        return
    fi

    printf 'Netmask (example 24 or 255.255.255.0): '
    read -r mask
    if [ -z "$mask" ]; then
        echo "Netmask is required"
        pause
        return
    fi
    prefix=$(mask_to_prefix "$mask")
    if [ -z "$prefix" ]; then
        echo "Invalid netmask: $mask"
        pause
        return
    fi
    cidr="$ip/$prefix"

    printf 'Default gateway: '
    read -r gw
    if [ -z "$gw" ]; then
        echo "Default gateway is required"
        pause
        return
    fi
    printf 'DNS server (optional): '
    read -r dns

    ip link set "$iface" up 2>/dev/null || true
    ip addr flush dev "$iface"
    if ! ip addr add "$cidr" dev "$iface"; then
        echo "Failed to set IP"
        pause
        return
    fi

    if [ -n "$gw" ]; then
        ip route del default >/dev/null 2>&1 || true
        ip route add default via "$gw" dev "$iface"
    fi

    if [ -n "$dns" ]; then
        printf 'nameserver %s\n' "$dns" > /etc/resolv.conf
    fi

    echo
    echo "Static config applied to $iface"
    pause
}

mask_to_prefix() {
    mask="$(echo "$1" | tr -d '[:space:]')"
    case "$mask" in
        0|1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20|21|22|23|24|25|26|27|28|29|30|31|32)
            echo "$mask"
            return 0
            ;;
    esac
    case "$mask" in
        255.0.0.0) echo 8 ;;
        255.128.0.0) echo 9 ;;
        255.192.0.0) echo 10 ;;
        255.224.0.0) echo 11 ;;
        255.240.0.0) echo 12 ;;
        255.248.0.0) echo 13 ;;
        255.252.0.0) echo 14 ;;
        255.254.0.0) echo 15 ;;
        255.255.0.0) echo 16 ;;
        255.255.128.0) echo 17 ;;
        255.255.192.0) echo 18 ;;
        255.255.224.0) echo 19 ;;
        255.255.240.0) echo 20 ;;
        255.255.248.0) echo 21 ;;
        255.255.252.0) echo 22 ;;
        255.255.254.0) echo 23 ;;
        255.255.255.0) echo 24 ;;
        255.255.255.128) echo 25 ;;
        255.255.255.192) echo 26 ;;
        255.255.255.224) echo 27 ;;
        255.255.255.240) echo 28 ;;
        255.255.255.248) echo 29 ;;
        255.255.255.252) echo 30 ;;
        255.255.255.254) echo 31 ;;
        255.255.255.255) echo 32 ;;
        *) return 1 ;;
    esac
}

network_menu() {
    while true; do
        header
        echo "Network"
        echo "1. Show network status"
        echo "2. DHCP on all interfaces"
        echo "3. DHCP on one interface"
        echo "4. Set static IPv4 on one interface"
        echo "5. Back"
        echo
        printf 'Choice: '
        read -r choice

        case "$choice" in
            1) show_network_status ;;
            2) network_dhcp_all ;;
            3) network_dhcp_one ;;
            4) network_static_one ;;
            5) return ;;
            *) echo "Invalid choice"; pause ;;
        esac
    done
}

bee_services_list() {
    for path in /etc/init.d/bee-*; do
        [ -e "$path" ] || continue
        basename "$path"
    done
}

services_status_all() {
    header
    echo "bee service status"
    echo
    for svc in $(bee_services_list); do
        if rc-service "$svc" status >/dev/null 2>&1; then
            echo "- $svc: running"
        else
            echo "- $svc: stopped"
        fi
    done
    pause
}

choose_service() {
    svcs="$(bee_services_list)"
    if [ -z "$svcs" ]; then
        echo "No bee-* services found"
        return 1
    fi

    echo "$svcs" | nl -w2 -s'. '
    echo
    printf 'Select service number: '
    read -r idx
    svc=$(echo "$svcs" | sed -n "${idx}p")
    if [ -z "$svc" ]; then
        echo "Invalid service selection"
        return 1
    fi
    CHOSEN_SERVICE="$svc"
    return 0
}

service_action_menu() {
    header
    echo "Service action"
    echo
    choose_service || { pause; return; }
    svc="$CHOSEN_SERVICE"

    echo
    echo "Selected: $svc"
    echo "1. status"
    echo "2. restart"
    echo "3. start"
    echo "4. stop"
    echo "5. toggle start/stop"
    echo
    printf 'Choice: '
    read -r act

    case "$act" in
        1)
            rc-service "$svc" status || true
            ;;
        2)
            rc-service "$svc" restart || true
            ;;
        3)
            rc-service "$svc" start || true
            ;;
        4)
            rc-service "$svc" stop || true
            ;;
        5)
            if rc-service "$svc" status >/dev/null 2>&1; then
                rc-service "$svc" stop || true
            else
                rc-service "$svc" start || true
            fi
            ;;
        *)
            echo "Invalid action"
            ;;
    esac
    pause
}

services_menu() {
    while true; do
        header
        echo "bee Services"
        echo "1. Status of all bee-* services"
        echo "2. Manage one service (status/restart/start/stop/toggle)"
        echo "3. Back"
        echo
        printf 'Choice: '
        read -r choice

        case "$choice" in
            1) services_status_all ;;
            2) service_action_menu ;;
            3) return ;;
            *) echo "Invalid choice"; pause ;;
        esac
    done
}

confirm_phrase() {
    phrase="$1"
    prompt="$2"
    echo
    printf '%s (%s): ' "$prompt" "$phrase"
    read -r value
    [ "$value" = "$phrase" ]
}

shutdown_menu() {
    while true; do
        header
        echo "Shutdown/Reboot Tests"
        echo "1. Reboot now"
        echo "2. Power off now"
        echo "3. Schedule poweroff in 60s"
        echo "4. Cancel scheduled shutdown"
        echo "5. IPMI chassis power status"
        echo "6. IPMI chassis power soft"
        echo "7. IPMI chassis power cycle"
        echo "8. Back"
        echo
        printf 'Choice: '
        read -r choice

        case "$choice" in
            1)
                confirm_phrase "REBOOT" "Type confirmation" || { echo "Canceled"; pause; continue; }
                reboot
                ;;
            2)
                confirm_phrase "POWEROFF" "Type confirmation" || { echo "Canceled"; pause; continue; }
                poweroff
                ;;
            3)
                confirm_phrase "SCHEDULE" "Type confirmation" || { echo "Canceled"; pause; continue; }
                shutdown -P +1 "bee test: scheduled poweroff in 60 seconds"
                echo "Scheduled"
                pause
                ;;
            4)
                shutdown -c || true
                echo "Canceled (if any schedule existed)"
                pause
                ;;
            5)
                ipmitool chassis power status || echo "ipmitool power status failed"
                pause
                ;;
            6)
                confirm_phrase "IPMI-SOFT" "Type confirmation" || { echo "Canceled"; pause; continue; }
                ipmitool chassis power soft || echo "ipmitool soft power failed"
                pause
                ;;
            7)
                confirm_phrase "IPMI-CYCLE" "Type confirmation" || { echo "Canceled"; pause; continue; }
                ipmitool chassis power cycle || echo "ipmitool power cycle failed"
                pause
                ;;
            8)
                return
                ;;
            *)
                echo "Invalid choice"
                pause
                ;;
        esac
    done
}

gpu_burn_10m() {
    header
    echo "GPU Burn (10 minutes)"
    echo
    if ! command -v gpu_burn >/dev/null 2>&1; then
        echo "gpu_burn binary not found in PATH"
        echo "Expected command: gpu_burn"
        pause
        return
    fi
    if ! command -v nvidia-smi >/dev/null 2>&1 || ! nvidia-smi -L >/dev/null 2>&1; then
        echo "NVIDIA driver/GPU not ready (nvidia-smi failed)"
        pause
        return
    fi

    confirm_phrase "GPU-BURN" "Type confirmation to start benchmark" || { echo "Canceled"; pause; return; }
    echo "Running: gpu_burn 600"
    echo "Log: /var/log/bee-gpuburn.log"
    gpu_burn 600 2>&1 | tee /var/log/bee-gpuburn.log
    echo
    echo "GPU Burn finished"
    pause
}

gpu_benchmarks_menu() {
    while true; do
        header
        echo "Benchmarks -> GPU"
        echo "1. GPU Burn (10 minutes)"
        echo "2. Back"
        echo
        printf 'Choice: '
        read -r choice

        case "$choice" in
            1) gpu_burn_10m ;;
            2) return ;;
            *) echo "Invalid choice"; pause ;;
        esac
    done
}

benchmarks_menu() {
    while true; do
        header
        echo "Benchmarks"
        echo "1. GPU"
        echo "2. Back"
        echo
        printf 'Choice: '
        read -r choice

        case "$choice" in
            1) gpu_benchmarks_menu ;;
            2) return ;;
            *) echo "Invalid choice"; pause ;;
        esac
    done
}

run_cmd_log() {
    label="$1"
    cmd="$2"
    log_file="$3"

    {
        echo "=== $label ==="
        echo "time: $(date -u '+%Y-%m-%dT%H:%M:%SZ')"
        echo "cmd:  $cmd"
        echo
        sh -c "$cmd"
    } >"$log_file" 2>&1
    return $?
}

run_gpu_nvidia_acceptance_test() {
    header
    echo "System acceptance tests -> GPU NVIDIA"
    echo
    confirm_phrase "SAT-GPU" "Type confirmation to start tests" || { echo "Canceled"; pause; return; }

    ts="$(date -u '+%Y%m%d-%H%M%S')"
    base_dir="/var/log/bee-sat"
    run_dir="$base_dir/gpu-nvidia-$ts"
    archive="$base_dir/gpu-nvidia-$ts.tar.gz"
    mkdir -p "$run_dir"

    summary="$run_dir/summary.txt"
    : >"$summary"

    echo "Running acceptance commands..."
    echo "Logs directory: $run_dir"
    echo "Archive target: $archive"
    echo

    c1="nvidia-smi -q"
    c2="dmidecode -t baseboard"
    c3="dmidecode -t system"
    c4="nvidia-bug-report.sh"

    run_cmd_log "nvidia_smi_q" "$c1" "$run_dir/01-nvidia-smi-q.log"; rc1=$?
    run_cmd_log "dmidecode_baseboard" "$c2" "$run_dir/02-dmidecode-baseboard.log"; rc2=$?
    run_cmd_log "dmidecode_system" "$c3" "$run_dir/03-dmidecode-system.log"; rc3=$?
    run_cmd_log "nvidia_bug_report" "$c4" "$run_dir/04-nvidia-bug-report.log"; rc4=$?

    # Collect any bug report artifact generated in cwd.
    bug_report="$(ls -1 nvidia-bug-report.log.gz 2>/dev/null | head -n1 || true)"
    if [ -n "$bug_report" ] && [ -f "$bug_report" ]; then
        cp -f "$bug_report" "$run_dir/"
    fi

    {
        echo "run_at_utc=$(date -u '+%Y-%m-%dT%H:%M:%SZ')"
        echo "cmd_nvidia_smi_q_rc=$rc1"
        echo "cmd_dmidecode_baseboard_rc=$rc2"
        echo "cmd_dmidecode_system_rc=$rc3"
        echo "cmd_nvidia_bug_report_rc=$rc4"
    } >>"$summary"

    tar -czf "$archive" -C "$base_dir" "gpu-nvidia-$ts"
    tar_rc=$?
    echo "archive_rc=$tar_rc" >>"$summary"

    echo
    echo "Done."
    echo "- Logs:    $run_dir"
    echo "- Archive: $archive (rc=$tar_rc)"
    pause
}

gpu_nvidia_sat_menu() {
    while true; do
        header
        echo "System acceptance tests -> GPU NVIDIA"
        echo "1. Run command pack"
        echo "2. Back"
        echo
        printf 'Choice: '
        read -r choice

        case "$choice" in
            1) run_gpu_nvidia_acceptance_test ;;
            2) return ;;
            *) echo "Invalid choice"; pause ;;
        esac
    done
}

system_acceptance_tests_menu() {
    while true; do
        header
        echo "System acceptance tests"
        echo "1. GPU NVIDIA"
        echo "2. Back"
        echo
        printf 'Choice: '
        read -r choice

        case "$choice" in
            1) gpu_nvidia_sat_menu ;;
            2) return ;;
            *) echo "Invalid choice"; pause ;;
        esac
    done
}

run_audit_now() {
    header
    echo "Run audit now"
    echo
    /usr/local/bin/audit --output stdout > /var/log/bee-audit.json 2>/var/log/bee-audit.log
    rc=$?
    if [ "$rc" -eq 0 ]; then
        echo "Audit completed successfully"
    else
        echo "Audit finished with errors (rc=$rc)"
    fi
    echo "Logs: /var/log/bee-audit.log, /var/log/bee-audit.json"
    pause
}

check_required_tools() {
    header
    echo "Required tools check"
    echo
    for tool in dmidecode smartctl nvme ipmitool lspci audit nvidia-smi gpu_burn; do
        if command -v "$tool" >/dev/null 2>&1; then
            echo "- $tool: OK ($(command -v "$tool"))"
        else
            echo "- $tool: MISSING"
        fi
    done
    pause
}

main_menu() {
    while true; do
        header
        echo "Main Menu"
        echo "1. Network setup"
        echo "2. bee service management"
        echo "3. Shutdown/reboot tests"
        echo "4. Benchmarks"
        echo "5. System acceptance tests"
        echo "6. Run audit now"
        echo "7. Check required tools"
        echo "8. Show last audit log tail"
        echo "9. Exit to console"
        echo
        printf 'Choice: '
        read -r choice

        case "$choice" in
            1) network_menu ;;
            2) services_menu ;;
            3) shutdown_menu ;;
            4) benchmarks_menu ;;
            5) system_acceptance_tests_menu ;;
            6) run_audit_now ;;
            7) check_required_tools ;;
            8)
                header
                tail -n 40 /var/log/bee-audit.log 2>/dev/null || echo "No /var/log/bee-audit.log"
                echo
                tail -n 20 /var/log/bee-audit.json 2>/dev/null || true
                pause
                ;;
            9) exit 0 ;;
            *) echo "Invalid choice"; pause ;;
        esac
    done
}

main_menu
