#!/usr/bin/env bash
# br-hw - BlackRoad OS Hardware Profile Manager
# Detect, configure, and manage custom hardware across the fleet
# Usage: br-hw <detect|list|apply|add|scan> [args]
set -euo pipefail

source "$HOME/.blackroad/config/nodes.sh" 2>/dev/null || true

HW_DIR="$HOME/.blackroad/hardware"
mkdir -p "$HW_DIR/profiles" "$HW_DIR/detected"

usage() {
  cat <<EOF
${PINK}br-hw${RESET} - BlackRoad OS Hardware Manager

${BLUE}USAGE:${RESET}
  br-hw detect [node]          Auto-detect hardware on a node
  br-hw list                   List all hardware profiles
  br-hw scan                   Scan fleet hardware
  br-hw add <name>             Create a custom hardware profile
  br-hw apply <profile> [node] Apply a hardware profile to a node
  br-hw info <node>            Show detected hardware for a node

${AMBER}HARDWARE PROFILES:${RESET}
  Profiles define device-specific configuration:
  - Power settings (governor, clock speed, GPU memory)
  - Peripheral support (Hailo, NVMe, cameras, I2C)
  - Service assignments (what runs where)
  - Custom udev rules and kernel parameters

${GREEN}EXAMPLES:${RESET}
  br-hw detect cecilia          Probe Cecilia's hardware
  br-hw add my-pi5-hailo        Create custom profile
  br-hw apply ai-accelerator cecilia
  br-hw scan                    Survey full fleet
EOF
}

