#!/bin/bash
# ==========================================================
#  CyberTools Admin – v1.5.1 (Dev / Clean Loop)
#  Author: Jeffery Raskin
#  Release: 2025-10-07
#  Path: /root/cybertoolsadmin/admin-menu.v1.5.1.dev
#  Description:
#    - Self-healing .bashrc (autostart block) with prints + logging
#    - License verification (non-blocking) with prints + logging
#    - Autostart + Auto-Logout Timeout status and management
#    - Pip/System dependency installers (from text files)
#    - Clean, single-pass status (no duplicate headers)
#    - First run: NO clear (so login banner stays visible)
#    - Subsequent loops: soft clear each time
# ==========================================================

set -u

# ─────────── 1) COLORS ───────────
RESET="\033[0m"; BOLD="\033[1m"
RED="\033[1;31m"; GREEN="\033[1;32m"; YELLOW="\033[1;33m"
BLUE="\033[1;34m"; CYAN="\033[1;36m"; MAGENTA="\033[1;35m"

# ─────────── 2) CONSTANTS & PATHS ───────────
BASE_DIR="/root/cybertoolsadmin"
CONFIG_FILE="$BASE_DIR/config.conf"
LICENSE_DIR="/root/.cybertoolsadmin"
LICENSE_FILE="$LICENSE_DIR/license.key"
VALID_HASH_FILE="$BASE_DIR/.valid_hash"
LOG_FILE="$BASE_DIR/cybertools-admin.log"
DEPS_FILE="$BASE_DIR/dependencies.txt"
SYS_DEPS_FILE="$BASE_DIR/system-deps.txt"
TMOUT_PROFILE="/etc/profile.d/99-cybertools-tmout.sh"
BASHRC="/root/.bashrc"

# This script’s resolved path (if readlink available)
SCRIPT_PATH="${0}"
if command -v readlink >/dev/null 2>&1; then
  SCRIPT_PATH="$(readlink -f "$0" 2>/dev/null || echo "$0")"
fi

# ─────────── 3) DEFAULT METADATA (can be overridden by config.conf) ───────────
VERSION_DEFAULT="1.5"
AUTHOR_DEFAULT="Jeffery Raskin"
RELEASE_DEFAULT="2025-10-07"

# ─────────── 4) UTILITIES ───────────
timestamp() { date "+%Y-%m-%d %H:%M:%S %Z"; }
log() { echo "[$(timestamp)] $*" >> "$LOG_FILE"; }

# Safe source config (non-fatal if missing)
if [ -f "$CONFIG_FILE" ]; then
  # shellcheck disable=SC1090
  . "$CONFIG_FILE"
fi
VERSION="${VERSION:-$VERSION_DEFAULT}"
AUTHOR="${AUTHOR:-$AUTHOR_DEFAULT}"
RELEASE_DATE="${RELEASE_DATE:-$RELEASE_DEFAULT}"


resolve_tool() {
  local tool="$1"

  # DEV mode → src
  if [ "${DEV_MODE:-0}" = "1" ]; then
    if [ -x "$BASE_DIR/src/${tool}.sh" ]; then
      echo "$BASE_DIR/src/${tool}.sh"
      return 0
    fi
  fi

  # PROD mode → bin
  if [ -x "$BASE_DIR/bin/$tool" ]; then
    echo "$BASE_DIR/bin/$tool"
    return 0
  fi

  return 1
}





# Custom Actions / Hooks
#HOOK_LOADER="$BASE_DIR/src/hook-loader.sh"
#[ -x "$HOOK_LOADER" ] && source "$HOOK_LOADER"

# ─────────── CUSTOM ACTIONS / HOOK ENGINE ───────────

# Hook config search order (NEVER overwritten)
HOOK_CONF_PRIVATE="/root/.cybertoolsadmin/hooks/menu.conf"
HOOK_CONF_LOCAL="$BASE_DIR/hooks/menu.conf"
HOOK_CONF_SAMPLE="$BASE_DIR/hooks/menu.conf.sample"

EDITOR_CMD="${EDITOR:-vi}"

pick_hook_conf() {
  for f in "$HOOK_CONF_PRIVATE" "$HOOK_CONF_LOCAL" "$HOOK_CONF_SAMPLE"; do
    [ -f "$f" ] && { echo "$f"; return; }
  done
  echo ""
}

