#!/usr/bin/env bash
# notify-chart-bump.sh — bump appVersion on tnd-zddc-chart and push.
#
# Replaces the inline shell that previously lived in
# .forgejo/workflows/notify-chart-dev.yml and the notify-chart-prod
# job in deploy-release.yml. Extracting the logic to a real script
# means we can:
#   1. test it locally without going through the runner
#      (CHART_FORGEJO_TOKEN=$FORGEJO_TOKEN ./.forgejo/scripts/notify-chart-bump.sh beta)
#   2. invoke manually as an escape hatch when CI is broken
#   3. avoid runner-version shell-wrapper quirks (e.g. Forgejo
#      runner v12.9.0 reporting phantom SIGPIPE on bare echo + set -eu)
#
# Usage:
#   notify-chart-bump.sh beta
#       Bump chart's develop branch with appVersion = <next-stable>-beta-<sha>
#       (next-stable = max(zddc-server-v* tag) + 1).
#       Self-skips if HEAD has a zddc-server-v* tag (the stable workflow
#       owns the bump in that case).
#
#   notify-chart-bump.sh stable VERSION
#       Bump chart's main + develop branches with appVersion = VERSION.
#       Called from deploy-release.yml's notify-chart-prod job, where
#       VERSION = "${GITHUB_REF#refs/tags/zddc-server-v}".
#
# Requires:
#   - run from the ZDDC repo root, with full git history (all tags)
#   - $CHART_FORGEJO_TOKEN with repo:write on BMCD/tnd-zddc-chart

set -eu

CHANNEL="${1:?usage: $(basename "$0") <beta|stable> [VERSION]}"
EXPLICIT_VERSION="${2:-}"

if [ -z "${CHART_FORGEJO_TOKEN:-}" ]; then
    echo "::error::CHART_FORGEJO_TOKEN env not set" >&2
    exit 1
fi

CHART_REPO="git.varasys.io/BMCD/tnd-zddc-chart.git"
CHART_URL="https://oauth2:${CHART_FORGEJO_TOKEN}@${CHART_REPO}"

case "$CHANNEL" in
    beta)
        # Self-skip if HEAD has a stable tag — prod workflow owns the
        # bump in that case (avoids both workflows racing on develop).
        STABLE_TAGS=$(git tag --points-at HEAD --list 'zddc-server-v*')
        if [ -n "$STABLE_TAGS" ]; then
            echo "HEAD has stable tag ($STABLE_TAGS) — stable workflow handles chart bump; skipping"
            exit 0
        fi

        LATEST_STABLE=$(git tag --list 'zddc-server-v*' --sort=-v:refname | head -1)
        if [ -z "$LATEST_STABLE" ]; then
            echo "::error::no zddc-server-v* tags exist; cannot derive next-stable target" >&2
            exit 1
        fi
        MAJ=$(echo "${LATEST_STABLE#zddc-server-v}" | cut -d. -f1)
        MIN=$(echo "${LATEST_STABLE#zddc-server-v}" | cut -d. -f2)
        PAT=$(echo "${LATEST_STABLE#zddc-server-v}" | cut -d. -f3)
        NEXT_STABLE="$MAJ.$MIN.$((PAT + 1))"

        # Pin to HEAD. The dev pipeline's Dockerfile fetches this SHA
        # via `git fetch --depth=1 origin <sha>` and runs `go build`
        # against it; //go:embed at build time bakes whatever
        # zddc/internal/apps/embedded/* and zddc/internal/handler/{form,
        # tables}.html are at THAT commit.
        #
        # Since `./build beta` (build:952-995) now auto-commits the
        # regenerated embedded artifacts before push, HEAD always
        # contains the bytes the binary will serve. Earlier this script
        # read the SHA from embedded/versions.txt to keep the served
        # HTML's build label cosmetically matched to the chart's
        # appVersion — but that read pinned the chart at the source-
        # side commit (HEAD-1), which is the commit BEFORE the
        # embedded refresh. The Dockerfile would then bake the previous
        # cut's bytes. Manual chart-rebases were required on every beta
        # cut. HEAD is the right anchor: substantively correct, even
        # if the build-label SHA in the served HTML is one commit
        # behind cosmetically (operators triaging "is this image
        # current?" should compare chart appVersion to the running
        # binary's `--version` output, not the HTML footer).
        FULL_SHA=$(git rev-parse HEAD)
        TARGET_VERSION="${NEXT_STABLE}-beta-${FULL_SHA}"
        BRANCHES="develop"
        TRIGGER_DESC="ZDDC beta cut"
        TRAILER="Triggered by push to git.varasys.io/VARASYS/ZDDC main with embedded/* changes (a ./build beta cut). Bumps appVersion so the dev Docker image is tagged zddc:$TARGET_VERSION, ensuring kubelet pulls a fresh image on the next helm upgrade."
        ;;
    stable)
        if [ -z "$EXPLICIT_VERSION" ]; then
            echo "::error::stable channel requires an explicit VERSION arg" >&2
            exit 1
        fi
        TARGET_VERSION="$EXPLICIT_VERSION"
        # Bump both branches: main fires BMCD pipeline-prod (prod image
        # rebuild), develop fires pipeline-dev so dev follows stable
        # whenever no beta is active.
        BRANCHES="main develop"
        TRIGGER_DESC="ZDDC stable cut"
        TRAILER="Triggered by zddc-server-v$TARGET_VERSION tag push on git.varasys.io/VARASYS/ZDDC. Bumps appVersion so prod (and dev tracking stable) rebuild against the new ZDDC stable."
        ;;
    *)
        echo "::error::unknown channel '$CHANNEL' (expected: beta | stable)" >&2
        exit 1
        ;;
