#!/bin/sh
# spp installer — gh-free, one line:
#   curl -fsSL https://spp-install.supalead.ai | sh
#
# Downloads the spp binary for this platform, verifies its sha256, and installs
# it to ~/.supapool/bin/spp. No GitHub login required. After install, run `spp`
# to sign up with your company email and onboard Claude Code / Codex.
#
# User-facing output is Korean (the team + the app TUI are Korean); code,
# variables, and comments stay English.
#
# Wrapped in main() + called on the last line so a truncated download never
# executes a partial script.
set -eu

SPP_INSTALL_HOST="${SPP_INSTALL_HOST:-https://spp-install.supalead.ai}"

main() {
  os="$(uname -s)"
  arch="$(uname -m)"
  case "$os" in
    Darwin) goos="darwin" ;;
    Linux) goos="linux" ;;
    *) echo "spp: 지원하지 않는 운영체제: $os" >&2; exit 1 ;;
  esac
  case "$arch" in
    x86_64 | amd64) goarch="amd64" ;;
    arm64 | aarch64) goarch="arm64" ;;
    *) echo "spp: 지원하지 않는 아키텍처: $arch" >&2; exit 1 ;;
  esac
  platform="${goos}-${goarch}"

  command -v curl >/dev/null 2>&1 || { echo "spp: curl이 필요합니다" >&2; exit 1; }

  # Resolve the binary URL + sha256 from the manifest (one atomic object) rather
  # than the stable bin/spp_<platform> alias. The manifest points at IMMUTABLE,
  # version-keyed objects, so the binary and its checksum are always consistent —
  # no split-object race and no CDN cache-skew window. The extraction is a plain
  # sed over the fixed machine-generated manifest shape (no jq/python needed).
  manifest="$(curl -fsSL "${SPP_INSTALL_HOST}/manifest.json")" || { echo "spp: manifest를 가져오지 못했습니다" >&2; exit 1; }
  # Flatten newlines/tabs to spaces so the line-based extraction works even if the
  # manifest is ever pretty-printed (multi-line) rather than the one-line form the
  # publisher emits today.
  manifest="$(printf '%s' "$manifest" | tr '\n\r\t' '   ')"
  # Require the platform key to be present before extracting: otherwise the sed
  # below would leave the whole manifest in $entry and read the FIRST platform's
  # url/sha256, silently installing the wrong-arch binary.
  case "$manifest" in
    *"\"${platform}\""*) : ;;
    *) echo "spp: manifest에 ${platform}용 빌드가 없습니다" >&2; exit 1 ;;
  esac
  entry="$(printf '%s' "$manifest" | sed "s/.*\"${platform}\"[[:space:]]*:[[:space:]]*{//; s/}.*//")"
  bin_url="$(printf '%s' "$entry" | sed -n 's/.*"url"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/p')"
  want="$(printf '%s' "$entry" | sed -n 's/.*"sha256"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/p')"
  if [ -z "$bin_url" ] || [ -z "$want" ]; then
    echo "spp: ${platform} manifest 항목이 손상되었습니다" >&2
    exit 1
  fi

  dest_dir="${HOME}/.supapool/bin"
  mkdir -p "$dest_dir"
  # Download into the DESTINATION directory so the final install is an atomic
  # same-filesystem rename — a cross-filesystem mv (tmp on /tmp) would fall back to
  # copy+remove and could destroy an existing working spp if the copy fails.
  tmp="$(mktemp "${dest_dir}/spp.XXXXXX")"
  trap 'rm -f "$tmp"' EXIT

  echo "spp: ${platform} 다운로드 중…"
  curl -fsSL "$bin_url" -o "$tmp"
  if command -v sha256sum >/dev/null 2>&1; then
    got="$(sha256sum "$tmp" | awk '{print $1}')"
  elif command -v shasum >/dev/null 2>&1; then
    got="$(shasum -a 256 "$tmp" | awk '{print $1}')"
  else
    echo "spp: sha256 도구(sha256sum/shasum)를 찾을 수 없습니다" >&2
    exit 1
  fi
  if [ "$want" != "$got" ]; then
    echo "spp: 체크섬 불일치 (기대값 $want, 실제 $got)" >&2
    exit 1
  fi

  chmod +x "$tmp"
  # Strip the macOS quarantine attribute if present (curl does not set it, but be
  # defensive); ignore failures.
  [ "$goos" = "darwin" ] && xattr -d com.apple.quarantine "$tmp" 2>/dev/null || true
  mv "$tmp" "${dest_dir}/spp"  # atomic rename (same filesystem)
  trap - EXIT

  version="$("${dest_dir}/spp" version 2>/dev/null || echo "installed")"
  echo ""
  echo "spp: ${version}"
  echo "spp: ${dest_dir}/spp 에 설치됨"

  # Put ~/.supapool/bin on PATH at install time so `spp` works in a new shell
  # immediately — not only after onboarding. Uses the same managed block markers
  # the app writes, so onboarding updates it in place (no duplicate) and
  # `spp uninstall` removes it. Idempotent: skip if the block already exists.
  path_ok=1
  ensure_path_block || path_ok=0

  echo ""
  case ":${PATH}:" in
    *":${dest_dir}:"*)
      # Already on this shell's PATH (re-install, or the rc block was loaded).
      echo "실행:  spp"
      ;;
    *)
      if [ "$path_ok" = 1 ]; then
        # The PATH line was written to the rc file, but a piped `curl | sh` runs in
        # a child process and cannot change the parent shell's PATH — so this
        # already-running terminal will not see `spp` until it re-reads that file.
        # Lead with the one-liner that activates it right here (matches rustup/nvm/
        # bun); a new terminal is the fallback.
        echo "설치 완료. 지금 이 터미널에서 바로 'spp'를 쓰려면 실행하세요:"
        echo ""
        echo "    source ${SPP_MANAGED_RC:-~/.zshrc}"
        echo ""
        echo "(또는 새 터미널을 열면 이 단계 없이 'spp'가 바로 됩니다)"
      else
        # PATH block could not be written; ensure_path_block already printed how to
        # fix PATH. The absolute path always works regardless.
        echo "바로 실행:  ${dest_dir}/spp"
      fi
      ;;
  esac
}

