#!/bin/sh
# Prepara una máquina con adJ ya instalado para trabajar con Crush y DeepSeek.
# Ejecutar después de inst-adJ.sh.
# Dominio público de acuerdo a legislación colombiana.
# http://www.pasosdejesus.org/dominio_publico_colombia.html
# 2026. vtamara@pasosdeJesus.org

# Configuración esperada en el ambiente:
#   IA_USER     - Usuario que usará Crush/DeepSeek (requerido)
#   NFS_SERVER  - IP o nombre del servidor NFS (opcional, ej: 100.64.1.2)
#   NFS_PATH    - Ruta exportada en el servidor NFS (opcional, ej: /var/www)
# Si no se definen NFS_*, /var/www será directorio local.

# NFS_SERVER y NFS_PATH se detectan automáticamente o se reciben del ambiente.
# Con 'local interface' de vmd, el anfitrión es el gateway de la VM.
# vmd asigna IP 100.64.N.3 a la VM y 100.64.N.1 al anfitrión via DHCP interno.

if [ -z "${NFS_SERVER}" ]; then
	NFS_SERVER=$(route -n get default 2>/dev/null | awk '/gateway/ {print $2}')
fi
NFS_SERVER="${NFS_SERVER:-100.64.1.1}"
NFS_PATH="${NFS_PATH:-/var/www}"

set -e

if [ -z "$IA_USER" ]; then
	echo "Error: Defina IA_USER con el nombre del usuario que usará Crush/DeepSeek"
	echo "  Ej: doas IA_USER=vtamara sh prep-vm-ia"
	exit 1
fi

HOME_IA="/home/${IA_USER}"

echo "=== prep-vm-ia: Preparando para Crush/DeepSeek (usuario: ${IA_USER}) ==="

# ---- timecounter (VM) ----
echo "[timecounter] Configurando..."
if ! sysctl kern.timecounter.hardware 2>/dev/null | grep -q pvclock0; then
	sysctl kern.timecounter.hardware=pvclock0 2>/dev/null || true
	if ! grep -q '^kern.timecounter.hardware=pvclock0' /etc/sysctl.conf 2>/dev/null; then
		echo 'kern.timecounter.hardware=pvclock0' >> /etc/sysctl.conf
	fi
	echo "  + pvclock0"
else
	echo "  = pvclock0 ya activo"
fi

# ---- ntpd con -s ----
echo "[ntpd] Configurando..."
if ! grep -q '^ntpd_flags=-s' /etc/rc.conf.local 2>/dev/null; then
	if grep -q '^ntpd_flags' /etc/rc.conf.local 2>/dev/null; then
		sed -i 's/^ntpd_flags=.*/ntpd_flags=-s/' /etc/rc.conf.local
	else
		echo 'ntpd_flags=-s' >> /etc/rc.conf.local
	fi
	rcctl restart ntpd 2>/dev/null || true
	echo "  + ntpd_flags=-s"
else
	echo "  = ntpd_flags ya configurado"
fi

# ---- npm config ----
echo "[npm] Configurando..."
NPMRC="${HOME_IA}/.npmrc"
if [ ! -f "$NPMRC" ] || ! grep -q 'prefix' "$NPMRC" 2>/dev/null; then
	echo 'prefix=/usr/local' > "$NPMRC"
	chown "${IA_USER}:${IA_USER}" "$NPMRC"
	echo "  + .npmrc configurado"
else
	echo "  = .npmrc ya configurado"
fi

# ---- Montajes NFS ----
echo "[nfs] Configurando montajes..."
if [ -n "${NFS_SERVER}" ] && [ -n "${NFS_PATH}" ]; then
	for dir in /var/www ; do
		if mount | grep -q "on ${dir} "; then
			echo "  = ${dir} ya montado"
		else
			mkdir -p "$dir"
			case "$dir" in
				*)
					opts="rw,nosuid,soft,intr,tcp"
					;;
			esac
			mount -t nfs -o "$opts" \
				"${NFS_SERVER}:${NFS_PATH}${dir}" "$dir" 2>/dev/null || true
			if ! grep -q " ${dir} " /etc/fstab 2>/dev/null; then
				echo "${NFS_SERVER}:${NFS_PATH}${dir} ${dir} nfs ${opts} 0 0" >> /etc/fstab
			fi
			echo "  + ${dir} montado via NFS"
		fi
	done
else
	# Sin NFS: solo asegurar /var/www local
	if [ ! -d /var/www ]; then
		mkdir -p /var/www
		chown root:servicio /var/www
		chmod 755 /var/www
		echo "  + /var/www creado como directorio local"
	else
		echo "  = /var/www ya existe"
	fi
fi

# ---- Go (requerido por Crush) ----
echo "[go] Instalando Go..."
GO_VERSION="1.26.5"
GO_TGZ="go${GO_VERSION}.openbsd-amd64.tar.gz"
GO_URL="https://go.dev/dl/${GO_TGZ}"
if [ -x /usr/local/go/bin/go ]; then
	go_ver=$(/usr/local/go/bin/go version 2>/dev/null | awk '{print $3}')
	echo "  = Go ya instalado: ${go_ver}"
