#!/bin/sh
# codewithads installer — https://codewithads.com
#   curl -fsSL https://codewithads.com/install | bash
# The ad-supported fork of opencode. Free forever; the spinner pays.
set -e

REPO="griffincockfoster56/codewithads"
INSTALL_DIR="${CODEWITHADS_INSTALL:-$HOME/.codewithads}"
BIN_DIR="$INSTALL_DIR/bin"

case "$(uname -s)" in
  Darwin) os="darwin" ;;
  Linux) os="linux" ;;
  *) echo "codewithads: unsupported OS $(uname -s) — grab a binary from https://github.com/$REPO/releases" >&2; exit 1 ;;
esac
case "$(uname -m)" in
  arm64|aarch64) arch="arm64" ;;
  x86_64|amd64) arch="x64" ;;
  *) echo "codewithads: unsupported arch $(uname -m)" >&2; exit 1 ;;
esac

asset="codewithads-$os-$arch.zip"
base="https://github.com/$REPO/releases/latest/download"

sha256() {
  if command -v shasum >/dev/null 2>&1; then shasum -a 256 "$1" | awk '{print $1}'
  elif command -v sha256sum >/dev/null 2>&1; then sha256sum "$1" | awk '{print $1}'
  else echo ""; fi
}

tmp="$(mktemp -d)"
trap 'rm -rf "$tmp"' EXIT

# Download with retries, then VERIFY before trusting it — a silently truncated
# download is exactly the bug that shipped a crashing binary before.
ok=0
attempt=1
while [ "$attempt" -le 3 ]; do
  echo "⠋ downloading $asset (attempt $attempt)…"
  if curl -fSL --retry 3 --retry-delay 2 "$base/$asset" -o "$tmp/app.zip"; then
    expected=""
    if curl -fsSL "$base/$asset.sha256" -o "$tmp/app.sha256" 2>/dev/null; then
      expected="$(awk '{print $1}' "$tmp/app.sha256")"
    fi
    actual="$(sha256 "$tmp/app.zip")"
    if [ -n "$expected" ] && [ -n "$actual" ] && [ "$expected" != "$actual" ]; then
      echo "  checksum mismatch (corrupt download) — retrying" >&2
    elif ! unzip -tq "$tmp/app.zip" >/dev/null 2>&1; then
      echo "  archive failed integrity check — retrying" >&2
    else
      ok=1
      break
    fi
  fi
  attempt=$((attempt + 1))
done
if [ "$ok" -ne 1 ]; then
  echo "codewithads: download failed or kept arriving corrupt after 3 tries." >&2
  echo "  Try again, or download a binary directly: https://github.com/$REPO/releases" >&2
  exit 1
fi

unzip -oq "$tmp/app.zip" -d "$tmp/extracted"
binary="$(find "$tmp/extracted" -type f \( -name opencode -o -name codewithads \) | head -1)"
if [ -z "$binary" ]; then
  echo "codewithads: no binary found in release asset" >&2
  exit 1
fi

mkdir -p "$BIN_DIR"
mv "$binary" "$BIN_DIR/codewithads"
chmod +x "$BIN_DIR/codewithads"

if [ "$os" = "darwin" ]; then
  xattr -d com.apple.quarantine "$BIN_DIR/codewithads" 2>/dev/null || true
  # cp/mv invalidates the ad-hoc signature; re-sign or macOS SIGKILLs it.
  codesign --force -s - "$BIN_DIR/codewithads" >/dev/null 2>&1 || true
fi

# Self-test: the binary must actually run. Catches truncation, corruption, or a
# bad signature BEFORE we tell the user it's installed.
if ! "$BIN_DIR/codewithads" --version >/dev/null 2>&1; then
  echo "codewithads: the installed binary did not run cleanly." >&2
  echo "  This usually means a corrupt download — please re-run the installer." >&2
  exit 1
fi

# Symlink somewhere already on PATH when we can.
for dir in "$HOME/.local/bin" "$HOME/bin"; do
  if [ -d "$dir" ] && [ -w "$dir" ]; then
    ln -sf "$BIN_DIR/codewithads" "$dir/codewithads"
    break
  fi
done

version="$("$BIN_DIR/codewithads" --version 2>/dev/null | head -1)"
echo ""
echo "⠹ codewithads installed → $BIN_DIR/codewithads  ($version)"
echo ""
case ":$PATH:" in
  *":$BIN_DIR:"*|*":$HOME/.local/bin:"*|*":$HOME/bin:"*) ;;
  *)
    echo "Add it to your PATH:"
    echo "  export PATH=\"$BIN_DIR:\$PATH\""
    ;;
esac
echo "Run: codewithads"
echo "Free forever — the spinner pays the bills. https://codewithads.com"
