#!/usr/bin/env bash
# Verificate HELIX v1.8 — online installer + the installed `verificate` CLI.
#
#   Install:   curl -fsSL https://get.verificate.ai | sudo bash
#   Then:      sudo verificate refresh    (new/renewed license key — seconds, no re-download)
#              verificate status          (containers, health, license days remaining)
#   (One-shot refresh without the CLI: curl -fsSL https://get.verificate.ai | sudo bash -s refresh)
#
# A successful install copies this script to /usr/local/bin/verificate. Invoked by that name
# with no arguments it shows usage — it NEVER silently reinstalls (a bare re-install would
# consume an activation seat).
#
# What it does: verifies this host can actually run the bundle (Linux x86_64, AVX-512, RAM, disk,
# Docker), asks for your install key, activates against get.verificate.ai, downloads the licensed
# images + model with resume support, verifies every sha256, and starts the stack. After install
# the runtime is FULLY OFFLINE — nothing phones home; the signed license file enforces expiry
# locally. `refresh` swaps in a new license token without touching images or the model.
#
# Every failure is loud and specific. No silent fallbacks.
set -euo pipefail

VERIFICATE_OFFICIAL_URL="https://get.verificate.ai"
VERIFICATE_URL="${VERIFICATE_URL:-$VERIFICATE_OFFICIAL_URL}"
INSTALL_DIR="${VERIFICATE_INSTALL_DIR:-/opt/verificate-helix}"
MIN_RAM_GB=80
MIN_DISK_GB=70

say()  { printf '\033[1;36m[verificate]\033[0m %s\n' "$*"; }
fail() { printf '\033[1;31m[verificate] ERROR:\033[0m %s\n' "$*" >&2; exit 1; }

# ---- helpers ---------------------------------------------------------------------------------------
need_cmd() { command -v "$1" >/dev/null 2>&1 || fail "'$1' is required but not installed$2"; }

json_get() {  # json_get <file> <dotted.path>  — python3 does the JSON heavy lifting (no jq dep)
  python3 - "$1" "$2" <<'PY'
import json, sys
obj = json.load(open(sys.argv[1]))
for part in sys.argv[2].split("."):
    obj = obj[int(part)] if isinstance(obj, list) else obj[part]
print(obj if not isinstance(obj, (dict, list)) else json.dumps(obj))
PY
}

prompt_key() {
  if [ -n "${VERIFICATE_INSTALL_KEY:-}" ]; then
    INSTALL_KEY="$VERIFICATE_INSTALL_KEY"
    return
  fi
  # curl|bash leaves stdin consumed by the pipe — read the key from the terminal directly.
  [ -r /dev/tty ] || fail "no terminal available to prompt for the key — set VERIFICATE_INSTALL_KEY instead"
  printf 'Enter your Verificate install key (vik-...): ' > /dev/tty
  read -r INSTALL_KEY < /dev/tty
  case "$INSTALL_KEY" in vik-*) ;; *) fail "that does not look like an install key (expected vik-...)" ;; esac
}

collect_hw() {
  ARCH="$(uname -m)"
  CPU_FLAGS="$(grep -m1 '^flags' /proc/cpuinfo | cut -d: -f2- || true)"
  RAM_GB=$(( $(grep -m1 MemTotal /proc/meminfo | awk '{print $2}') / 1048576 ))
  # Root-only install dir: downloaded artifacts sit here between sha256 verification and
  # docker load — no non-root user may have write (or even read) access in that window.
  mkdir -p "$INSTALL_DIR"
  chmod 700 "$INSTALL_DIR"
  DISK_GB=$(( $(df -Pk "$INSTALL_DIR" | awk 'NR==2{print $4}') / 1048576 ))
  GPU="none"
  command -v nvidia-smi >/dev/null 2>&1 && GPU="$(nvidia-smi --query-gpu=name --format=csv,noheader 2>/dev/null | head -1 || echo none)"
}

