#!/usr/bin/env bash
# ferrovec adoption tracker.
#
# GitHub's traffic API only keeps a rolling 14-day window, so run this
# regularly (weekly is enough) — it appends to scripts/stats.csv and that
# CSV becomes the only long-term record you have.
#
#   ./scripts/stats.sh          # print + append a row
#   ./scripts/stats.sh --print  # print only
set -euo pipefail

REPO="singhpratech/ferrovec"
CSV="$(dirname "$0")/stats.csv"
DATE="$(date -u +%Y-%m-%d)"

crates_json="$(curl -sS -H 'User-Agent: ferrovec-stats' https://crates.io/api/v1/crates/ferrovec)"
npm_json="$(curl -sS https://api.npmjs.org/downloads/range/last-month/ferrovec)"
repo_json="$(gh api "repos/$REPO")"
views_json="$(gh api "repos/$REPO/traffic/views")"
clones_json="$(gh api "repos/$REPO/traffic/clones")"

read -r CRATES NPM_WK STARS FORKS VIEWS VUNIQ CLONES CUNIQ LATEST_SHARE <<EOF
$(python3 - "$crates_json" "$npm_json" "$repo_json" "$views_json" "$clones_json" <<'PY'
import json, sys
crates, npm, repo, views, clones = (json.loads(a) for a in sys.argv[1:6])

total = crates["crate"]["downloads"]
vs = crates["versions"]
# Share of downloads sitting on the newest version. Humans install the
# latest; crawlers sweep every version evenly. High share => real users.
latest = max(vs, key=lambda v: v["created_at"])["downloads"]
share = round(100 * latest / total) if total else 0

npm_week = sum(d["downloads"] for d in npm.get("downloads", [])[-7:])

print(total, npm_week, repo["stargazers_count"], repo["forks_count"],
      views["count"], views["uniques"], clones["count"], clones["uniques"], share)
PY
)
EOF

printf '\n  ferrovec — %s (UTC)\n\n' "$DATE"
printf '  crates.io   %s total   (%s%% on latest version)\n' "$CRATES" "$LATEST_SHARE"
printf '  npm         %s in the last 7 days\n' "$NPM_WK"
printf '  GitHub      %s stars, %s forks\n' "$STARS" "$FORKS"
printf '  traffic     %s views / %s unique   |   %s clones / %s unique  (14d)\n\n' \
  "$VIEWS" "$VUNIQ" "$CLONES" "$CUNIQ"

# The honest read: a star is the only signal bots never fake. Unique
# viewers can be scanners that render the page, and clones are almost all
# automated (mirrors, scanners, LLM crawlers) — so clones >> views with
# 0 stars is the bot signature, not adoption. Require a star, OR an
# external referrer showing up (reddit/HN/news), before calling it real.
if [ "$STARS" -gt 0 ]; then
  printf '  => real humans: %s star(s). Someone chose to click.\n\n' "$STARS"
elif [ "$CLONES" -gt "$VIEWS" ]; then
  printf '  => still bots/mirrors. Clones (%s) outnumber views (%s) and\n' "$CLONES" "$VIEWS"
  printf '     stars are 0 — that is scanners cloning, not people reading.\n\n'
else
  printf '  => 0 stars. Watch for an external referrer + a first star.\n\n'
fi

if [ "${1:-}" != "--print" ]; then
  [ -f "$CSV" ] || echo "date,crates_total,crates_latest_pct,npm_7d,stars,forks,views,view_uniques,clones,clone_uniques" > "$CSV"
  echo "$DATE,$CRATES,$LATEST_SHARE,$NPM_WK,$STARS,$FORKS,$VIEWS,$VUNIQ,$CLONES,$CUNIQ" >> "$CSV"
  printf '  appended to %s\n\n' "$CSV"
fi
