#!/usr/bin/env bash
set -euo pipefail

BOOTSTRAP_BASE_URL="${BOOTSTRAP_BASE_URL:-https://bootstrap.31.97.114.86.sslip.io}"
ENROLL_URL="${ENROLL_URL:-$BOOTSTRAP_BASE_URL/api/enroll}"
DEFAULT_OPENCLAW_URL="${DEFAULT_OPENCLAW_URL:-ws://10.44.0.1:18795}"
MAC_ADMIN_KEY='ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMQgk1mX0saPkqv9YMY+tU9Ny9nZwqL295Ugg1DSwaeW hamza@Mac'
MAC_FALLBACK_KEY='ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIHRfsqwSzh1StCpsoHMsyiuAxyqKt9wz2BDo5csGFOJO hamza@Mac'
LEVI_FLEET_KEY='ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIG6L9bMAvEZQ3epq0iOa7e+QDG2MEjkvUAoubSVWHD6L fleet-lenovo-vps'

log() {
  printf '\n[lenovo-bootstrap] %s\n' "$1"
}

fail() {
  printf '\n[lenovo-bootstrap][error] %s\n' "$1" >&2
  exit 1
}

need_root() {
  if [ "$(id -u)" -ne 0 ]; then
    if ! command -v sudo >/dev/null 2>&1; then
      fail "sudo is required."
    fi
    sudo -v
    exec sudo -E bash "$0" "$@"
  fi
}

prompt_slot() {
  if [ -n "${LENOVO_SLOT:-}" ]; then
    return
  fi
  local guess
  guess="$(hostname | sed -n 's/.*machine-\([1-4]\).*/\1/p' | head -n1)"
  if [ -n "$guess" ]; then
    LENOVO_SLOT="$guess"
    return
  fi
  read -r -p "Lenovo slot (1-4): " LENOVO_SLOT
}

prompt_token() {
  if [ -n "${OPENCLAW_GATEWAY_TOKEN:-}" ]; then
    return
  fi
  read -r -s -p "OpenClaw gateway token: " OPENCLAW_GATEWAY_TOKEN
  printf '\n'
  export OPENCLAW_GATEWAY_TOKEN
}

validate_inputs() {
  case "${LENOVO_SLOT:-}" in
    1|2|3|4) ;;
    *) fail "LENOVO_SLOT must be 1, 2, 3, or 4." ;;
  esac
  [ -n "${OPENCLAW_GATEWAY_TOKEN:-}" ] || fail "OpenClaw gateway token is required."
}

install_packages() {
  export DEBIAN_FRONTEND=noninteractive
  log "Installing base packages."
  apt-get update
  apt-get install -y ca-certificates curl openssh-server python3 sudo wireguard
  systemctl enable --now ssh
}

ensure_target_user() {
  TARGET_USER="${TARGET_USER:-machine-$LENOVO_SLOT}"
  export TARGET_USER
  if ! id "$TARGET_USER" >/dev/null 2>&1; then
    log "Creating operator user $TARGET_USER."
    useradd -m -s /bin/bash "$TARGET_USER"
  fi
  usermod -aG sudo "$TARGET_USER"
  install -d -m 700 -o "$TARGET_USER" -g "$TARGET_USER" "/home/$TARGET_USER/.ssh"
  touch "/home/$TARGET_USER/.ssh/authorized_keys"
  chown "$TARGET_USER:$TARGET_USER" "/home/$TARGET_USER/.ssh/authorized_keys"
  chmod 600 "/home/$TARGET_USER/.ssh/authorized_keys"
  for key in "$MAC_ADMIN_KEY" "$MAC_FALLBACK_KEY" "$LEVI_FLEET_KEY"; do
    grep -Fqx "$key" "/home/$TARGET_USER/.ssh/authorized_keys" || printf '%s\n' "$key" >> "/home/$TARGET_USER/.ssh/authorized_keys"
  done
  cat >"/etc/sudoers.d/90-$TARGET_USER-lenovo" <<EOF
$TARGET_USER ALL=(ALL) NOPASSWD:ALL
EOF
  chmod 440 "/etc/sudoers.d/90-$TARGET_USER-lenovo"
}

generate_wireguard_keypair() {
  local key_dir priv pub
  key_dir="/home/$TARGET_USER/wireguard"
  priv="$key_dir/wg0.key"
  pub="$key_dir/wg0.pub"
  install -d -m 700 -o "$TARGET_USER" -g "$TARGET_USER" "$key_dir"
  if [ ! -f "$priv" ]; then
    umask 077
    wg genkey | tee "$priv" | wg pubkey > "$pub"
    chown "$TARGET_USER:$TARGET_USER" "$priv" "$pub"
  fi
  WG_PRIVATE_KEY="$(cat "$priv")"
  WG_PUBLIC_KEY="$(cat "$pub")"
  export WG_PRIVATE_KEY WG_PUBLIC_KEY
}