check_host() {
  # Everything trusted (artifact URLs AND their sha256s) comes from this server, so a silently
  # redirected VERIFICATE_URL = arbitrary root code execution. Overrides (staging tests) must be
  # explicit and acknowledged.
  if [ "$VERIFICATE_URL" != "$VERIFICATE_OFFICIAL_URL" ]; then
    [ "${VERIFICATE_URL_ACK:-}" = "1" ] || fail \
      "VERIFICATE_URL is overridden to '$VERIFICATE_URL' (official: $VERIFICATE_OFFICIAL_URL).
  If this is intentional (staging), re-run with VERIFICATE_URL_ACK=1. Otherwise your environment
  may be compromised — do NOT proceed."
    say "WARNING: using overridden server $VERIFICATE_URL (acknowledged)"
  fi
  [ "$(uname -s)" = "Linux" ] || fail "this installer supports Linux only (found $(uname -s))"
  [ "$ARCH" = "x86_64" ] || fail "x86_64 required (found $ARCH)"
  [ "$(id -u)" = "0" ] || fail "run as root: curl -fsSL $VERIFICATE_URL | sudo bash"
  need_cmd python3 " (apt/dnf install python3)"
  need_cmd curl ""
  echo "$CPU_FLAGS" | grep -qw avx512f || fail \
    "this CPU has no AVX-512. The HELIX v1.8 CPU engine is compiled for AVX-512 (AMD Zen4+/Intel
  Sapphire Rapids+) and would crash with an illegal instruction here. Contact info@verificate.ai
  about hardware options."
  [ "$RAM_GB" -ge "$MIN_RAM_GB" ] || fail "${RAM_GB} GiB RAM found; ${MIN_RAM_GB} GiB needed for the 120B model"
  [ "$DISK_GB" -ge "$MIN_DISK_GB" ] || fail "${DISK_GB} GiB free at $INSTALL_DIR; ${MIN_DISK_GB} GiB needed"
  if ! command -v docker >/dev/null 2>&1; then
    say "Docker not found — installing via get.docker.com (the only third-party step)..."
    curl -fsSL https://get.docker.com | sh || fail "Docker install failed — install Docker 24+ manually and re-run"
  fi
  docker compose version >/dev/null 2>&1 || fail "Docker Compose v2 plugin missing (docker-compose-plugin package)"
}

activate() {
  say "Activating against $VERIFICATE_URL ..."
  local req="$INSTALL_DIR/.activate-req.json" resp="$INSTALL_DIR/.activate-resp.json" http
  python3 - "$req" "$INSTALL_KEY" "$ARCH" "$RAM_GB" "$DISK_GB" "$GPU" "$CPU_FLAGS" <<'PY'
import json, sys
json.dump({"install_key": sys.argv[2],
           "hw": {"arch": sys.argv[3], "ram_gb": int(sys.argv[4]), "disk_gb": int(sys.argv[5]),
                  "gpu": sys.argv[6], "cpu_flags": sys.argv[7].strip()}}, open(sys.argv[1], "w"))
PY
  http=$(curl -sS -o "$resp" -w '%{http_code}' -H 'Content-Type: application/json' \
              --data-binary @"$req" "$VERIFICATE_URL/activate") || fail "cannot reach $VERIFICATE_URL"
  rm -f "$req"
  [ "$http" = "200" ] || fail "activation refused (HTTP $http): $(cat "$resp")"
  TIER=$(json_get "$resp" tier)
  say "Activated: tier=$TIER, expires $(date -u -d "@$(json_get "$resp" expires_at)" +%Y-%m-%d 2>/dev/null || json_get "$resp" expires_at)"
}

download_artifacts() {
  local resp="$INSTALL_DIR/.activate-resp.json" n i name url sha size f
  n=$(python3 -c "import json,sys; print(len(json.load(open(sys.argv[1]))['artifacts']))" "$resp")
  mkdir -p "$INSTALL_DIR/downloads"
  for i in $(seq 0 $((n - 1))); do
    name=$(json_get "$resp" "artifacts.$i.name")
    url=$(json_get  "$resp" "artifacts.$i.url")
    sha=$(json_get  "$resp" "artifacts.$i.sha256")
    size=$(json_get "$resp" "artifacts.$i.size")
    f="$INSTALL_DIR/downloads/$name"
    if [ -f "$f" ] && printf '%s  %s\n' "$sha" "$f" | sha256sum -c --quiet 2>/dev/null; then
      say "$name already downloaded and verified — skipping"
      continue
    fi
    say "Downloading $name ($((size / 1048576)) MB, resumable)..."
    curl -fL --retry 5 --retry-all-errors -C - -o "$f" "$url" || fail "download of $name failed — re-run the installer to resume"
    printf '%s  %s\n' "$sha" "$f" | sha256sum -c --quiet || fail "sha256 MISMATCH on $name — corrupt or tampered download, re-run to retry"
    say "$name verified."
  done
}

