#!/bin/sh
# Joey CLI installer. POSIX sh, idempotent, macOS (arm64/x86_64) + Linux (x86_64).
#
# Usage: curl -fsSL https://get.getjoey.io | sh
#   Flags (pass after `sh -s --` when piping, or directly when run as a file):
#     --no-warp        skip installing, enrolling and connecting Cloudflare WARP
#     --no-login       skip `joey auth login`
#     --no-brightdata  skip installing the Bright Data CLI and its key file
#     --dry-run        print every step this script would run; execute nothing
#
# No Google Cloud tooling is needed. os.getjoey.io answers only through Cloudflare
# WARP (Zero Trust team joey-getjoey), so WARP is set up first; the client then
# installs from the index served there, and `joey web` gets its provider keys from
# the Joey service for the signed-in researcher.
set -eu

NO_WARP=0
NO_LOGIN=0
NO_BRIGHTDATA=0
DRY_RUN=0
WARP_TEAM="joey-getjoey"
JOEY_HOST="https://os.getjoey.io"
JOEY_CLI_VERSION="0.3.0rc17.post40219636507"

for arg in "$@"; do
  case "$arg" in
    --no-warp) NO_WARP=1 ;;
    --no-login) NO_LOGIN=1 ;;
    --no-brightdata) NO_BRIGHTDATA=1 ;;
    --dry-run) DRY_RUN=1 ;;
    *)
      echo "unknown flag: $arg" >&2
      exit 1
      ;;
  esac
done

run() {
  if [ "$DRY_RUN" -eq 1 ]; then
    printf 'DRY-RUN: %s\n' "$*"
  else
    "$@"
  fi
}

note() {
  printf '%s\n' "$*"
}

os_name="$(uname -s)"

# --- 1. Cloudflare WARP ------------------------------------------------------

warp_cli() {
  if command -v warp-cli >/dev/null 2>&1; then
    warp-cli "$@"
  elif [ -x /usr/local/bin/warp-cli ]; then
    /usr/local/bin/warp-cli "$@"
  else
    return 127
  fi
}

warp_field() {
  # One "key": "value" string from warp-cli's JSON, without needing jq.
  sed -n "s/.*\"$1\"[[:space:]]*:[[:space:]]*\"\([^\"]*\)\".*/\1/p" | head -n 1
}

warp_status() {
  warp_cli -j status 2>/dev/null | warp_field status || true
}

warp_team() {
  warp_cli -j registration show 2>/dev/null | warp_field organization || true
}

warp_fail() {
  note "error: $1"
  note "  fix: $2"
  note "  then rerun: curl -fsSL https://get.getjoey.io | sh"
  exit 1
}

joey_reachable() {
  curl -fsS --max-time 5 "$JOEY_HOST/health/live" >/dev/null 2>&1
}

if [ "$NO_WARP" -eq 1 ]; then
  note "Skipping Cloudflare WARP (--no-warp); $JOEY_HOST answers only through it."
elif [ "$DRY_RUN" -eq 1 ]; then
  if [ "$os_name" = "Darwin" ]; then
    printf 'DRY-RUN: %s\n' "brew install --cask cloudflare-warp (skipped if warp-cli exists; asks for your Mac password)"
  else
    printf 'DRY-RUN: %s\n' "add pkg.cloudflareclient.com to apt/dnf, then install cloudflare-warp (skipped if warp-cli exists)"
  fi
  printf 'DRY-RUN: %s\n' "warp-cli --accept-tos registration new $WARP_TEAM (skipped if already enrolled; opens Google sign-in)"
  printf 'DRY-RUN: %s\n' "warp-cli connect; wait for Connected and $JOEY_HOST/health/live"