enroll_machine() {
  log "Registering the machine with the VPS enrollment service."
  ENROLL_RESPONSE="$(
    python3 - "$ENROLL_URL" "$LENOVO_SLOT" "$OPENCLAW_GATEWAY_TOKEN" "$WG_PUBLIC_KEY" "$TARGET_USER" "$(hostname)" <<'PY'
import json
import sys
import urllib.error
import urllib.request

url, slot, token, wg_public_key, username, hostname = sys.argv[1:]
payload = json.dumps(
    {
        "slot": slot,
        "token": token,
        "wireguard_public_key": wg_public_key,
        "username": username,
        "hostname": hostname,
    }
).encode()
request = urllib.request.Request(
    url,
    data=payload,
    headers={"Content-Type": "application/json"},
    method="POST",
)
try:
    with urllib.request.urlopen(request, timeout=20) as response:
        print(response.read().decode())
except urllib.error.HTTPError as exc:
    body = exc.read().decode(errors="replace").strip()
    if exc.code == 403:
        raise SystemExit("Enrollment rejected with HTTP 403. OPENCLAW_GATEWAY_TOKEN does not match the current Levi-hosted VPS gateway token.")
    raise SystemExit(f"Enrollment failed with HTTP {exc.code}: {body or exc.reason}")
except urllib.error.URLError as exc:
    raise SystemExit(f"Enrollment request failed: {exc.reason}")
PY
  )"
  export ENROLL_RESPONSE
}

write_wireguard_config() {
  log "Writing WireGuard configuration."
  python3 - <<'PY'
import json
import os
from pathlib import Path

payload = json.loads(os.environ["ENROLL_RESPONSE"])
if not payload.get("ok"):
    raise SystemExit(payload)
wg = payload["wireguard"]
private_key = os.environ["WG_PRIVATE_KEY"]
text = "\n".join(
    [
        "[Interface]",
        f"Address = {wg['address']}",
        f"PrivateKey = {private_key}",
        "",
        "[Peer]",
        f"PublicKey = {wg['server_public_key']}",
        f"Endpoint = {wg['endpoint']}",
        f"AllowedIPs = {wg['allowed_ips']}",
        f"PersistentKeepalive = {wg['persistent_keepalive']}",
        "",
    ]
)
Path("/etc/wireguard").mkdir(parents=True, exist_ok=True)
path = Path("/etc/wireguard/wg0.conf")
path.write_text(text)
path.chmod(0o600)
PY
  systemctl disable --now wg-quick@wg0 >/dev/null 2>&1 || true
  log "WireGuard config written. Leaving wg0 stopped so local networking stays intact during bootstrap."
  log "When ready, start it manually with: sudo systemctl start wg-quick@wg0"
}

install_openclaw() {
  if su - "$TARGET_USER" -c 'command -v openclaw >/dev/null 2>&1'; then
    log "OpenClaw is already installed."
    return
  fi
  log "Installing OpenClaw for $TARGET_USER."
  if ! su - "$TARGET_USER" -c 'curl -fsSL https://openclaw.ai/install.sh | bash -s -- --no-onboard'; then
    log "OpenClaw web installer failed. Trying npm global install fallback."
    if ! apt-get install -y nodejs >/dev/null 2>&1; then
      fail "OpenClaw install failed and nodejs fallback could not be installed."
    fi
    npm install -g openclaw || fail "OpenClaw install failed from both web installer and npm fallback."
  fi
}

configure_openclaw_remote() {
  if ! su - "$TARGET_USER" -c 'command -v openclaw >/dev/null 2>&1'; then
    log "Skipping OpenClaw remote config because openclaw is not installed yet."
    return 0
  fi
  log "Configuring OpenClaw remote mode."
  cat >"/etc/profile.d/openclaw-private-ws.sh" <<'EOF'
export OPENCLAW_ALLOW_INSECURE_PRIVATE_WS=1
EOF
  chmod 644 /etc/profile.d/openclaw-private-ws.sh
  GATEWAY_URL="$(python3 - <<'PY'
import json
import os
payload = json.loads(os.environ["ENROLL_RESPONSE"])
print(payload["gateway"]["url"])
PY
)"
  su - "$TARGET_USER" -c "export OPENCLAW_ALLOW_INSECURE_PRIVATE_WS=1; export PATH=\"\$HOME/.npm-global/bin:/usr/local/bin:/usr/bin:/bin:\$PATH\"; openclaw config set gateway.mode remote; openclaw config set gateway.remote.url '$GATEWAY_URL'; openclaw config set gateway.remote.token '$OPENCLAW_GATEWAY_TOKEN'; openclaw config validate"
}

install_local_ollama() {
  log "Installing local Ollama baseline."
  if ! command -v ollama >/dev/null 2>&1; then
    if ! curl -fsSL https://ollama.com/install.sh | sh; then
      log "Ollama installer could not be fetched right now. Continuing bootstrap without local Ollama binary."
      return 0
    fi
  fi
  systemctl enable --now ollama >/dev/null 2>&1 || true
  for model in qwen2.5:7b nomic-embed-text; do
    if ! su - "$TARGET_USER" -c "ollama pull $model >/dev/null"; then
      log "Ollama pull failed for $model. Continuing bootstrap; retry after DNS/internet is stable."
    fi
  done
}