install_bundle() {
  local resp="$INSTALL_DIR/.activate-resp.json" d="$INSTALL_DIR/downloads"
  say "Loading Docker images..."
  local found_image=0 tarball
  for tarball in "$d"/*image*.tar.gz; do
    [ -e "$tarball" ] || break            # unexpanded glob = no matches
    found_image=1
    gunzip -c "$tarball" | docker load || fail "docker load failed for $tarball"
  done
  [ "$found_image" = "1" ] || fail "no *image*.tar.gz artifacts in the download set — the release bundle manifest is broken; contact info@verificate.ai"
  say "Installing bundle files..."
  tar -xzf "$d/compose-bundle.tar.gz" -C "$INSTALL_DIR" || fail "compose bundle extract failed"
  mkdir -p "$INSTALL_DIR/models" "$INSTALL_DIR/license"
  mv -f "$d"/*.gguf "$INSTALL_DIR/models/" 2>/dev/null || true
  # The bundle always ships a model — catch its absence NOW, not as an engine crash at first start.
  ls "$INSTALL_DIR/models/"*.gguf >/dev/null 2>&1 || fail "no model (.gguf) in the download set — the release bundle is broken; contact info@verificate.ai"
  umask 077
  json_get "$resp" license_token > "$INSTALL_DIR/license/license.vlt"
  json_get "$resp" license_pubkey_hex > "$INSTALL_DIR/license/license_pubkey.hex"
  {
    echo "VERIFICATE_API_KEY=$(json_get "$resp" runtime_api_key)"
    echo "VERIFICATE_LICENSE_PUBKEY=$(json_get "$resp" license_pubkey_hex)"
    echo "# Tuning (defaults shown; see CUSTOMER_RUNBOOK.md):"
    echo "#HELIX_THREADS=24"
    echo "#HELIX_PARALLEL=2"
    echo "#HELIX_CTX=8192"
    echo "#HELIX_HOST_PORT=8000"
  } > "$INSTALL_DIR/.env"
  chmod 600 "$INSTALL_DIR/.env"
  rm -f "$resp"          # contains the one-time runtime key — .env is now its only home
  say "Starting..."
  (cd "$INSTALL_DIR" && docker compose up -d) || fail "docker compose up failed"
}

wait_healthy() {
  say "Waiting for the engine to load the model (first start takes several minutes)..."
  local i
  for i in $(seq 1 120); do
    if curl -sf http://127.0.0.1:8000/health >/dev/null 2>&1; then
      say "HEALTHY. OpenAI-compatible API on http://127.0.0.1:8000"
      say 'Try:  curl -s http://127.0.0.1:8000/v1/chat/completions -H "Authorization: Bearer $(grep ^VERIFICATE_API_KEY '"$INSTALL_DIR"'/.env | cut -d= -f2)" -H "Content-Type: application/json" -d '"'"'{"model":"gpt-oss-120b","messages":[{"role":"user","content":"hello"}]}'"'"
      return 0
    fi
    sleep 10
  done
  fail "engine did not become healthy in 20 min — check: cd $INSTALL_DIR && docker compose logs"
}

install_cli() {
  # Install this script as the `verificate` command. Prefer the exact bytes that just ran
  # (file invocation); a piped run ($0 = "bash") re-downloads from the same server instead.
  local dest=/usr/local/bin/verificate src
  src="$(readlink -f "$0" 2>/dev/null || true)"
  if [ -n "$src" ] && [ -f "$src" ] && head -3 "$src" | grep -q "Verificate HELIX" \
     && [ "$src" != "$(readlink -f "$dest" 2>/dev/null || echo "$dest")" ]; then
    cp "$src" "$dest"
  elif ! curl -fsSL "$VERIFICATE_URL/install.sh" -o "$dest"; then
    # The runtime is already healthy at this point — losing the convenience CLI must not fail
    # the install, but it is warned about LOUDLY (re-run install later to retry, no seat used
    # once downloads are cached... a full re-run DOES use a seat; use the curl refresh form).
    say "WARNING: could not install the 'verificate' CLI at $dest — refresh via:"
    say "  curl -fsSL $VERIFICATE_OFFICIAL_URL | sudo bash -s refresh"
    return 0
  fi
  chmod 0755 "$dest"
  say "CLI installed: sudo verificate [refresh|status|help]"
}

do_status() {
  [ -d "$INSTALL_DIR" ] || fail "no installation found at $INSTALL_DIR — install with: curl -fsSL $VERIFICATE_OFFICIAL_URL | sudo bash"
  local port=8000
  [ -f "$INSTALL_DIR/.env" ] && port=$(grep -m1 '^HELIX_HOST_PORT=' "$INSTALL_DIR/.env" | cut -d= -f2 || true) && port="${port:-8000}"
  say "Containers ($INSTALL_DIR):"
  (cd "$INSTALL_DIR" && docker compose ps) || say "WARNING: docker unreachable — try: sudo verificate status"
  say "Health + license (proxy :$port):"
  local out
  if out=$(curl -sf "http://127.0.0.1:$port/health"); then
    echo "$out"
  else
    say "WARNING: proxy not answering on :$port — check: cd $INSTALL_DIR && docker compose logs proxy"
  fi
}

do_benchmark() {
  [ -d "$INSTALL_DIR" ] || fail "no installation found at $INSTALL_DIR — install first: curl -fsSL $VERIFICATE_OFFICIAL_URL | sudo bash"
  need_cmd python3 " (apt install python3)"
  local port=8000 key
  [ -f "$INSTALL_DIR/.env" ] && port=$(grep -m1 '^HELIX_HOST_PORT=' "$INSTALL_DIR/.env" | cut -d= -f2 || true) && port="${port:-8000}"
  key=$(grep -m1 '^VERIFICATE_API_KEY=' "$INSTALL_DIR/.env" | cut -d= -f2- || true)
  [ -n "$key" ] || fail "no VERIFICATE_API_KEY in $INSTALL_DIR/.env"
  curl -sf "http://127.0.0.1:$port/health" >/dev/null 2>&1 || fail "engine not ready on :$port — run 'verificate status' first"
  local streams="${1:-1,2,4}" secs="${VERIFICATE_BENCH_SECONDS:-40}"
  local out="$INSTALL_DIR/benchmark_$(hostname)_$(date -u +%Y%m%dT%H%M%SZ).json"
  say "Benchmarking on :$port (streams=$streams, ${secs}s each) — a few minutes..."
  local tmp; tmp="$(mktemp)"
  cat > "$tmp" <<'PY'
import argparse,json,statistics,threading,time,urllib.request
W=("system latency throughput bandwidth vector matrix decode prefill token cache memory "
   "channel socket thread core numa page fault stream batch slot ").split()
def prompt(n): return "Summarise the following notes. "+" ".join(W[i%len(W)] for i in range(n))
def one(base,key,p,mx,timeout=600):
    body=json.dumps({"model":"gpt-oss-120b","temperature":0,"max_tokens":mx,
                     "messages":[{"role":"user","content":p}]}).encode()
    req=urllib.request.Request(base+"/v1/chat/completions",data=body,
        headers={"Content-Type":"application/json","Authorization":"Bearer "+key})
    t0=time.monotonic()
    with urllib.request.urlopen(req,timeout=timeout) as r: resp=json.loads(r.read())
    dt=time.monotonic()-t0; u=resp.get("usage") or {}; tm=resp.get("timings") or {}
    return {"latency_s":round(dt,3),"completion_tokens":u.get("completion_tokens",0),
            "server_pred_per_s":tm.get("predicted_per_second")}
def retry(base,key,p,mx,n=3):
    e=None
    for _ in range(n):
        try: return one(base,key,p,mx)
        except Exception as ex: e=ex; time.sleep(2)
    raise SystemExit(f"server not responding: {e}")
def sweep(base,key,streams,secs,p,mx):
    dl=time.monotonic()+secs; res=[]; lk=threading.Lock()
    def w():
        while time.monotonic()<dl:
            try: r=one(base,key,p,mx)
            except Exception as ex:
                with lk: res.append({"error":str(ex)[:200]})
                time.sleep(1); continue
            with lk: res.append(r)
    t0=time.monotonic(); ts=[threading.Thread(target=w) for _ in range(streams)]
    [t.start() for t in ts]; [t.join() for t in ts]; wall=time.monotonic()-t0
    ok=[r for r in res if "error" not in r]; er=[r for r in res if "error" in r]
    tk=sum(r["completion_tokens"] for r in ok); lat=sorted(r["latency_s"] for r in ok)
    pr=[r["server_pred_per_s"] for r in ok if r.get("server_pred_per_s")]
    return {"streams":streams,"requests_ok":len(ok),"requests_err":len(er),
            "aggregate_output_tok_s":round(tk/wall,2) if wall else None,
            "per_request_decode_tok_s_mean":round(statistics.mean(pr),2) if pr else None,
            "latency_p50_s":lat[len(lat)//2] if lat else None,
            "latency_p95_s":lat[min(len(lat)-1,int(round(0.95*len(lat)))-1)] if lat else None}
a=argparse.ArgumentParser()
a.add_argument("--base",required=True); a.add_argument("--key",required=True)
a.add_argument("--out",required=True); a.add_argument("--streams",default="1,2,4"); a.add_argument("--seconds",type=int,default=40)
a=a.parse_args(); p=prompt(256)
[retry(a.base,a.key,p,64) for _ in range(2)]
hl=[retry(a.base,a.key,p,200) for _ in range(2)]
single=max((h["server_pred_per_s"] if h["server_pred_per_s"] else h["completion_tokens"]/h["latency_s"]) for h in hl)
out={"host_base":a.base,"headline_single_stream_tok_s":round(single,2),"sweep":[]}
for s in (int(x) for x in a.streams.split(",")):
    print(f"  running streams={s} ...",flush=True); out["sweep"].append(sweep(a.base,a.key,s,a.seconds,p,64)); time.sleep(10)
with open(a.out,"w") as f: json.dump(out,f,indent=1)
print(f"\n  headline single-stream decode: {out['headline_single_stream_tok_s']} tok/s\n")
print("  streams | agg tok/s | decode tok/s | p50 s | p95 s | ok | err")
for s in out["sweep"]:
    print(f"  {s['streams']:>7} | {str(s['aggregate_output_tok_s']):>9} | {str(s['per_request_decode_tok_s_mean']):>12} | "
          f"{str(s['latency_p50_s']):>5} | {str(s['latency_p95_s']):>5} | {s['requests_ok']:>2} | {s['requests_err']}")
PY
  python3 "$tmp" --base "http://127.0.0.1:$port" --key "$key" --out "$out" --streams "$streams" --seconds "$secs" || { rm -f "$tmp"; fail "benchmark failed"; }
  rm -f "$tmp"
  say "Saved: $out"
}

usage() {
  cat <<'EOF'
Verificate HELIX v1.8
  sudo verificate install       install (prompts for a vik- install key; uses an activation seat)
  sudo verificate refresh       activate a new or renewed license key (seconds, no re-download)
  verificate status             containers, health, license days remaining
  verificate benchmark [S]      throughput sweep (default streams 1,2,4) -> prints a table + saves JSON
  verificate help               this text
EOF
}

do_refresh() {
  [ -d "$INSTALL_DIR/license" ] || fail "no installation found at $INSTALL_DIR — run the installer first"
  prompt_key
  say "Requesting a fresh license..."
  local resp="$INSTALL_DIR/.refresh-resp.json" http
  http=$(curl -sS -o "$resp" -w '%{http_code}' -H 'Content-Type: application/json' \
              -d "{\"install_key\":\"$INSTALL_KEY\"}" "$VERIFICATE_URL/refresh") || fail "cannot reach $VERIFICATE_URL"
  [ "$http" = "200" ] || fail "refresh refused (HTTP $http): $(cat "$resp")"
  umask 077
  json_get "$resp" license_token > "$INSTALL_DIR/license/license.vlt.new"
  mv -f "$INSTALL_DIR/license/license.vlt.new" "$INSTALL_DIR/license/license.vlt"   # atomic swap
  say "License refreshed: tier=$(json_get "$resp" tier), expires $(date -u -d "@$(json_get "$resp" expires_at)" +%Y-%m-%d 2>/dev/null || json_get "$resp" expires_at)"
  rm -f "$resp"
  # The proxy hot-reloads the token file on its next request — restart is belt-and-braces.
  (cd "$INSTALL_DIR" && docker compose restart proxy >/dev/null 2>&1) || true
  say "Done."
}

# ---- main ------------------------------------------------------------------------------------------
CMD="${1:-}"
if [ -z "$CMD" ]; then
  # Piped bootstrap ($0 = "bash") defaults to install; the installed CLI invoked bare shows
  # usage — never a silent reinstall (install consumes an activation seat).
  case "$(basename "$0")" in
    verificate) CMD=help ;;
    *) CMD=install ;;
  esac
fi
case "$CMD" in
  refresh)
    do_refresh
    ;;
  status)
    do_status
    ;;
  benchmark|bench)
    do_benchmark "${2:-}"
    ;;
  help|--help|-h)
    usage
    ;;
  install)
    say "Verificate HELIX v1.8 installer"
    collect_hw
    check_host
    prompt_key
    activate
    download_artifacts
    install_bundle
    wait_healthy
    install_cli
    say "Install complete. Next: 'verificate status' | 'sudo verificate refresh' | cd $INSTALL_DIR && docker compose [ps|logs|down|up -d]"
    ;;
  *)
    usage
    fail "unknown command '$CMD' (expected: install | refresh | status | help)"
    ;;
esac
