#!/usr/bin/env bash
#
# release-app.sh — one-command release of the BUNDLED Capacitor app.
#
# Does the whole cycle:
#   1. bump the version (android/app/build.gradle + android/update-files/version.json)
#   2. npm run build:app        (rebuild the mobile-only static SPA → .output/public)
#   3. npm run cap:sync:app     (copy the bundle into android/)
#   4. gradle assembleDebug     (build the APK) + stage it into android/update-files/
#   5. scripts/upload-mobile-update.sh   (publish APK + version.json so devices get the update)
#
# Usage:
#   scripts/release-app.sh                 # auto-bump the patch (e.g. 1.0.2 -> 1.0.3)
#   scripts/release-app.sh 1.1.0           # set an explicit versionName
#   scripts/release-app.sh --no-upload     # build + stage only, don't publish
#   RELEASE_NOTES="..." scripts/release-app.sh   # skip the notes prompt
#
# versionCode is always auto-incremented by 1. versionName must strictly increase or the in-app
# updater won't offer the release.
#
set -euo pipefail

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

GRADLE="android/app/build.gradle"
VERSION_JSON="android/update-files/version.json"
APK_BUILT="android/app/build/outputs/apk/debug/app-debug.apk"
APK_STAGED="android/update-files/logship-mobile.apk"

bold() { printf '\033[1m%s\033[0m\n' "$*"; }
err()  { printf '\033[31mERROR:\033[0m %s\n' "$*" >&2; }
ok()   { printf '\033[32m✔\033[0m %s\n' "$*"; }

# --------------------------------------------------------------------------
# Args
# --------------------------------------------------------------------------
NO_UPLOAD=0
NEW_NAME_ARG=""
for a in "$@"; do
  case "$a" in
    --no-upload) NO_UPLOAD=1 ;;
    -h|--help) sed -n '3,22p' "$0" | sed 's/^# \{0,1\}//'; exit 0 ;;
    --*) err "unknown option: $a"; exit 1 ;;
    *) NEW_NAME_ARG="$a" ;;
  esac
done

# --------------------------------------------------------------------------
# Current version
# --------------------------------------------------------------------------
CUR_CODE="$(grep -E 'versionCode +[0-9]+' "$GRADLE" | head -1 | grep -oE '[0-9]+' | head -1)"
CUR_NAME="$(grep -E 'versionName +"[^"]*"' "$GRADLE" | head -1 | sed -E 's/.*versionName +"([^"]*)".*/\1/')"
if [ -z "$CUR_CODE" ] || [ -z "$CUR_NAME" ]; then
  err "could not read current versionCode/versionName from $GRADLE"; exit 1
fi

NEW_CODE=$(( CUR_CODE + 1 ))
if [ -n "$NEW_NAME_ARG" ]; then
  NEW_NAME="$NEW_NAME_ARG"
