#!/usr/bin/env sh
set -eu

ROOT="$(CDPATH= cd -- "$(dirname -- "$0")/.." && pwd)"
VERSION=""

usage() {
  cat <<'EOF'
Usage: bin/release [version]

Cuts a ttfx release: runs the tests, bumps Cargo.toml, tags and pushes, and
creates the GitHub release with generated notes. That is all a release needs:
omarchy-pkgs watches this repository's releases (its sync-upstream job), and
updates the ttfx package's version and checksum from the new tag on its own.

  version  0.4.0 or v0.4.0. Defaults to bumping the last tag's patch number.
EOF
}

while [ $# -gt 0 ]; do
  case "$1" in
  -h | --help)
    usage
    exit 0
    ;;
  -*)
    echo "Unknown option: $1" >&2
    usage >&2
    exit 1
    ;;
  *)
    if [ -n "$VERSION" ]; then
      echo "Unexpected argument: $1" >&2
      exit 1
    fi
    VERSION="$1"
    ;;
  esac
  shift
done

for tool in cargo git gh awk; do
  if ! command -v "$tool" >/dev/null 2>&1; then
    echo "$tool is required to release ttfx." >&2
    exit 1
  fi
done

cd "$ROOT"

if [ -n "$(git status --porcelain)" ]; then
  echo "Working tree is dirty; commit or stash before releasing." >&2
  exit 1
fi

PREV="$(git describe --tags --abbrev=0 2>/dev/null || true)"

if [ -z "$VERSION" ]; then
  if [ -z "$PREV" ]; then
    echo "No v* tag to bump from; pass a version explicitly." >&2
    exit 1
  fi
  VERSION="$(echo "${PREV#v}" | awk -F. -v OFS=. '{ $NF += 1; print }')"
fi

VERSION="${VERSION#v}"
TAG="v$VERSION"

case "$VERSION" in
[0-9]*.[0-9]*.[0-9]*) ;;
*)
  echo "Version must look like 0.4.0; got '$VERSION'." >&2
  exit 1
  ;;
esac

if git rev-parse -q --verify "refs/tags/$TAG" >/dev/null; then
  echo "Tag $TAG already exists." >&2
  exit 1
fi

if [ -n "$(git ls-remote --tags origin "refs/tags/$TAG")" ]; then
  echo "Tag $TAG already exists on origin." >&2
  exit 1
fi

if ! gh auth status >/dev/null 2>&1; then
  echo "gh is not authenticated; run: gh auth login" >&2
  exit 1
fi

echo "Releasing ttfx $TAG (previous: ${PREV:-none})"

"$ROOT/bin/test"

# From here until the commit lands, put Cargo.toml back if anything fails.
trap 'git -C "$ROOT" checkout -- Cargo.toml Cargo.lock 2>/dev/null || true' EXIT

awk -v v="$VERSION" '
  !bumped && /^version = "/ { sub(/"[^"]*"/, "\"" v "\""); bumped = 1 }
  { print }
' Cargo.toml >Cargo.toml.new && mv Cargo.toml.new Cargo.toml

if ! grep -q "^version = \"$VERSION\"$" Cargo.toml; then
  echo "Failed to set version in Cargo.toml." >&2
  exit 1
fi

# Also refreshes Cargo.lock, so both go into the bump commit.
"$ROOT/bin/build"

BUILT="$("$ROOT/target/release/ttfx" --version)"
if [ "$BUILT" != "ttfx $VERSION" ]; then
  echo "Built binary reports '$BUILT', expected 'ttfx $VERSION'." >&2
  exit 1
fi

git add Cargo.toml Cargo.lock
git commit -m "Bump to $VERSION"
trap - EXIT

git push
git tag "$TAG"
git push origin "$TAG"

RELEASE_URL="$(gh release create "$TAG" --title "$TAG" --generate-notes)"

echo
echo "Released ttfx $TAG"
echo "  $RELEASE_URL"
echo "omarchy-pkgs picks it up with its next sync-upstream run."