else
  if ! warp_cli --version >/dev/null 2>&1; then
    note "Installing Cloudflare WARP ($JOEY_HOST is reachable only through it)..."
    if [ "$os_name" = "Darwin" ]; then
      if command -v brew >/dev/null 2>&1; then
        note "Homebrew will ask for your Mac password to install the WARP system service."
        brew install --cask cloudflare-warp
      else
        warp_pkg="$(mktemp -d)/Cloudflare_WARP.pkg"
        curl -fsSL -o "$warp_pkg" https://downloads.cloudflareclient.com/v1/download/macos/ga
        note "macOS will ask for your password to install the WARP system service."
        sudo installer -pkg "$warp_pkg" -target /
      fi
    elif command -v apt-get >/dev/null 2>&1; then
      curl -fsSL https://pkg.cloudflareclient.com/pubkey.gpg \
        | sudo gpg --yes --dearmor --output /usr/share/keyrings/cloudflare-warp-archive-keyring.gpg
      # shellcheck disable=SC1091
      warp_codename="$(. /etc/os-release && printf '%s' "${VERSION_CODENAME:-}")"
      echo "deb [signed-by=/usr/share/keyrings/cloudflare-warp-archive-keyring.gpg] https://pkg.cloudflareclient.com/ $warp_codename main" \
        | sudo tee /etc/apt/sources.list.d/cloudflare-client.list >/dev/null
      sudo apt-get update -q && sudo apt-get install -y -q cloudflare-warp
    elif command -v dnf >/dev/null 2>&1 || command -v yum >/dev/null 2>&1; then
      curl -fsSL https://pkg.cloudflareclient.com/cloudflare-warp-ascii.repo \
        | sudo tee /etc/yum.repos.d/cloudflare-warp.repo >/dev/null
      if command -v dnf >/dev/null 2>&1; then
        sudo dnf install -y cloudflare-warp
      else
        sudo yum install -y cloudflare-warp
      fi
    else
      warp_fail "no supported package manager to install Cloudflare WARP" \
        "install it from https://developers.cloudflare.com/cloudflare-one/team-and-resources/devices/cloudflare-one-client/downloads/"
    fi
  fi

  # The daemon starts with the package; give it a moment to answer.
  tries=0
  until warp_cli -j status >/dev/null 2>&1; do
    tries=$((tries + 1))
    [ "$tries" -le 30 ] || warp_fail "the WARP service did not start" \
      "open the Cloudflare WARP app once (it starts the service)"
    sleep 1
  done

  team="$(warp_team)"
  if [ "$team" = "$WARP_TEAM" ]; then
    note "WARP already enrolled in $WARP_TEAM."
  else
    if [ -n "$team" ]; then
      note "WARP is enrolled in $team; switching it to $WARP_TEAM."
      warp_cli registration delete >/dev/null 2>&1 || true
    fi
    note "Enrolling WARP in $WARP_TEAM: sign in with your getjoey.io Google account in the browser tab that opens."
    warp_cli --accept-tos registration new "$WARP_TEAM" || true
    tries=0
    until [ "$(warp_team)" = "$WARP_TEAM" ]; do
      tries=$((tries + 1))
      [ "$tries" -le 180 ] || warp_fail "WARP was not enrolled in $WARP_TEAM within 3 minutes" \
        "run \`warp-cli registration new $WARP_TEAM\` and finish the Google sign-in with your getjoey.io account"
      sleep 1
    done
    note "WARP enrolled in $WARP_TEAM."
  fi

  if [ "$(warp_status)" != "Connected" ]; then
    note "Connecting WARP..."
    warp_cli connect >/dev/null 2>&1 || true
  fi
  tries=0
  until [ "$(warp_status)" = "Connected" ] && joey_reachable; do
    tries=$((tries + 1))
    [ "$tries" -le 60 ] || warp_fail "WARP is $(warp_status || echo unknown) and $JOEY_HOST did not answer within 60s" \
      "run \`warp-cli connect\`; if it stays unreachable, re-authenticate in the Cloudflare WARP app (the Zero Trust session lasts 24h)"
    sleep 1
  done
  note "WARP connected; $JOEY_HOST answers."
fi

# --- 2. uv -------------------------------------------------------------------

if command -v uv >/dev/null 2>&1; then
  note "uv already installed: $(command -v uv)"
else
  note "Installing uv..."
  if [ "$DRY_RUN" -eq 1 ]; then
    printf 'DRY-RUN: %s\n' "curl -LsSf https://astral.sh/uv/install.sh | sh"
  else
    curl -LsSf https://astral.sh/uv/install.sh | sh
  fi
  PATH="$HOME/.local/bin:$PATH"
  export PATH
fi