# Detect hardware on a node via SSH
cmd_detect() {
  local node="${1:-}"

  if [[ -z "$node" ]]; then
    # Detect local (Mac)
    printf '%bDetecting local hardware...%b\n' "$AMBER" "$RESET"
    detect_local
    return
  fi

  printf '%bDetecting hardware on %s...%b\n' "$AMBER" "$node" "$RESET"

  if ! br_ssh_up "$node" 2>/dev/null; then
    printf '%b%s is offline%b\n' "$RED" "$node" "$RESET"
    return 1
  fi

  local out_file="$HW_DIR/detected/${node}.yaml"

  # Collect hardware info via SSH
  local hw_info
  hw_info=$(br_ssh "$node" "
    echo '---'
    echo 'node: $node'
    echo 'detected: $(date -u +%Y-%m-%dT%H:%M:%SZ)'

    # Platform
    echo 'platform:'
    echo '  model: \"'$(cat /proc/device-tree/model 2>/dev/null | tr -d '\0' || echo 'unknown')'\"'
    echo '  arch: \"'$(uname -m)'\"'
    echo '  kernel: \"'$(uname -r)'\"'
    echo '  os: \"'$(. /etc/os-release 2>/dev/null && echo \"\$PRETTY_NAME\" || echo 'unknown')'\"'

    # CPU
    echo 'cpu:'
    echo '  cores: '$(nproc)
    echo '  governor: \"'$(cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor 2>/dev/null || echo 'unknown')'\"'
    echo '  freq_mhz: '$(cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq 2>/dev/null | awk '{printf \"%.0f\", \$1/1000}' || echo '0')
    echo '  max_freq_mhz: '$(cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_max_freq 2>/dev/null | awk '{printf \"%.0f\", \$1/1000}' || echo '0')

    # Memory
    echo 'memory:'
    echo '  total_mb: '$(free -m | awk '/Mem:/{print \$2}')
    echo '  available_mb: '$(free -m | awk '/Mem:/{print \$7}')
    echo '  swap_mb: '$(free -m | awk '/Swap:/{print \$2}')

    # Storage
    echo 'storage:'
    lsblk -dn -o NAME,SIZE,TYPE,TRAN 2>/dev/null | while read -r dev size type tran; do
      echo \"  - device: /dev/\$dev\"
      echo \"    size: \\\"\$size\\\"\"
      echo \"    type: \\\"\$type\\\"\"
      echo \"    transport: \\\"\${tran:-unknown}\\\"\"
    done

    # GPU
    echo 'gpu:'
    echo '  mem_mb: '$(vcgencmd get_config gpu_mem 2>/dev/null | cut -d= -f2 || echo '0')

    # Temperature
    echo 'thermal:'
    echo '  temp_c: '$(vcgencmd measure_temp 2>/dev/null | grep -oP '[0-9.]+' || echo '0')
    echo '  throttled: \"'$(vcgencmd get_throttled 2>/dev/null | cut -d= -f2 || echo 'unknown')'\"'

    # Voltage
    echo '  voltage_v: '$(vcgencmd measure_volts 2>/dev/null | grep -oP '[0-9.]+' || echo '0')

    # Accelerators
    echo 'accelerators:'
    if [ -e /dev/hailo0 ]; then
      echo '  - type: hailo-8'
      echo '    device: /dev/hailo0'
      serial=\$(hailortcli fw-control identify 2>/dev/null | grep -i serial | awk '{print \$NF}' || echo 'unknown')
      echo \"    serial: \\\"\$serial\\\"\"
      echo '    tops: 26'
    fi

    # USB devices
    echo 'usb_devices:'
    lsusb 2>/dev/null | grep -v 'root hub' | while read -r line; do
      echo \"  - \\\"\$line\\\"\"
    done

    # I2C devices
    echo 'i2c_devices:'
    for bus in /dev/i2c-*; do
      [ -e \"\$bus\" ] || continue
      bus_num=\${bus##*-}
      i2cdetect -y \"\$bus_num\" 2>/dev/null | grep -oP '[0-9a-f]{2}' | while read -r addr; do
        echo \"  - bus: \$bus_num\"
        echo \"    address: 0x\$addr\"
      done
    done 2>/dev/null

    # Network
    echo 'network:'
    for iface in eth0 wlan0; do
      if ip addr show \"\$iface\" &>/dev/null; then
        ip_addr=\$(ip -4 addr show \"\$iface\" 2>/dev/null | grep -oP 'inet \K[0-9.]+' | head -1)
        echo \"  \$iface: \\\"\${ip_addr:-down}\\\"\"
      fi
    done

    # Docker
    echo 'docker:'
    if command -v docker &>/dev/null; then
      echo '  installed: true'
      echo '  containers: '$(docker ps -q 2>/dev/null | wc -l)
    else
      echo '  installed: false'
    fi

    # Services
    echo 'services:'
    for svc in ollama docker tailscaled cloudflared nginx postgresql; do
      if systemctl is-active \"\$svc\" &>/dev/null; then
        echo \"  \$svc: active\"
      fi
    done
  " 2>/dev/null) || {
    printf '%bFailed to detect hardware on %s%b\n' "$RED" "$node" "$RESET"
    return 1
  }

  echo "$hw_info" > "$out_file"
  printf '%bHardware profile saved: %s%b\n' "$GREEN" "$out_file" "$RESET"

  # Display summary
  echo "$hw_info"
}

detect_local() {
  local out_file="$HW_DIR/detected/mac.yaml"
  cat > "$out_file" <<YAML
---
node: mac
detected: $(date -u +%Y-%m-%dT%H:%M:%SZ)
platform:
  model: "$(sysctl -n hw.model 2>/dev/null || echo 'Mac')"
  arch: "$(uname -m)"
  kernel: "$(uname -r)"
  os: "$(sw_vers -productName 2>/dev/null) $(sw_vers -productVersion 2>/dev/null)"
cpu:
  cores: $(sysctl -n hw.ncpu 2>/dev/null || echo 0)
  brand: "$(sysctl -n machdep.cpu.brand_string 2>/dev/null || echo 'unknown')"
memory:
  total_mb: $(( $(sysctl -n hw.memsize 2>/dev/null || echo 0) / 1048576 ))
storage:
  - device: /dev/disk0
    size: "$(diskutil info / 2>/dev/null | grep 'Disk Size' | awk -F: '{print $2}' | xargs || echo 'unknown')"
docker:
  installed: $(command -v docker &>/dev/null && echo true || echo false)
  containers: $(docker ps -q 2>/dev/null | wc -l | tr -d ' ')
YAML
  printf '%bLocal hardware saved: %s%b\n' "$GREEN" "$out_file" "$RESET"
  cat "$out_file"
}

cmd_list() {
  printf '%b%-20s %s%b\n' "$BLUE" "PROFILE" "DESCRIPTION" "$RESET"
  printf '%-20s %s\n' "───────" "───────────"
  for f in "$HW_DIR/profiles/"*.yaml; do
    [[ -f "$f" ]] || continue
    name=$(basename "$f" .yaml)
    desc=$(grep '^description:' "$f" 2>/dev/null | sed 's/^description: *//' | head -1)
    printf '%-20s %s\n' "$name" "${desc:-—}"
  done

  echo ""
  printf '%bDetected:%b\n' "$AMBER" "$RESET"
  for f in "$HW_DIR/detected/"*.yaml; do
    [[ -f "$f" ]] || continue
    name=$(basename "$f" .yaml)
    detected=$(grep '^detected:' "$f" 2>/dev/null | awk '{print $2}')
    printf '  %-16s (scanned %s)\n' "$name" "${detected:-never}"
  done
}

cmd_add() {
  local name="$1"
  local profile="$HW_DIR/profiles/${name}.yaml"

  if [[ -f "$profile" ]]; then
    echo "Profile '$name' already exists."
    return 1
  fi

  cat > "$profile" <<YAML
# BlackRoad OS Hardware Profile: $name
name: $name
description: Custom hardware profile
version: 1.0.0

# Target platform constraints
platform:
  types: [pi5, pi4, pi400]  # or: [x86, mac, any]
  min_ram: 2048              # MB
  required_devices: []       # e.g., [hailo, nvme]

# Power configuration
power:
  governor: conservative     # ondemand, conservative, performance, powersave
  max_freq_mhz: 2000
  gpu_mem_mb: 16
  swappiness: 10

# Kernel parameters (appended to /boot/firmware/cmdline.txt)
kernel_params: []
  # - "isolcpus=3"
  # - "nohz_full=3"

# Sysctl overrides
sysctl:
  vm.swappiness: 10
  vm.dirty_ratio: 40
  # net.core.somaxconn: 4096

# Services to enable/disable
services:
  enable: []
    # - ollama
    # - docker
  disable: []
    # - cups
    # - avahi-daemon

# udev rules (deployed to /etc/udev/rules.d/)
udev_rules: []
  # - 'SUBSYSTEM=="usb", ATTR{idVendor}=="1a86", MODE="0666"'

# Custom setup commands (run once on apply)
setup_commands: []
  # - "pip3 install hailort"

# Cron jobs to install
cron: []
  # - "*/5 * * * * /opt/blackroad/bin/power-monitor.sh"
YAML

  printf '%bCreated profile: %s%b\n' "$GREEN" "$profile" "$RESET"
  printf 'Edit the profile: %s\n' "$profile"
}

cmd_apply() {
  local profile_name="$1"
  local node="${2:-}"
  local profile="$HW_DIR/profiles/${profile_name}.yaml"

  if [[ ! -f "$profile" ]]; then
    echo "Profile '$profile_name' not found."
    return 1
  fi

  if [[ -z "$node" ]]; then
    echo "Usage: br-hw apply <profile> <node>"
    return 1
  fi

  printf '%bApplying profile %s to %s...%b\n' "$AMBER" "$profile_name" "$node" "$RESET"

  if ! br_ssh_up "$node" 2>/dev/null; then
    printf '%b%s is offline%b\n' "$RED" "$node" "$RESET"
    return 1
  fi

  # Copy profile to node
  local ssh_target
  ssh_target="$(br_ssh_target "$node")"
  scp -q "$profile" "$ssh_target:/tmp/br-hw-profile.yaml" 2>/dev/null

  # Apply power settings
  local governor
  governor=$(grep 'governor:' "$profile" | head -1 | awk '{print $2}')
  if [[ -n "$governor" && "$governor" != "null" ]]; then
    printf '  governor → %s: ' "$governor"
    br_ssh "$node" "echo '$governor' | sudo tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor >/dev/null 2>&1" && \
      printf '%bok%b\n' "$GREEN" "$RESET" || printf '%bfail%b\n' "$RED" "$RESET"
  fi

  # Apply sysctl
  local swappiness
  swappiness=$(grep 'swappiness:' "$profile" | tail -1 | awk '{print $2}')
  if [[ -n "$swappiness" && "$swappiness" != "null" ]]; then
    printf '  swappiness → %s: ' "$swappiness"
    br_ssh "$node" "sudo sysctl -w vm.swappiness=$swappiness >/dev/null 2>&1" && \
      printf '%bok%b\n' "$GREEN" "$RESET" || printf '%bfail%b\n' "$RED" "$RESET"
  fi

  printf '%bProfile %s applied to %s%b\n' "$GREEN" "$profile_name" "$node" "$RESET"
}

cmd_scan() {
  printf '%bScanning fleet hardware...%b\n\n' "$AMBER" "$RESET"

  # Detect local first
  detect_local
  echo ""

  # Then all Pi nodes
  for node in "${PI_NODES[@]}"; do
    cmd_detect "$node" 2>/dev/null || true
    echo ""
  done

  printf '%bFleet scan complete. Profiles in %s/detected/%b\n' "$GREEN" "$HW_DIR" "$RESET"
}

cmd_info() {
  local node="$1"
  local detected="$HW_DIR/detected/${node}.yaml"

  if [[ ! -f "$detected" ]]; then
    echo "No hardware data for '$node'. Run: br-hw detect $node"
    return 1
  fi

  cat "$detected"
}

# Main
case "${1:-}" in
  detect)    cmd_detect "${2:-}" ;;
  list)      cmd_list ;;
  scan)      cmd_scan ;;
  add)       cmd_add "${2:?profile name required}" ;;
  apply)     cmd_apply "${2:?profile name required}" "${3:-}" ;;
  info)      cmd_info "${2:?node name required}" ;;
  -h|--help|help|"") usage ;;
  *)         echo "Unknown: $1"; usage; exit 1 ;;
esac
