#!/usr/bin/env bash
#
# stage-mobile-update.sh
# ----------------------
# Publishes the LogShip Mobile Android update artifacts into the logyou.de
# website project (../logship/logyou-landing, Nuxt 4), which serves them as
# static files under https://www.logyou.de/logship/ — the URL the in-app
# updater reads (see app/composables/useAppUpdate.ts and
# server/api/mobile/app-version.get.ts). Since the website relaunch the old
# SFTP web root no longer exists; deploying the website repo IS the release.
#
#     android/update-files/logship-mobile.apk  ->  <landing>/public/logship/logship-mobile.apk
#     android/update-files/version.json        ->  <landing>/public/logship/version.json
#     (replaced APK)                           ->  <landing>/public/logship/history/logship-mobile-<vn>-<vc>.apk
#     history.json                             ->  merged manifest for the in-app version browser
#
# NOTE: this is the LEGACY channel kept for devices on old builds. New builds are served from the
# ERP itself (scripts/publish-mobile-update.sh → data/mobile-releases/ on app.logship.de).
#
# The layout and the archive/history.json logic mirror scripts/upload-mobile-update.sh
# (which is still used for SFTP-hosted targets such as Blut24).
#
# Usage:
#     scripts/stage-mobile-update.sh              # copy + archive, then print the git commands
#     scripts/stage-mobile-update.sh --commit     # additionally git-commit the files in the landing repo
#     scripts/stage-mobile-update.sh --push       # --commit + git push (= production deploy via webhook)
#
# Env:
#     LANDING_DIR   path of the logyou-landing checkout (default ../logship/logyou-landing)
#     KEEP_HISTORY  how many archived APKs to keep in history/ (default 10; 0 = keep all)
#
set -euo pipefail

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
REPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
UPDATE_DIR="$REPO_ROOT/android/update-files"
APK_LOCAL="$UPDATE_DIR/logship-mobile.apk"
VERSION_LOCAL="$UPDATE_DIR/version.json"

LANDING_DIR="${LANDING_DIR:-$REPO_ROOT/../logship/logyou-landing}"
KEEP_HISTORY="${KEEP_HISTORY:-10}"
TARGET_REL="public/logship"
ARCHIVE_SUBDIR="history"

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' "$*"; }

DO_COMMIT=0; DO_PUSH=0
for a in "$@"; do
  case "$a" in
    --commit) DO_COMMIT=1 ;;
    --push) DO_COMMIT=1; DO_PUSH=1 ;;
    -h|--help) sed -n '3,30p' "$0" | sed 's/^# \{0,1\}//'; exit 0 ;;
    *) err "unknown option: $a"; exit 1 ;;
  esac
done

# --------------------------------------------------------------------------
# Validate
# --------------------------------------------------------------------------
for f in "$APK_LOCAL" "$VERSION_LOCAL"; do
  [ -f "$f" ] || { err "Missing $f — run scripts/release-app.sh (or stage the APK) first"; exit 1; }
done
if [ ! -d "$LANDING_DIR/public" ] || [ ! -f "$LANDING_DIR/nuxt.config.ts" ]; then
  err "logyou-landing project not found at $LANDING_DIR (set LANDING_DIR)"; exit 1
fi
LANDING_DIR="$(cd "$LANDING_DIR" && pwd)"
TARGET_DIR="$LANDING_DIR/$TARGET_REL"
mkdir -p "$TARGET_DIR/$ARCHIVE_SUBDIR"

json_field() { # file key -> value (string or number)
  node -e 'const j=JSON.parse(require("fs").readFileSync(process.argv[1],"utf8"));process.stdout.write(String(j[process.argv[2]]??""))' "$1" "$2"
}

new_vn="$(json_field "$VERSION_LOCAL" versionName)"
new_vc="$(json_field "$VERSION_LOCAL" versionCode)"
[ -n "$new_vn" ] && [ -n "$new_vc" ] || { err "versionName/versionCode missing in $VERSION_LOCAL"; exit 1; }

# APK ↔ version.json sanity check (the updater keys off version.json)
find_aapt() {
  local base cand
  for base in "${ANDROID_HOME:-}" "${ANDROID_SDK_ROOT:-}" "$HOME/Library/Android/sdk" "$HOME/Android/Sdk"; do
    [ -n "$base" ] || continue
    cand="$(ls -1 "$base"/build-tools/*/aapt 2>/dev/null | sort -V | tail -1 || true)"
    [ -n "$cand" ] && { printf '%s' "$cand"; return 0; }
  done
  command -v aapt >/dev/null 2>&1 && { command -v aapt; return 0; }
  return 1
}
AAPT="$(find_aapt || true)"
if [ -n "${AAPT:-}" ]; then
  badging="$("$AAPT" dump badging "$APK_LOCAL" 2>/dev/null | grep '^package:' || true)"
  apk_vn="$(printf '%s' "$badging" | sed -n "s/.*versionName='\([^']*\)'.*/\1/p")"
  apk_vc="$(printf '%s' "$badging" | sed -n "s/.*versionCode='\([^']*\)'.*/\1/p")"
  bold "Version check"
  printf '  APK         : versionName=%s versionCode=%s\n' "$apk_vn" "$apk_vc"
  printf '  version.json: versionName=%s versionCode=%s\n' "$new_vn" "$new_vc"
  if [ "$apk_vn" != "$new_vn" ] || [ "$apk_vc" != "$new_vc" ]; then
    err "version.json does NOT match the APK — devices compare version.json, a mismatch breaks updates."
    read -rp "Stage anyway? [y/N] " ans
    case "$ans" in y|Y) ;; *) exit 1;; esac
  else
    ok "version.json matches the APK"
  fi