# --- 3. joey client from the index behind WARP --------------------------------

note "Installing the joey client from $JOEY_HOST/packages/simple/ ..."
run uv tool install --force --python 3.12 --prerelease allow \
  --index "joey=$JOEY_HOST/packages/simple/" "joey-cli==$JOEY_CLI_VERSION"
PATH="$HOME/.local/bin:$PATH"
export PATH

# --- 4. joey config ------------------------------------------------------------

target_endpoint="$JOEY_HOST"
if [ "$DRY_RUN" -eq 1 ]; then
  printf 'DRY-RUN: %s\n' "joey config init --endpoint $target_endpoint (skipped if already configured)"
else
  # A fresh config report succeeds with endpoint:null; a damaged config must
  # fail here rather than being overwritten by initialization.
  joey_config_report="$(joey config show)"
  case "$(printf '%s' "$joey_config_report" | tr -d '[:space:]')" in
    *'"endpoint":null'*|*'"endpoint":""'*)
      joey config init --endpoint "$target_endpoint"
      ;;
    *) note "Preserving existing Joey endpoint and human-login settings." ;;
  esac
fi

# --- 5. Bright Data ------------------------------------------------------------

if [ "$NO_BRIGHTDATA" -eq 1 ]; then
  note "Skipping Bright Data CLI install (--no-brightdata)."
else
  node_ok=0
  if command -v node >/dev/null 2>&1; then
    node_major="$(node -p 'process.versions.node.split(".")[0]' 2>/dev/null || echo 0)"
    if [ "$node_major" -ge 20 ] 2>/dev/null; then
      node_ok=1
    fi
  fi

  if [ "$node_ok" -eq 1 ]; then
    note "Node $(node -v 2>/dev/null) already satisfies >= 20."
  else
    if [ "$os_name" = "Darwin" ] && command -v brew >/dev/null 2>&1; then
      note "Installing Node via Homebrew..."
      run brew install node
    else
      note "Node >= 20 not found. Install it manually (e.g. https://nodejs.org) and re-run this installer."
    fi
  fi

  note "Installing @brightdata/cli..."
  run npm install -g @brightdata/cli
fi

# --- 6. Sign in -----------------------------------------------------------------

run joey config show

if [ "$NO_LOGIN" -eq 1 ]; then
  note "Skipping joey auth login (--no-login)."
else
  run joey auth login
fi

# --- 7. Provider keys ------------------------------------------------------------
#
# `joey web` reads provider keys from the Joey service in memory, so nothing is written
# for it. Only the separate `bdata` tool needs a key file, which the service fills.

keys_state="not checked"
if [ "$NO_BRIGHTDATA" -eq 1 ]; then
  note "Skipping the Bright Data key file (--no-brightdata)."
elif [ "$DRY_RUN" -eq 1 ]; then
  printf 'DRY-RUN: %s\n' "joey web credentials sync (writes ~/.config/joey/brightdata.env from the Joey service)"
elif joey web credentials sync >/dev/null 2>&1; then
  keys_state="served by $JOEY_HOST"
else
  keys_state="not served yet"
  note "warning: the Joey service did not supply provider keys; run \`joey auth login\`, then \`joey web credentials sync\`, and see \`joey doctor\`"
fi

# --- Summary -----------------------------------------------------------------

note ""
note "Joey install summary:"
if [ "$NO_WARP" -eq 1 ]; then
  note "  warp:       skipped (--no-warp)"
elif [ "$DRY_RUN" -eq 0 ]; then
  note "  warp:       $(warp_status || echo unknown) ($(warp_team || true))"
fi
note "  uv:         $(command -v uv 2>/dev/null || echo 'not on PATH')"
note "  joey:       $(command -v joey 2>/dev/null || echo 'not on PATH')"
if [ "$NO_BRIGHTDATA" -eq 1 ]; then
  note "  bdata:      skipped (--no-brightdata)"
else
  note "  bdata:      $(command -v bdata 2>/dev/null || echo 'not on PATH')"
fi
if [ "$DRY_RUN" -eq 0 ]; then
  note "  web keys:   $keys_state"
fi
note "Run \`joey doctor\` any time: it names the one command that fixes whatever is not ready."