# ensure_path_block appends a supapool-managed PATH block to the startup file the
# user's shell actually loads (zsh -> ~/.zshrc, bash -> ~/.bashrc, else
# ~/.profile), matching the markers the app manages. The block itself is POSIX so
# it works in any of them. Idempotent: skip if already present.
ensure_path_block() {
  case "$(basename "${SHELL:-/bin/sh}")" in
    zsh)  rc="${HOME}/.zshrc" ;;
    bash) rc="${HOME}/.bashrc" ;;
    *)    rc="${HOME}/.profile" ;;
  esac
  # Expose the resolved startup file so the final message can tell the user which
  # file to `source`. Use the ~-relative form (rc is always $HOME/.<name>) for a
  # clean, copy-paste-friendly hint rather than echoing the absolute home path.
  SPP_MANAGED_RC="~/${rc##*/}"
  start="# >>> supapool managed >>>"
  end="# <<< supapool managed <<<"
  if [ -f "$rc" ] && grep -qF "$start" "$rc" 2>/dev/null; then
    return 0   # already managed (by a prior install or onboarding)
  fi
  # Start on a fresh line: if the rc file exists and its last byte is not a
  # newline, appending would glue the start marker onto the user's last line
  # (e.g. `export FOO=1# >>> supapool managed >>>`), which also makes uninstall
  # delete that user line when it strips the block.
  if [ -f "$rc" ] && [ -n "$(tail -c1 "$rc" 2>/dev/null)" ]; then
    printf '\n' >> "$rc"
  fi
  if {
    printf '%s\n' "$start"
    printf '%s\n' 'case ":$PATH:" in'
    printf '%s\n' '  *":$HOME/.supapool/bin:"*) ;;'
    printf '%s\n' '  *) export PATH="$HOME/.supapool/bin:$PATH" ;;'
    printf '%s\n' 'esac'
    printf '%s\n' "$end"
  } >> "$rc" 2>/dev/null; then
    echo "spp: ~/.supapool/bin 을 ${rc} 의 PATH에 추가했습니다"
    return 0
  fi
  echo "spp: ${rc} 를 수정하지 못했습니다 — 셸 시작 파일에 아래를 직접 추가하세요:" >&2
  echo '  export PATH="$HOME/.supapool/bin:$PATH"' >&2
  return 1
}

main "$@"