else
  printf 'aapt not found — skipping APK/version.json match check.\n'
fi

# --------------------------------------------------------------------------
# Archive the currently published version (if any, and if different)
# --------------------------------------------------------------------------
old_vn=""; old_vc=""; ARCHIVE_NAME=""
if [ -f "$TARGET_DIR/version.json" ]; then
  old_vn="$(json_field "$TARGET_DIR/version.json" versionName)"
  old_vc="$(json_field "$TARGET_DIR/version.json" versionCode)"
fi
if [ -n "$old_vn" ] && [ -n "$old_vc" ] && [ "$old_vc" != "$new_vc" ] && [ -f "$TARGET_DIR/logship-mobile.apk" ]; then
  ARCHIVE_NAME="logship-mobile-${old_vn}-${old_vc}.apk"
fi

bold "About to stage"
printf '  from   : %s\n           %s\n' "$APK_LOCAL" "$VERSION_LOCAL"
printf '  to     : %s\n' "$TARGET_DIR"
printf '  version: %s (code %s)' "$new_vn" "$new_vc"
[ -n "$old_vc" ] && printf '  replacing %s (code %s)' "$old_vn" "$old_vc"
echo
if [ -n "$ARCHIVE_NAME" ]; then
  printf '  archive: current APK -> %s/%s (keep last %s)\n' "$ARCHIVE_SUBDIR" "$ARCHIVE_NAME" "$([ "$KEEP_HISTORY" = "0" ] && echo all || echo "$KEEP_HISTORY")"
else
  printf '  archive: (none — first release or same version)\n'
fi

if [ -n "$ARCHIVE_NAME" ]; then
  mv -f "$TARGET_DIR/logship-mobile.apk" "$TARGET_DIR/$ARCHIVE_SUBDIR/$ARCHIVE_NAME"
  # Merge the replaced version into history.json (newest first, dedup by versionCode),
  # prune to KEEP_HISTORY entries and delete archived APKs no longer listed.
  OLD_VERSION_FILE="$TARGET_DIR/version.json" HISTORY_FILE="$TARGET_DIR/history.json" \
  ARCHIVE_URL="${ARCHIVE_SUBDIR}/${ARCHIVE_NAME}" KEEP="$KEEP_HISTORY" ARCHIVE_DIR="$TARGET_DIR/$ARCHIVE_SUBDIR" \
  node -e '
    const fs = require("fs"), path = require("path");
    const oldV = JSON.parse(fs.readFileSync(process.env.OLD_VERSION_FILE, "utf8"));
    let hist = [];
    try { hist = JSON.parse(fs.readFileSync(process.env.HISTORY_FILE, "utf8")); if (!Array.isArray(hist)) hist = []; } catch { hist = []; }
    const entry = {
      versionName: oldV.versionName || "",
      versionCode: Number(oldV.versionCode) || 0,
      releaseDate: oldV.releaseDate || "",
      releaseNotes: oldV.releaseNotes || "",
      apkUrl: process.env.ARCHIVE_URL,
    };
    hist = hist.filter(h => Number(h.versionCode) !== entry.versionCode);
    hist.unshift(entry);
    hist.sort((a, b) => (Number(b.versionCode) || 0) - (Number(a.versionCode) || 0));
    const keep = Number(process.env.KEEP) || 0;
    const dropped = keep > 0 ? hist.splice(keep) : [];
    for (const d of dropped) {
      const f = path.join(process.env.ARCHIVE_DIR, path.basename(String(d.apkUrl || "")));
      if (d.apkUrl && fs.existsSync(f)) { fs.unlinkSync(f); console.log("  pruned " + path.basename(f)); }
    }
    fs.writeFileSync(process.env.HISTORY_FILE, JSON.stringify(hist, null, 2) + "\n");
    console.log("  history.json: " + hist.length + " entries");
  '
  ok "archived previous APK as $ARCHIVE_SUBDIR/$ARCHIVE_NAME"
fi

cp -f "$APK_LOCAL" "$TARGET_DIR/logship-mobile.apk"
cp -f "$VERSION_LOCAL" "$TARGET_DIR/version.json"
[ -f "$TARGET_DIR/history.json" ] || printf '[]\n' > "$TARGET_DIR/history.json"
ok "staged $TARGET_REL/logship-mobile.apk ($(du -h "$TARGET_DIR/logship-mobile.apk" | cut -f1)) + version.json"

# --------------------------------------------------------------------------
# Git (the website deploys from its repo — pushing main = release)
# --------------------------------------------------------------------------
cd "$LANDING_DIR"
MSG="Mobile app update ${new_vn} (code ${new_vc})"
if [ "$DO_COMMIT" = "1" ]; then
  git add -A -- "$TARGET_REL"
  if git diff --cached --quiet; then
    ok "nothing to commit in $TARGET_REL"
  else
    git commit -q -m "$MSG" -- "$TARGET_REL"
    ok "committed: $MSG"
  fi
  if [ "$DO_PUSH" = "1" ]; then
    git push
    ok "pushed — the website deploy publishes https://www.logyou.de/logship/version.json"
  fi
else
  echo
  bold "Next: commit + deploy the website"
  printf '  cd %s\n  git add -A -- %s\n  git commit -m "%s"\n  git push        # webhook deploy of logyou.de\n' "$LANDING_DIR" "$TARGET_REL" "$MSG"
fi