trim() { sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//'; }

load_hooks() {
  HOOK_KEYS=()
  HOOK_LABELS=()
  HOOK_ACTIONS=()
  HOOK_TARGETS=()

  while IFS= read -r raw || [ -n "$raw" ]; do
    line="$(echo "$raw" | sed 's/#.*$//' | trim)"
    [ -z "$line" ] && continue

    order="$(echo "$line" | awk -F'|' '{print $1}' | trim)"
    label="$(echo "$line" | awk -F'|' '{print $2}' | trim)"
    action="$(echo "$line" | awk -F'|' '{print $3}' | trim)"
    target="$(echo "$line" | awk -F'|' '{print $4}' | trim)"

    [ -z "$order" ] || [ -z "$label" ] || [ -z "$action" ] || [ -z "$target" ] && continue

    HOOK_KEYS+=("$order")
    HOOK_LABELS+=("$label")
    HOOK_ACTIONS+=("$action")
    HOOK_TARGETS+=("$target")
  done < <(sort -n "$1")
}

#resolve_tool() {
#  local name="$1"
#
#  if [ "${DEV_MODE:-0}" = "1" ]; then
#    [ -x "$BASE_DIR/src/$name.sh" ] && echo "$BASE_DIR/src/$name.sh"
#  else
#    [ -x "$BASE_DIR/bin/$name" ] && echo "$BASE_DIR/bin/$name"
#  fi
#}

resolve_tool() {
  local tool_name="$1"
  local src_tool="/root/cybertoolsadmin/src/${tool_name}.sh"
  local bin_tool="/root/cybertoolsadmin/bin/${tool_name}"

  # If menu itself is running from /bin, prefer /bin tools
  if [[ "$0" == */bin/* ]] && [ -x "$bin_tool" ]; then
    echo "$bin_tool"
    return
  fi

  # Otherwise (DEV), use src
  if [ -x "$src_tool" ]; then
    echo "$src_tool"
    return
  fi

  return 1
}





run_hook_action() {
  case "$1" in
    script) [ -x "$2" ] && bash "$2" || echo "Missing: $2" ;;
    edit) mkdir -p "$(dirname "$2")"; touch "$2"; "$EDITOR_CMD" "$2" ;;
    view) [ -f "$2" ] && less "$2" || echo "Missing: $2" ;;
    cmd) bash -lc "$2" ;;
    *) echo "Unknown hook action" ;;
  esac
  read -rp "Press Enter..."
}

custom_actions_menu() {
  conf="$(pick_hook_conf)"
  [ -z "$conf" ] && { echo "No hook config found."; read -rp "Enter..."; return; }

  load_hooks "$conf"

  while true; do
    clear
    echo "========================================"
    echo " Beta – Custom Code Hooks (v1.0)"
    echo " Using: $conf"
    echo "========================================"
    echo

    for i in "${!HOOK_KEYS[@]}"; do
      printf "%s) %s\n" "${HOOK_KEYS[$i]}" "${HOOK_LABELS[$i]}"
    done

    echo
    echo "X) Back"
    read -rp "Choose an option: " choice

    [[ "$choice" =~ ^[xX]$ ]] && return

    for i in "${!HOOK_KEYS[@]}"; do
      [ "$choice" = "${HOOK_KEYS[$i]}" ] && {
        run_hook_action "${HOOK_ACTIONS[$i]}" "${HOOK_TARGETS[$i]}"
        break
      }
    done
  done
}



# ─────────── 5) CLEAR SCREEN ───────────
# Hard clear kept for future use, but we don't use it on startup
hard_clear() { printf '\033c'; }     # full terminal reset (safe)
soft_clear() { tput clear 2>/dev/null || printf '\033[2J\033[H'; }

# ─────────── 6) LICENSE CHECK ───────────
check_license() {
  local status="UNKNOWN"
  if [ -f "$LICENSE_FILE" ] && [ -f "$VALID_HASH_FILE" ]; then
    local cur_hash
    if cur_hash=$(sha256sum "$LICENSE_FILE" 2>/dev/null | awk '{print $1}'); then
      if grep -q "^$cur_hash$" "$VALID_HASH_FILE"; then
        status="VALID"
      else
        status="INVALID"
      fi
    else
      status="UNREADABLE"
    fi
  else
    status="MISSING"
  fi
  echo "$status"
}

# ─────────── 7) SELF-HEAL .bashrc (autostart block) ───────────
heal_bashrc() {
  local TAG="# CyberToolsAdmin Autostart"
  local BLOCK="$TAG
if [[ \$- == *i* ]] && [ -x \"$SCRIPT_PATH\" ]; then
  \"$SCRIPT_PATH\"
fi"

  local changed="no"

  # Remove any old duplicated blocks for CyberToolsAdmin
  if grep -q "$TAG" "$BASHRC" 2>/dev/null; then
    sed -i "/$TAG/,+3d" "$BASHRC"
    echo -e "${YELLOW}Self-Heal:${RESET} removed old autostart block in ${BOLD}$BASHRC${RESET}"
    log "SELF-HEAL: removed existing autostart block from $BASHRC"
    changed="yes"
  fi

  # Append fresh, correct block
  {
    echo ""
    echo "$BLOCK"
  } >> "$BASHRC"

  echo -e "${GREEN}Self-Heal:${RESET} wrote fresh autostart block pointing to ${BOLD}$SCRIPT_PATH${RESET}"
  log "SELF-HEAL: wrote new autostart block to $BASHRC (path=$SCRIPT_PATH)"
  changed="yes"

  # Small pause if changed
  if [ "$changed" = "yes" ]; then sleep 1; fi
}

# ─────────── 8) AUTOSTART STATUS ───────────
get_autostart_status() {
  local TAG="# CyberToolsAdmin Autostart"
  if grep -q "$TAG" "$BASHRC" 2>/dev/null; then
    echo "ENABLED (manual)"
  else
    echo "DISABLED"
  fi
}

enable_autostart() {
  heal_bashrc
  echo -e "${GREEN}Autostart enabled.${RESET}"
  log "Autostart enabled"
  read -rp "Press Enter to continue..."
}

disable_autostart() {
  local TAG="# CyberToolsAdmin Autostart"
  if grep -q "$TAG" "$BASHRC" 2>/dev/null; then
    sed -i "/$TAG/,+3d" "$BASHRC"
    echo -e "${YELLOW}Autostart block removed from $BASHRC.${RESET}"
    log "Autostart disabled (block removed)"
  else
    echo -e "${YELLOW}Autostart already disabled.${RESET}"
  fi
  read -rp "Press Enter to continue..."
}

# ─────────── 9) TIMEOUT (TMOUT) STATUS & EDITOR ───────────
get_timeout_status() {
  local seconds=""
  if [ -f "$TMOUT_PROFILE" ]; then
    seconds=$(grep -E '^\s*export\s+TMOUT=' "$TMOUT_PROFILE" 2>/dev/null | sed -E 's/.*TMOUT=([0-9]+).*/\1/')
  fi
  if [ -z "$seconds" ]; then
    seconds="${TMOUT:-}"
  fi

  if [ -z "$seconds" ]; then
    echo "OFF"
  else
    local mins=$(( (seconds + 59) / 60 ))
    echo "${mins} minutes"
  fi
}

update_timeout() {
  soft_clear
  echo -e "${BOLD}Set Auto-Logout Timeout${RESET}"
  echo -e "Enter minutes (0 to disable auto-logout):"
  read -rp "> " mins

  if ! [[ "$mins" =~ ^[0-9]+$ ]]; then
    echo -e "${RED}Invalid number.${RESET}"
    read -rp "Press Enter..."
    return
  fi

  if [ "$mins" -eq 0 ]; then
    rm -f "$TMOUT_PROFILE"
    echo -e "${YELLOW}Auto-logout disabled (removed $TMOUT_PROFILE).${RESET}"
    log "TMOUT disabled"
  else
    local secs=$(( mins * 60 ))
    cat > "$TMOUT_PROFILE" <<EOF
# Set by CyberToolsAdmin – Auto-Logout
# Human: ${mins} minutes  (${secs} seconds)
export TMOUT=${secs}
EOF
    chmod 644 "$TMOUT_PROFILE"
    echo -e "${GREEN}Auto-logout set to $mins minute(s) [${secs}s].${RESET}"
    log "TMOUT set to ${secs}s (${mins}m)"
  fi
  read -rp "Press Enter to continue..."
}

# ─────────── 10) DEPENDENCY HELPERS ───────────
py_import_name() {
  case "$1" in
    mysqlclient) echo "MySQLdb" ;;
    *) echo "$1" ;;
  esac
}

dep_strip() {
  # Trim, drop inline comments
  echo "$1" | sed 's/\r$//' | sed 's/#.*$//' | sed 's/[[:space:]]\+$//' | sed 's/^[[:space:]]\+//'
}

show_deps_status() {
  echo -e "Dependencies (from $DEPS_FILE):"
  if [ ! -f "$DEPS_FILE" ]; then
    echo -e " - ${YELLOW}No dependencies file found${RESET}"
    return
  fi

  while IFS= read -r raw; do
    local line
    line=$(dep_strip "$raw")
    [ -z "$line" ] && continue
    local pkg="$line"
    local mod
    mod="$(py_import_name "$pkg")"

    if python3 - <<PY 2>/dev/null
import importlib, sys
try:
  importlib.import_module("$mod")
  sys.exit(0)
except Exception:
  sys.exit(1)
PY
    then
      echo -e " - ${pkg}: ${GREEN}INSTALLED${RESET}"
    else
      echo -e " - ${pkg}: ${RED}MISSING${RESET} (press I to install)"
    fi
  done < "$DEPS_FILE"
}

install_pip_deps() {
  echo -e "${CYAN}Installing dependencies from $DEPS_FILE...${RESET}"
  log "Install pip deps started"
  if [ ! -f "$DEPS_FILE" ]; then
    echo -e "${YELLOW}No $DEPS_FILE found.${RESET}"
    read -rp "Press Enter..."
    return
  fi

  while IFS= read -r raw; do
    local line
    line=$(dep_strip "$raw")
    [ -z "$line" ] && continue
    local pkg="$line"
    echo -e "📦 Installing ${BOLD}$pkg${RESET}..."
    if pip3 install -q "$pkg"; then
      echo -e "✅ $pkg installed"
      log "pip installed $pkg"
    else
      echo -e "⚠️  ${YELLOW}Failed to install $pkg${RESET}"
      log "pip failed $pkg"
    fi
  done < "$DEPS_FILE"
  echo -e "${GREEN}Done.${RESET}"
  read -rp "Press Enter to continue..."
}

install_system_deps() {
  echo -e "${CYAN}Installing system packages from $SYS_DEPS_FILE...${RESET}"
  log "Install system deps started"
  if [ ! -f "$SYS_DEPS_FILE" ]; then
    echo -e "${YELLOW}No $SYS_DEPS_FILE found (skipping).${RESET}"
    read -rp "Press Enter..."
    return
  fi

  PKGS=""
  while IFS= read -r raw; do
    local line
    line=$(dep_strip "$raw")
    [ -z "$line" ] && continue
    PKGS="$PKGS $line"
  done < "$SYS_DEPS_FILE"

  if [ -z "$PKGS" ]; then
    echo -e "${YELLOW}No packages listed in $SYS_DEPS_FILE.${RESET}"
    read -rp "Press Enter..."
    return
  fi

  if ! command -v apt-get >/dev/null 2>&1; then
    echo -e "${YELLOW}apt-get not available on this system.${RESET}"
    read -rp "Press Enter..."
    return
  fi

  if ! apt-get update -y 2>/dev/null; then
    echo -e "${YELLOW}apt-get update encountered a lock. Try again later.${RESET}"
    log "apt-get update lock/failed"
    read -rp "Press Enter..."
    return
  fi

  if apt-get install -y $PKGS; then
    echo -e "${GREEN}System dependencies installed.${RESET}"
    log "apt-get installed: $PKGS"
  else
    echo -e "${YELLOW}Some system packages failed to install.${RESET}"
    log "apt-get partial/failed: $PKGS"
  fi
  read -rp "Press Enter to continue..."
}

# ─────────── 11) STATUS BLOCK ───────────
show_status() {
  local lic_status autostart timeout
  lic_status=$(check_license)
  autostart=$(get_autostart_status)
  timeout=$(get_timeout_status)

  echo -e "${BOLD}=== CyberTools Admin – v${VERSION} ===${RESET}"
  echo -e "Author: ${BOLD}${AUTHOR}${RESET}    Release: ${BOLD}${RELEASE_DATE}${RESET}\n"

  if [ "$lic_status" = "VALID" ]; then
    echo -e "🔐  License Status: ${GREEN}VALID${RESET}"
  else
    echo -e "🔐  License Status: ${RED}${lic_status}${RESET}"
  fi
  echo

  echo -e "${BOLD}=== Status ===${RESET}"
  echo -e "Autostart: ${BOLD}${autostart}${RESET}"
  echo -e "Auto-Logout Timeout: ${BOLD}${timeout}${RESET}\n"

  show_deps_status
  echo
}

# ─────────── 12) MENU LOOP ───────────
# ─────────── 12) MENU LOOP ───────────
main_menu() {
  local first_run="yes"
  MENU_LOOP_COUNT=0

  while true; do
    # First run: DO NOT clear, so login banner is visible.
    # Later runs: soft clear before redrawing status/menu.

    if [ "$first_run" = "yes" ]; then
      first_run="no"
    else
      soft_clear
    fi


    show_status

  MENU_LOOP_COUNT=$((MENU_LOOP_COUNT + 1))

    if [ "${DEV_MODE:-0}" = "1" ]; then
      echo -e "${CYAN}[DEV] Menu loop count: $MENU_LOOP_COUNT${RESET}"
    fi


  # ─────────── EXECUTION CONTEXT ───────────
  MENU_EXEC_PATH="$(readlink -f "$0" 2>/dev/null || echo "$0")"
  MENU_EXEC_TYPE="SCRIPT"

  # shc-compiled binaries still have $0, but no .sh extension
  if [[ "$MENU_EXEC_PATH" != *.sh ]]; then
  MENU_EXEC_TYPE="COMPILED"
  fi

  echo "[INFO] Admin Menu running:"
  echo "       Type : $MENU_EXEC_TYPE"
  echo "       Path : $MENU_EXEC_PATH"
  echo






    echo -e "${BOLD}=== CyberTools Admin Menu ===${RESET}"
    echo "1) CyberBackup – Backup & Restore Tools"
    echo "2) CyberMonitor – Resource + Cron Usage (Coming Soon)"
    echo "3) CyberSec – Security Check & File Watch (Coming Soon)"
    echo "4) CyberSEO – WP SEO Analysis & Fixes (Coming Soon)"
    echo "5) Enable Autostart on Root Login"
    echo "6) Disable Autostart on Root Login"
    echo "7) Install System Dependencies"
    echo "8) Set Auto-Logout Timeout"
    echo "9) Beta – Custom Code Hooks (v1.0)"
    echo
    echo "                    X) Exit to Shell"
    echo

    read -rp "Choose an option (or press I to install missing pip deps): " choice

    case "$choice" in
      1)
        TOOL="$(resolve_tool admin-backup 2>/dev/null || true)"
        if [ -n "${TOOL:-}" ] && [ -e "$TOOL" ]; then
          # If it's a binary (ELF), execute directly. If it's a script, run with bash.
          if file "$TOOL" 2>/dev/null | grep -qi 'ELF'; then
            "$TOOL"
          else
            bash "$TOOL"
          fi
        else
          echo -e "${YELLOW}Backup tool not found (admin-backup).${RESET}"
          read -rp "Press Enter..."
        fi
        ;;
      2)
        echo -e "${YELLOW}CyberMonitor coming soon.${RESET}"
        read -rp "Press Enter..."
        ;;
      3)
        echo -e "${YELLOW}CyberSec coming soon.${RESET}"
        read -rp "Press Enter..."
        ;;
      4)
        echo -e "${YELLOW}CyberSEO coming soon.${RESET}"
        read -rp "Press Enter..."
        ;;
      5)
        enable_autostart
        ;;
      6)
        disable_autostart
        ;;
      7)
        install_system_deps
        ;;
      8)
        update_timeout
        ;;
      9)
        if declare -F custom_actions_menu >/dev/null 2>&1; then
          custom_actions_menu
        else
          echo -e "${YELLOW}Custom Actions not available (hook engine not loaded).${RESET}"
          read -rp "Press Enter..."
        fi
        ;;
      [iI])
        install_pip_deps
        ;;
      [xX])
        echo "Exiting CyberTools Admin..."
        log "Exited menu"
        exit 0
        ;;
      *)
        echo -e "${RED}Invalid option.${RESET}"
        read -rp "Press Enter..."
        ;;
    esac
  done
}


# ─────────── 13) STARTUP (log + heal, no clear) ───────────
log "=== CyberTools Admin menu launched (v${VERSION}) by $(whoami) ==="

# Self-heal .bashrc autostart block
# heal_bashrc

# License check (log only; visual handled in show_status)
LIC_NOW="$(check_license)"
log "LICENSE status = $LIC_NOW"

# ─────────── 14) ENTER MENU ───────────
main_menu
