#!/usr/bin/env bash
set -euo pipefail

# Usage ------------------------------------------------------------------
usage() {
  cat <<EOF
Usage: $(basename "$0") <bump>

  bump      Version bump kind passed to 'uv version --bump'
            (patch, minor, major, etc.)

Examples:
  $(basename "$0") patch
  $(basename "$0") minor
EOF
  exit 1
}

if [[ $# -ne 1 ]]; then
  usage
fi

PROJECT_DIR="$(cd "$(dirname "$(realpath "${BASH_SOURCE[0]}")")/.." && pwd)"
cd "$PROJECT_DIR"

BUMP="$1"
shift

# Helpers ----------------------------------------------------------------
is_jj() { [[ -d "$PROJECT_DIR/.jj" ]]; }

check_clean() {
  if is_jj; then
    if [[ -n "$(jj diff --summary 2>/dev/null)" ]]; then
      echo "error: working copy is not clean (jj diff shows changes)" >&2
      exit 1
    fi
  else
    if [[ -n "$(git status --porcelain)" ]]; then
      echo "error: working copy is not clean (git status shows changes)" >&2
      exit 1
    fi
  fi
}

read_version() {
  uv version --short --package "$1"
}

# 1. Lint & type-check ---------------------------------------------------
echo "==> Running linters and type checkers..."
just lint

# 2. Ensure working copy is clean -----------------------------------------
echo "==> Checking working copy is clean..."
check_clean

# 3. Process the package: bump, check tag, generate changelog -----------
pkg="algebraic"
UV_PKG="algebraic-arrays"
PYPROJECT="pyproject.toml"
CLIFF_CONFIG="cliff.toml"
CHANGELOG="CHANGELOG.md"

OLD_VERSION="$(read_version "$UV_PKG")"
echo "==> [$pkg] current version: $OLD_VERSION"

echo "==> [$pkg] Bumping version ($BUMP)..."
uv version --bump "$BUMP" --package "$UV_PKG"

NEW_VERSION="$(read_version "$UV_PKG")"
TAG="${TAG_PREFIX:-}v${NEW_VERSION}"
echo "    [$pkg] new version: $NEW_VERSION"
echo "    [$pkg] tag:         $TAG"

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

echo "==> [$pkg] Generating changelog..."
git cliff --config "$CLIFF_CONFIG" --tag "$TAG" -o "$CHANGELOG"

TAGS+=("$TAG")
TAG_PREFIXES+=("$TAG_PREFIX")
CLIFF_CONFIGS+=("$CLIFF_CONFIG")
CHANGELOGS+=("$CHANGELOG")
PYPROJECTS+=("$PYPROJECT")
COMMIT_PARTS+=("${pkg} ${NEW_VERSION}")

# 4. Commit ---------------------------------------------------------------
# Build a single commit message listing all released packages.
COMMIT_MSG="chore(release): $(
  IFS=', '
  echo "${COMMIT_PARTS[*]}"
)"
echo "==> Committing: $COMMIT_MSG"

if is_jj; then
  jj commit -m "$COMMIT_MSG"
else
  git add "${PYPROJECTS[@]}" "${CHANGELOGS[@]}"
  git commit -m "$COMMIT_MSG"
fi

# 5. Tag each package -----------------------------------------------------
for i in "${!TAGS[@]}"; do
  TAG="${TAGS[$i]}"
  CLIFF_CONFIG="${CLIFF_CONFIGS[$i]}"

  TAG_MESSAGE="$(git cliff --config "$CLIFF_CONFIG" --tag "$TAG" --unreleased --strip all)"
  if [[ -z "$TAG_MESSAGE" ]]; then
    TAG_MESSAGE="Release ${TAG}"
  fi

  echo "==> Tagging $TAG"
  if is_jj; then
    jj git import 2>/dev/null || true
    git tag -a "$TAG" --cleanup=verbatim -m "$TAG_MESSAGE"
    jj git import 2>/dev/null || true
  else
    git tag -a "$TAG" --cleanup=verbatim -m "$TAG_MESSAGE"
  fi
done

echo ""
echo "Done! Created tags: ${TAGS[*]}"
echo "To publish, push the tags:  git push origin ${TAGS[*]}"