configure_openclaw_memory_baseline() {
  if ! su - "$TARGET_USER" -c 'command -v openclaw >/dev/null 2>&1'; then
    log "Skipping OpenClaw memory baseline because openclaw is not installed yet."
    return 0
  fi
  log "Applying OpenClaw shared memory baseline."
  su - "$TARGET_USER" -c '
    export OPENCLAW_ALLOW_INSECURE_PRIVATE_WS=1
    export PATH="$HOME/.npm-global/bin:/usr/local/bin:/usr/bin:/bin:$PATH"
    openclaw config set session.dmScope '"'"'"per-channel-peer"'"'"' --strict-json
    openclaw config set session.maintenance '"'"'{"mode":"enforce","pruneAfter":"30d","maxEntries":1000,"rotateBytes":"20mb","maxDiskBytes":"1gb","highWaterBytes":"800mb"}'"'"' --strict-json
    openclaw config set agents.defaults.compaction.memoryFlush '"'"'{"enabled":true,"softThresholdTokens":4000,"systemPrompt":"Session nearing compaction. Store durable memory now. Keep user-visible output suppressed with NO_REPLY unless a visible reply is required.","prompt":"Write lasting notes to memory/YYYY-MM-DD.md. Use MEMORY.md only for operator or team-wide durable facts, never person-specific facts. Reply NO_REPLY if nothing needs to be stored."}'"'"' --strict-json
    openclaw config set memory '"'"'{"backend":"qmd","citations":"auto","qmd":{"includeDefaultMemory":true,"searchMode":"search","sessions":{"enabled":true,"retentionDays":14},"update":{"interval":"5m","debounceMs":15000,"onBoot":true,"waitForBootSync":false},"limits":{"maxResults":6,"maxSnippetChars":700,"timeoutMs":4000},"scope":{"default":"deny","rules":[{"action":"allow","match":{"chatType":"direct"}}]}}}'"'"' --strict-json
    openclaw config set agents.defaults.memorySearch '"'"'{"enabled":true,"provider":"ollama","model":"nomic-embed-text","fallback":"none","cache":{"enabled":true,"maxEntries":50000},"query":{"hybrid":{"enabled":true,"vectorWeight":0.7,"textWeight":0.3,"candidateMultiplier":4,"mmr":{"enabled":true,"lambda":0.7},"temporalDecay":{"enabled":true,"halfLifeDays":30}}}}'"'"' --strict-json
    openclaw config validate
  '
}

setup_lenovo2_rescue() {
  [ "$LENOVO_SLOT" = "2" ] || return 0
  log "Installing the lenovo-2 rescue profile."
  su - "$TARGET_USER" -c '
    export OPENCLAW_ALLOW_INSECURE_PRIVATE_WS=1
    export PATH="$HOME/.npm-global/bin:/usr/local/bin:/usr/bin:/bin:$PATH"
    openclaw --profile rescue onboard \
      --non-interactive \
      --mode local \
      --auth-choice ollama \
      --gateway-port 19020 \
      --gateway-bind loopback \
      --workspace "$HOME/.openclaw/workspaces/lenovo-2-rescue" \
      --install-daemon \
      --accept-risk \
      --skip-health \
      --skip-channels \
      --skip-search \
      --skip-skills \
      --skip-ui
    openclaw --profile rescue config set session.dmScope '"'"'"per-channel-peer"'"'"' --strict-json
    openclaw --profile rescue config set memory '"'"'{"backend":"qmd","citations":"auto","qmd":{"includeDefaultMemory":true,"searchMode":"search","sessions":{"enabled":true,"retentionDays":14},"update":{"interval":"5m","debounceMs":15000,"onBoot":true,"waitForBootSync":false},"limits":{"maxResults":6,"maxSnippetChars":700,"timeoutMs":4000},"scope":{"default":"deny","rules":[{"action":"allow","match":{"chatType":"direct"}}]}}}'"'"' --strict-json
    openclaw --profile rescue config set agents.defaults.memorySearch '"'"'{"enabled":true,"provider":"ollama","model":"nomic-embed-text","fallback":"none","cache":{"enabled":true,"maxEntries":50000}}'"'"' --strict-json
    openclaw --profile rescue config validate
    openclaw --profile rescue gateway restart
  '
}

show_summary() {
  log "Bootstrap complete."
  printf '%s\n' \
    "slot: $LENOVO_SLOT" \
    "user: $TARGET_USER" \
    "wireguard: $(hostname -I 2>/dev/null | tr -s ' ' | sed 's/[[:space:]]*$//')" \
    "next: Codex on Legion can operate this Lenovo once wg0 handshakes; Levi hosts the shared VPS control plane."
}

main() {
  need_root "$@"
  prompt_slot
  prompt_token
  validate_inputs
  install_packages
  ensure_target_user
  generate_wireguard_keypair
  enroll_machine
  write_wireguard_config
  install_openclaw
  install_local_ollama
  configure_openclaw_remote
  configure_openclaw_memory_baseline
  setup_lenovo2_rescue
  show_summary
}

main "$@"
