#!/bin/sh

PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/spike-emu/bin
export PATH
export SPIKE3_EMU=1
export MESA_SHADER_CACHE_DIR=/tmp/cache/mesa

mountpoint() {
  grep -qs " $1 " /proc/mounts
}

mount_fs() {
  type="$1"
  src="$2"
  dst="$3"
  opts="$4"
  mkdir -p "$dst"
  if ! mountpoint "$dst"; then
    mount -t "$type" -o "$opts" "$src" "$dst" 2>/dev/null || true
  fi
}

cmdline_value() {
  key="$1"
  tr ' ' '\n' < /proc/cmdline | sed -n "s/^$key=//p" | tail -n 1
}

mount_fs proc proc /proc defaults
mount_fs sysfs sysfs /sys defaults
mount_fs devtmpfs devtmpfs /dev mode=0755
mount_fs devpts devpts /dev/pts gid=5,mode=620,ptmxmode=0666
mount_fs tmpfs tmpfs /run mode=0755,nosuid,nodev
mount_fs tmpfs tmpfs /tmp mode=1777
mount_fs tmpfs tmpfs /dev/shm mode=1777,nosuid,nodev

mkdir -p /tmp/cache/mesa /connectivity/dump/log/spike-emu /connectivity/dump/cores
mkdir -p /connectivity/dump/spike-emu
mkdir -p /connectivity/alsa /connectivity/bluetooth /connectivity/bluealsa
mkdir -p /var/lib
ln -sfn /connectivity/alsa /var/lib/alsa
ln -sfn /connectivity/bluetooth /var/lib/bluetooth
ln -sfn /connectivity/bluealsa /var/lib/bluealsa

# Restricted QEMU forwarding exposes only the local mock service. This is a
# generated-emulator option, never a change to the evidence network config.
if [ "$(cmdline_value spike3.local_ic)" = 1 ]; then
  modprobe virtio_net || echo "Local IC: failed to load virtio_net" >&2
  ip link set lo up
  ip link set eth0 up
  ip addr replace 10.0.2.15/24 dev eth0
  ip route replace default via 10.0.2.2 dev eth0
fi

hostname spike3-emu 2>/dev/null || true
syslogd 2>/dev/null || true
klogd 2>/dev/null || true

hw_log=/connectivity/dump/log/spike-emu/hardware.log
{
  echo "hardware setup starting"
  for module in drm drm_kms_helper virtio virtio_ring virtio_pci virtio_gpu virtio_input evdev 8250 8250_pci snd_hda_intel; do
    if modprobe "$module" 2>/dev/null; then
      echo "modprobe $module: ok"
    else
      echo "modprobe $module: failed"
    fi
  done
  module_root="/lib/modules/$(uname -r)/kernel"
  for module_path in \
    "$module_root/drivers/char/virtio_console.ko" \
    "$module_root/drivers/virtio/virtio_input.ko" \
    "$module_root/drivers/input/evdev.ko" \
    "$module_root/sound/soundcore.ko" \
    "$module_root/sound/core/snd.ko" \
    "$module_root/sound/core/snd-timer.ko" \
    "$module_root/sound/core/snd-pcm.ko" \
    "$module_root/sound/core/snd-hwdep.ko" \
    "$module_root/sound/hda/snd-hda-core.ko" \
    "$module_root/sound/pci/hda/snd-hda-codec.ko" \
    "$module_root/drivers/leds/trigger/ledtrig-audio.ko" \
    "$module_root/sound/pci/hda/snd-hda-codec-generic.ko" \
    "$module_root/sound/hda/snd-intel-dspcfg.ko" \
    "$module_root/sound/pci/hda/snd-hda-intel.ko"; do
    module_name="$(basename "$module_path" .ko | tr '-' '_')"
    if [ -f "$module_path" ] && insmod "$module_path" 2>/dev/null; then
      echo "insmod $module_path: ok"
    elif grep -q "^$module_name " /proc/modules 2>/dev/null; then
      echo "insmod $module_path: already loaded"
    else
      echo "insmod $module_path: failed"
    fi
  done
} >>"$hw_log" 2>&1
for _ in 1 2 3 4 5 6 7 8 9 10; do
  [ -e /dev/dri/card0 ] && break
  sleep 0.2
done
for _ in 1 2 3 4 5 6 7 8 9 10; do
  [ -e /dev/snd/pcmC0D0p ] && break
  sleep 0.2
done
if [ -e /dev/dri/card0 ] && [ ! -e /dev/dri/card1 ]; then
  ln -s card0 /dev/dri/card1 2>/dev/null || true
fi
{
  echo "--- /dev/dri ---"
  ls -l /dev/dri 2>&1 || true
  echo "--- /sys/class/drm ---"
  ls -l /sys/class/drm 2>&1 || true
  echo "--- lsmod drm/virtio ---"
  lsmod 2>/dev/null | grep -E 'drm|virtio' || true
  echo "--- /dev/snd ---"
  ls -l /dev/snd 2>&1 || true
  echo "--- ALSA cards/PCM ---"
  cat /proc/asound/cards 2>&1 || true
  cat /proc/asound/pcm 2>&1 || true
} >>"$hw_log" 2>&1

/usr/local/spike-emu/bin/setup-fake-devices.sh
/usr/local/spike-emu/bin/guest-control-agent.sh &
/usr/local/spike-emu/bin/keyboard-switch-relay \
  >>/connectivity/dump/log/spike-emu/keyboard-relay.log 2>&1 &

autostart="$(cmdline_value spike3.autostart)"
[ -n "$autostart" ] || autostart=boot-display

echo "SPIKE3 emulator init complete; autostart=$autostart" >/dev/console
(
  /usr/local/spike-emu/bin/launch-target.sh "$autostart" 2>&1
) | tee /connectivity/dump/log/spike-emu/launch.log >/dev/console &

# Explicit local debugger console; absent from normal launches. The host must
# also add a private virtserialport named spike3.diagnostic.
if [ "$(cmdline_value spike3.startup_diagnostics)" = 1 ]; then
  (
    while true; do
      for namefile in /sys/class/virtio-ports/*/name; do
        [ "$(cat "$namefile")" = "spike3.diagnostic" ] || continue
        port=/dev/$(basename "$(dirname "$namefile")")
        ( exec 3<>"$port"; /bin/sh <&3 >&3 2>&1 )
      done
      sleep 1
    done
  ) &
fi

while true; do
  sleep 3600
done
