#!/usr/bin/env bash
# After agtop vX.Y.Z is published as a GitHub Release, this script:
#   1. Downloads MBrassey-agtop-v${VER}_GH0.tar.gz
#   2. Computes its sha256 + byte size
#   3. Patches sysutils/agtop/distinfo (replaces placeholders)
#   4. Forks freebsd/freebsd-ports if no fork exists
#   5. Shallow-clones the fork into a worktree
#   6. Drops the prepared port files into sysutils/agtop/
#   7. Commits, pushes, opens the PR
#
# Idempotent on re-run: if the fork already exists / branch exists,
# it picks up where it left off.
#
# Required: gh (logged in), curl, sha256sum
set -euo pipefail

VER="${1:-2.3.1}"
PORT_SRC="$HOME/code/agtop-freebsd-port/sysutils/agtop"
WORK="$HOME/code/freebsd-ports-fork"
TARBALL_NAME="MBrassey-agtop-v${VER}_GH0.tar.gz"
TARBALL_URL="https://github.com/MBrassey/agtop/archive/v${VER}.tar.gz"

[ -d "$PORT_SRC" ] || { echo "missing $PORT_SRC — run scripts/gen_freebsd_port.py first"; exit 2; }

echo "== Step 1: download $TARBALL_URL =="
TMP=$(mktemp -d)
trap 'rm -rf "$TMP"' EXIT
curl -sfL -o "$TMP/$TARBALL_NAME" "$TARBALL_URL"
SHA=$(sha256sum "$TMP/$TARBALL_NAME" | awk '{print $1}')
SZ=$(stat -c%s "$TMP/$TARBALL_NAME" 2>/dev/null || stat -f%z "$TMP/$TARBALL_NAME")
echo "  sha256: $SHA"
echo "  size:   $SZ bytes"

echo "== Step 2: patch distinfo =="
sed -i \
  -e "s|__SOURCE_SHA256_PLACEHOLDER__|$SHA|" \
  -e "s|__SOURCE_SIZE_PLACEHOLDER__|$SZ|" \
  "$PORT_SRC/distinfo"
# Also bump DISTVERSION in the Makefile if the user passed a non-default
# (the template ships 2.3.1, but allow this script to retarget later).
sed -i "s|^DISTVERSION=.*|DISTVERSION=\t${VER}|" "$PORT_SRC/Makefile"
sed -i "s|MBrassey-agtop-v2\\.[0-9]*\\.[0-9]*_GH0|MBrassey-agtop-v${VER}_GH0|g" "$PORT_SRC/distinfo"

echo "== Step 3: fork freebsd/freebsd-ports (or reuse) =="
if ! gh repo view MBrassey/freebsd-ports >/dev/null 2>&1; then
  # `gh repo fork <repo>` mutually excludes --remote (newer gh versions);
  # we don't want a remote on this machine anyway since we shallow-
  # clone the fork directly in step 4.
  gh repo fork freebsd/freebsd-ports --clone=false --default-branch-only
fi

echo "== Step 4: shallow-clone the fork =="
if [ ! -d "$WORK/.git" ]; then
  git clone --depth=1 "https://github.com/MBrassey/freebsd-ports.git" "$WORK"
fi
cd "$WORK"
# Make sure we're on main and up-to-date.
git fetch --depth=1 origin main
git checkout -B "agtop-${VER}" origin/main

echo "== Step 5: drop port files in =="
mkdir -p sysutils/agtop
cp "$PORT_SRC/Makefile"   sysutils/agtop/Makefile
cp "$PORT_SRC/distinfo"   sysutils/agtop/distinfo
cp "$PORT_SRC/pkg-descr"  sysutils/agtop/pkg-descr

echo "== Step 6: commit =="
git config user.name  "mbrassey"
git config user.email "matt@brassey.io"
git add sysutils/agtop/Makefile sysutils/agtop/distinfo sysutils/agtop/pkg-descr
git commit -m "sysutils/agtop: new port — process monitor for AI coding agents

agtop is a top-style ratatui TUI that walks /proc (sysinfo on
non-Linux) plus the on-disk session transcripts of Claude Code,
OpenAI Codex, Block Goose, Aider, and Google Gemini, and reports
per-agent CPU, RSS, status, current tool, in-flight subagents,
token usage, estimated cost, context-window fill, and loaded
skills.

On FreeBSD, writable-FD enumeration is provided by libprocstat;
per-process IO byte counters are not available through sysinfo
on this platform.

WWW: https://github.com/MBrassey/agtop"

echo "== Step 7: push branch =="
git push -u origin "agtop-${VER}" --force

echo "== Step 8: open PR =="
gh pr create --repo freebsd/freebsd-ports \
  --base main --head "MBrassey:agtop-${VER}" \
  --title "sysutils/agtop: new port — process monitor for AI coding agents" \
  --body "$(cat <<'BODY'
### New port: sysutils/agtop

agtop is a top-style ratatui TUI for monitoring AI coding agents
(Claude Code, OpenAI Codex, Block Goose, Aider, Google Gemini).
Reports per-agent CPU, RSS, status, current tool, in-flight
subagents, token usage, estimated cost, context-window fill, and
loaded skills.

#### FreeBSD-specific notes

- Writable-FD enumeration uses `libprocstat` directly (matches
  what `fstat -p <pid>` returns).  Implemented via FFI in
  `src/writing_files.rs`.
- Per-process IO byte counters are not available through sysinfo
  on FreeBSD; the column reads 0 (this is documented in the
  upstream README).
- All other features — process metrics, sessions, cost,
  context-window, skills — work identically to the Linux backend.

#### Testing notes

- `cargo check --release --target x86_64-unknown-freebsd` is clean
  on every push (CI matrix).
- The CARGO_CRATES list was generated by walking Cargo.lock and
  fetching each crate from crates.io to compute sha256.  247
  registry deps in total.
- Maintainer (matt@brassey.io) is the upstream author; happy to
  iterate on any review feedback.

#### Description

Process monitor for AI coding agents.

Reads /proc on Linux (sysinfo on macOS, Windows, and *BSD) plus
the on-disk session transcripts of Claude Code, OpenAI Codex,
Block Goose, Aider, and Google Gemini.  For each detected agent
it reports CPU, RSS, status, current tool / task, in-flight
subagents, cumulative token usage, estimated cost,
context-window fill, and loaded skills.

WWW: https://github.com/MBrassey/agtop
BODY
)"

echo
echo "✓ PR opened.  Track with:"
echo "    gh pr list --repo freebsd/freebsd-ports --author MBrassey"