esac

echo "Bumping tnd-zddc-chart appVersion → $TARGET_VERSION"
echo "Branches: $BRANCHES (HEAD=$(git rev-parse HEAD))"

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

for BRANCH in $BRANCHES; do
    echo ""
    echo "=== bumping $BRANCH ==="
    rm -rf tnd-zddc-chart
    git clone --depth=20 --branch="$BRANCH" "$CHART_URL"
    cd tnd-zddc-chart

    CURRENT=$(grep '^appVersion:' chart/Chart.yaml \
              | sed -E 's/^appVersion: *"?([^"]*)"?.*/\1/')
    if [ "$CURRENT" = "$TARGET_VERSION" ]; then
        echo "  $BRANCH already at $TARGET_VERSION; skipping"
        cd ..
        continue
    fi

    sed -i "s/^appVersion: .*/appVersion: \"$TARGET_VERSION\"/" chart/Chart.yaml
    OLD_CHART_VER=$(grep '^version:' chart/Chart.yaml | awk '{print $2}')
    MAJC=$(echo "$OLD_CHART_VER" | cut -d. -f1)
    MINC=$(echo "$OLD_CHART_VER" | cut -d. -f2)
    PATC=$(echo "$OLD_CHART_VER" | cut -d. -f3)
    # Chart-version bump strategy:
    #   stable cut → MINOR++, PATCH=0  (e.g. 0.2.7 → 0.3.0)
    #   beta cut   → PATCH++           (e.g. 0.3.0 → 0.3.1)
    # This keeps the patch number bounded (≈ #betas-per-stable, not
    # all-time), while staying monotonically increasing — JFrog chart
    # repos reject duplicate chart-version numbers, so a literal
    # "reset to 0.2.0" cycle would break uploads after the first
    # stable cut. The actual zddc-server version lives in appVersion;
    # chart version is just JFrog packaging metadata.
    if [ "$CHANNEL" = "stable" ]; then
        NEW_CHART_VER="$MAJC.$((MINC + 1)).0"
    else
        NEW_CHART_VER="$MAJC.$MINC.$((PATC + 1))"
    fi
    sed -i "s/^version: .*/version: $NEW_CHART_VER/" chart/Chart.yaml

    echo "  appVersion: $CURRENT → $TARGET_VERSION"
    echo "  version:    $OLD_CHART_VER → $NEW_CHART_VER"

    git config user.name "ZDDC Release Bot"
    git config user.email "noreply@zddc.varasys.io"
    git add chart/Chart.yaml
    git commit \
        -m "chore(chart): auto-bump appVersion to $TARGET_VERSION ($TRIGGER_DESC)" \
        -m "$TRAILER" \
        -m "Auto-generated by .forgejo/scripts/notify-chart-bump.sh. The next ZDDC beta or stable cut will overwrite this."

    git push origin "$BRANCH"
    echo "  pushed $BRANCH"
    cd ..
done

echo ""
echo "Done."