else
	echo "  + descargando Go ${GO_VERSION}..."
	ftp -o "/tmp/${GO_TGZ}" "$GO_URL"
	echo "  + instalando en /usr/local/go..."
	rm -rf /usr/local/go
	tar -C /usr/local -xzf "/tmp/${GO_TGZ}"
	rm -f "/tmp/${GO_TGZ}"
	echo "  + Go ${GO_VERSION} instalado"
fi

# Asegurar GOPATH para el usuario
GOBIN="${HOME_IA}/go/bin"
if ! grep -q '/go/bin' "${HOME_IA}/.profile" 2>/dev/null; then
	echo "export GOPATH=${HOME_IA}/go" >> "${HOME_IA}/.profile"
	echo "export PATH=\$PATH:/usr/local/go/bin:${GOBIN}" >> "${HOME_IA}/.profile"
	chown "${IA_USER}:${IA_USER}" "${HOME_IA}/.profile"
fi
mkdir -p "$GOBIN"
chown -R "${IA_USER}:${IA_USER}" "${HOME_IA}/go" 2>/dev/null || true

# ---- Crush ----
echo "[crush] Instalando Crush..."
if [ -x "${GOBIN}/crush" ]; then
	echo "  = Crush ya instalado: $(${GOBIN}/crush --version 2>/dev/null || echo ok)"
else
	echo "  + compilando Crush (puede tomar varios minutos)..."
	ulimit -d 20000000 2>/dev/null || true
	su - "${IA_USER}" -c "PATH=\$PATH:/usr/local/go/bin:${GOBIN} GOPATH=${HOME_IA}/go go install github.com/charmbracelet/crush@latest"
	echo "  + Crush instalado en ${GOBIN}/crush"
fi



# ---- Crush config ----
echo "[crush] Configurando..."
CRUSH_DIR="${HOME_IA}/.config/crush"
CRUSH_JSON="${CRUSH_DIR}/crush.json"

if [ ! -f "$CRUSH_JSON" ]; then
	mkdir -p "$CRUSH_DIR"
	cat > "$CRUSH_JSON" << 'FINCRUSH'
{
  "providers": {
    "deepseek": {
      "type": "openai",
      "base_url": "https://api.deepseek.com/v1",
      "api_key": "DEEPSEEK_API_KEY",
      "models": [
        { "id": "deepseek-chat", "name": "DeepSeek V4" },
        { "id": "deepseek-reasoner", "name": "DeepSeek Reasoner" }
      ]
    }
  },
  "options": {
    "tui": {
      "transparent": false
    }
  },
  "providers-x": {
    "deepseek-thinking": {
      "type": "anthropic",
      "base_url": "https://api.deepseek.com/anthropic",
      "api_key": "DEEPSEEK_API_KEY",
      "models": [
        { "id": "deepseek-reasoner", "name": "DeepSeek Thinking" }
      ]
    }
  }
}
FINCRUSH
	chown -R "${IA_USER}:${IA_USER}" "$CRUSH_DIR"
	echo "  + crush.json creado (reemplace DEEPSEEK_API_KEY)"
else
	echo "  = crush.json ya existe"
fi

# ---- Crush runtime ----
CRUSH_RUNTIME="${HOME_IA}/.crush"
if [ ! -d "$CRUSH_RUNTIME" ]; then
	mkdir -p "$CRUSH_RUNTIME/logs"
	chown -R "${IA_USER}:${IA_USER}" "$CRUSH_RUNTIME"
	echo "  + directorio .crush creado"
else
	echo "  = directorio .crush ya existe"
fi

# ---- pnpm global ----
echo "[pnpm] Instalando pnpm..."
if ! which pnpm > /dev/null 2>&1; then
	npm install -g pnpm@10.34.5 2>&1 | tail -3
	echo "  + pnpm instalado globalmente"
else
	echo "  = pnpm ya instalado: $(pnpm --version)"
fi

# ---- pnpm store compartido ----
echo "[pnpm-store] Configurando..."
PNPM_RC="${HOME_IA}/.config/pnpm/rc"
if [ ! -f "$PNPM_RC" ] || ! grep -q 'store-dir' "$PNPM_RC" 2>/dev/null; then
	mkdir -p "$(dirname "$PNPM_RC")"
	echo 'store-dir=/var/www/adJ-ia/.store' > "$PNPM_RC"
	chown -R "${IA_USER}:${IA_USER}" "$(dirname "$PNPM_RC")"
	echo "  + pnpm store configurado en /var/www/adJ-ia/.store"
else
	echo "  = pnpm store ya configurado"
fi

# ---- Paquete m (si está disponible) ----
echo "[m] Verificando..."
if ! which m > /dev/null 2>&1; then
	if pkg_info -e m > /dev/null 2>&1; then
		echo "  = m ya instalado via paquete"
	else
		echo "  ! m no disponible — instalar con pkg_add m cuando el porte esté listo"
	fi
else
	echo "  = m ya disponible: $(which m)"
fi

echo ""
echo "=== prep-vm-ia completado ==="
echo "Recuerde reemplazar DEEPSEEK_API_KEY en ${CRUSH_JSON}"
echo "Si m no está disponible, puede usar el árbol de desarrollo:"
echo "  ~/comp/m/bin/m ai:framework"
