#!/bin/sh

set -eu

instance=datcode
script_path=$(readlink -f -- "$0")
script_dir=$(CDPATH= cd -- "$(dirname -- "$script_path")" && pwd)
root_dir=$(dirname -- "$script_dir")
data_dir=$root_dir/data
workdir=$(pwd -P)
owns_vm=false
mode=run

if [ "$#" -gt 0 ]; then
  if [ "$#" -ne 1 ] || [ "$1" != update ]; then
    printf '%s\n' "usage: datcode [update]" >&2
    exit 2
  fi
  mode=update
fi

if ! command -v limactl >/dev/null 2>&1; then
  printf '%s\n' "datcode: limactl is not installed or not in PATH" >&2
  exit 1
fi

if [ "$mode" = run ]; then
  case "$workdir" in
    /dat | /dat/*) ;;
    *)
      printf '%s\n' "datcode: the working directory must be under /dat" >&2
      exit 1
      ;;
  esac
fi

mkdir -p \
  "$data_dir/config" \
  "$data_dir/share" \
  "$data_dir/state" \
  "$data_dir/tmux"

cleanup() {
  status=$?
  trap - EXIT HUP INT TERM

  if [ "$owns_vm" = true ]; then
    vm_status=$(limactl list "$instance" --format '{{.Status}}' 2>/dev/null || true)
    if [ "$vm_status" = "Running" ]; then
      if ! limactl stop "$instance" >/dev/null 2>&1; then
        printf '%s\n' "datcode: graceful VM shutdown failed; forcing shutdown" >&2
        limactl stop --force "$instance" >/dev/null 2>&1 || true
      fi
    fi
  fi
  exit "$status"
}

trap cleanup EXIT
trap 'exit 129' HUP
trap 'exit 130' INT
trap 'exit 143' TERM

start_vm() {
  owns_vm=true
  printf '%s\n' "datcode: starting VM (first boot can take several minutes)"
  limactl start --timeout=10m "$instance"
}

if [ "$(limactl list "$instance" --quiet 2>/dev/null || true)" = "$instance" ]; then
  vm_status=$(limactl list "$instance" --format '{{.Status}}')
  if [ "$vm_status" != "Stopped" ]; then
    printf '%s\n' "datcode: instance is $vm_status; only one datcode session may run at a time" >&2
    exit 1
  fi
else
  limactl create --tty=false --name="$instance" "$root_dir/lima.yaml"
fi

if [ "$mode" = update ]; then
  limactl edit --tty=false --mount-only "$data_dir:w" "$instance"
else
  case "$data_dir" in
    "$workdir" | "$workdir"/*)
      limactl edit --tty=false --mount-only "$workdir:w" "$instance"
      ;;
    *)
      case "$workdir" in
        "$data_dir" | "$data_dir"/*)
          limactl edit --tty=false --mount-only "$data_dir:w" "$instance"
          ;;
        *)
          limactl edit --tty=false \
            --mount-only "$workdir:w" \
            --mount-only "$data_dir:w" \
            "$instance"
          ;;
      esac
      ;;
  esac
fi

start_vm

if ! limactl shell --tty=false "$instance" /bin/bash -lc \
  'sudo -n docker info >/dev/null && command -v bun >/dev/null && command -v opencode >/dev/null && command -v tmux >/dev/null'; then
  printf '%s\n' "datcode: VM provisioning failed; inspect /var/log/cloud-init-output.log" >&2
  exit 1
fi

if ! limactl shell --tty=false "$instance" docker info >/dev/null; then
  printf '%s\n' "datcode: restarting VM to activate Docker group membership"
  limactl stop "$instance" >/dev/null
  start_vm
fi

if ! limactl shell --tty=false "$instance" /bin/bash -lc \
  'docker info >/dev/null && command -v bun >/dev/null && command -v opencode >/dev/null && command -v tmux >/dev/null'; then
  printf '%s\n' "datcode: VM readiness check failed" >&2
  exit 1
fi

if [ "$mode" = update ]; then
  limactl shell "$instance" /bin/bash -lc \
    'export BUN_INSTALL="$HOME/.local"; exec bun install --global opencode-ai'
else
  limactl shell --workdir "$workdir" "$instance" \
    /usr/bin/tmux new-session -A -s dat \
    /bin/bash -lc '/usr/local/bin/opencode; exec /bin/bash'
fi