else
  # auto-increment the last dotted numeric segment (bash 3.2 safe — no negative array index)
  IFS='.' read -r -a PARTS <<< "$CUR_NAME"
  last=$(( ${#PARTS[@]} - 1 ))
  if ! [[ "${PARTS[$last]}" =~ ^[0-9]+$ ]]; then
    err "versionName '$CUR_NAME' doesn't end in a number — pass an explicit version: scripts/release-app.sh <x.y.z>"; exit 1
  fi
  PARTS[$last]=$(( ${PARTS[$last]} + 1 ))
  NEW_NAME="$(IFS='.'; echo "${PARTS[*]}")"
fi

echo
bold "Release  $CUR_NAME (code $CUR_CODE)  ->  $NEW_NAME (code $NEW_CODE)"

# --------------------------------------------------------------------------
# Release notes
# --------------------------------------------------------------------------
RELEASE_NOTES="${RELEASE_NOTES:-}"
if [ -z "$RELEASE_NOTES" ]; then
  read -rp "Release notes (DE) [Verbesserungen und Fehlerbehebungen.]: " RELEASE_NOTES
  RELEASE_NOTES="${RELEASE_NOTES:-Verbesserungen und Fehlerbehebungen.}"
fi

read -rp "Build${NO_UPLOAD:+ (no upload)} this release? [y/N] " go
case "$go" in y|Y) ;; *) echo "Aborted."; exit 0;; esac

# --------------------------------------------------------------------------
# 1. Bump versions
# --------------------------------------------------------------------------
sed -E "s/versionCode +[0-9]+/versionCode $NEW_CODE/; s/versionName +\"[^\"]*\"/versionName \"$NEW_NAME\"/" \
  "$GRADLE" > "$GRADLE.tmp" && mv "$GRADLE.tmp" "$GRADLE"
ok "build.gradle → versionName $NEW_NAME / versionCode $NEW_CODE"

REL_DATE="$(date +%Y-%m-%d)"
MIN_REQ="$(grep -oE '"minRequiredVersion"[^,}]*' "$VERSION_JSON" 2>/dev/null | sed -E 's/.*: *"([^"]*)".*/\1/')"
MIN_REQ="${MIN_REQ:-1.0.0}"
# JSON-escape the notes (backslash + double-quote)
ESC_NOTES="$(printf '%s' "$RELEASE_NOTES" | sed 's/\\/\\\\/g; s/"/\\"/g')"
cat > "$VERSION_JSON" <<EOF
{
  "versionName": "$NEW_NAME",
  "versionCode": $NEW_CODE,
  "apkUrl": "logship-mobile.apk",
  "releaseNotes": "$ESC_NOTES",
  "releaseDate": "$REL_DATE",
  "minRequiredVersion": "$MIN_REQ"
}
EOF
ok "version.json → versionName $NEW_NAME / versionCode $NEW_CODE"

# --------------------------------------------------------------------------
# 2. Build the static SPA + 3. sync native
# --------------------------------------------------------------------------
echo; bold "Building mobile SPA (npm run build:app)…"
npm run build:app
echo; bold "Syncing native project (npm run cap:sync:app)…"
npm run cap:sync:app

# --------------------------------------------------------------------------
# 4. Build the APK + stage
# --------------------------------------------------------------------------
export JAVA_HOME="$(/usr/libexec/java_home -v 21 2>/dev/null || echo /Library/Java/JavaVirtualMachines/jdk-21.jdk/Contents/Home)"
echo; bold "Building APK (gradle assembleDebug)…"
( cd android && ./gradlew assembleDebug --console=plain )

if [ ! -f "$APK_BUILT" ]; then err "APK not found at $APK_BUILT"; exit 1; fi
cp "$APK_BUILT" "$APK_STAGED"
ok "staged $APK_STAGED ($(du -h "$APK_STAGED" | cut -f1))"

# Quick sanity: APK version should match version.json (the upload script re-checks this too).
AAPT="$(ls -1 "${ANDROID_HOME:-$HOME/Library/Android/sdk}"/build-tools/*/aapt 2>/dev/null | sort -V | tail -1 || true)"
if [ -n "$AAPT" ]; then
  APK_VER="$("$AAPT" dump badging "$APK_STAGED" 2>/dev/null | grep -oE "versionCode='[0-9]+' versionName='[^']+'")"
  echo "  APK: $APK_VER"
fi

# --------------------------------------------------------------------------
# 5. Publish
# --------------------------------------------------------------------------
if [ "$NO_UPLOAD" = "1" ]; then
  echo; ok "Build complete (upload skipped: --no-upload)."
  echo "  Publish later with:  scripts/upload-mobile-update.sh"
else
  echo; bold "Publishing…"
  "$SCRIPT_DIR/upload-mobile-update.sh"
fi

echo
ok "Done — released $NEW_NAME (code $NEW_CODE)."
echo "  ↪ Commit the version bump:  git add $GRADLE $VERSION_JSON && git commit -m \"release app $NEW_NAME\""
