#!/usr/bin/env bash
#
# scripts/gen-keystore.sh
# ---------------------------------------------------------------------------
# Generate a NEW dedicated release keystore for Wisp, then print the exact
# commands to base64-encode it and the list of Gitea Actions secrets to set.
#
# Run this ONCE on a trusted machine. The resulting keystore is the SINGLE
# source of truth for signing every future Wisp APK — if you lose it (or its
# passwords), you cannot ship an update that upgrades an already-installed APK
# (signature mismatch). BACK IT UP somewhere safe (password manager / offline).
#
# This script does NOT touch CI, does NOT commit anything, and does NOT generate
# a "real" production key for you silently — YOU run it, YOU keep the output.
#
# Requires: keytool (ships with any JDK).
#
# Usage:
#   ./scripts/gen-keystore.sh                       # interactive password prompts
#   STORE_PASS=... KEY_PASS=... ./scripts/gen-keystore.sh   # non-interactive
# ---------------------------------------------------------------------------

set -euo pipefail

# --- Tunables (override via env) --------------------------------------------
# Output keystore path. Default lands beside the script, OUTSIDE the app tree so
# you don't accidentally commit it (.gitignore already excludes *.jks/*.keystore,
# but we keep it out of the way regardless).
KEYSTORE_OUT="${KEYSTORE_OUT:-./wisp-release.keystore}"
# Key alias. MUST match ANDROID_KEY_ALIAS in CI. scripts/ci-android-sign.sh and
# the docs assume the alias 'wisp'.
KEY_ALIAS="${KEY_ALIAS:-wisp}"
# RSA 2048, valid for 10000 days (~27 years) — Google Play's minimum validity
# recommendation for upload/app-signing keys is well within this.
KEY_ALG="RSA"
KEY_SIZE="2048"
VALIDITY_DAYS="10000"
# Distinguished Name. Edit to taste; only CN is really meaningful for an app key.
DNAME="${DNAME:-CN=Wisp, OU=Wisp, O=briggen.dev, L=, ST=, C=DE}"

log()  { printf '[gen-keystore] %s\n' "$*"; }
fail() { printf '[gen-keystore] ERROR: %s\n' "$*" >&2; exit 1; }

# --- Preconditions ----------------------------------------------------------
command -v keytool >/dev/null 2>&1 || fail "keytool not found. Install a JDK (e.g. JDK 17)."

if [[ -e "${KEYSTORE_OUT}" ]]; then
    fail "Refusing to overwrite existing keystore at ${KEYSTORE_OUT}. Move/delete it first."
fi

# --- Collect passwords ------------------------------------------------------
# Allow non-interactive use via env (STORE_PASS / KEY_PASS); otherwise prompt.
# We do NOT echo passwords. For most setups STORE_PASS and KEY_PASS can be equal.
STORE_PASS="${STORE_PASS:-}"
KEY_PASS="${KEY_PASS:-}"

if [[ -z "${STORE_PASS}" ]]; then
    read -r -s -p "Enter NEW keystore (store) password: " STORE_PASS; echo
    read -r -s -p "Confirm keystore password: " STORE_PASS_CONFIRM; echo
    [[ "${STORE_PASS}" == "${STORE_PASS_CONFIRM}" ]] || fail "Store passwords do not match."
fi
[[ "${#STORE_PASS}" -ge 6 ]] || fail "Keystore password must be at least 6 characters (keytool requirement)."

if [[ -z "${KEY_PASS}" ]]; then
    read -r -s -p "Enter NEW key (alias) password [blank = same as store]: " KEY_PASS; echo
    KEY_PASS="${KEY_PASS:-$STORE_PASS}"
fi

# --- Generate the keystore --------------------------------------------------
# -storetype PKCS12 is the modern default (JKS is deprecated). keytool will emit
# a PKCS12 keystore; that's fully supported by Gradle/apksigner.
log "Generating ${KEY_ALG} ${KEY_SIZE} key, alias '${KEY_ALIAS}', valid ${VALIDITY_DAYS} days..."
keytool -genkeypair \
    -keystore "${KEYSTORE_OUT}" \
    -storetype PKCS12 \
    -alias "${KEY_ALIAS}" \
    -keyalg "${KEY_ALG}" \
    -keysize "${KEY_SIZE}" \
    -validity "${VALIDITY_DAYS}" \
    -dname "${DNAME}" \
    -storepass "${STORE_PASS}" \
    -keypass "${KEY_PASS}"

log "Keystore created: ${KEYSTORE_OUT}"
echo

# --- Print follow-up instructions -------------------------------------------
# Show the EXACT base64 command and the secrets to configure in Gitea. We print
# the base64 command (not the base64 itself, and never the passwords) so the
# human runs it themselves and pastes into the Gitea secrets UI.
cat <<EOF
=============================================================================
NEXT STEPS — configure Gitea Actions secrets for the build-apk job
=============================================================================

1) Base64-encode the keystore (single line, no wrapping) and copy it:

     # Linux:
     base64 -w0 "${KEYSTORE_OUT}"

     # macOS (no -w flag; -b0 disables wrapping):
     base64 -b0 "${KEYSTORE_OUT}"

   Copy the entire single-line output — that is ANDROID_KEYSTORE_BASE64.

2) In Gitea -> the Wisp repo -> Settings -> Actions -> Secrets, add:

     ANDROID_KEYSTORE_BASE64    = <the base64 string from step 1>
     ANDROID_KEYSTORE_PASSWORD  = <the store password you just chose>
     ANDROID_KEY_ALIAS          = ${KEY_ALIAS}
     ANDROID_KEY_PASSWORD       = <the key password you just chose>

   (These names match scripts/ci-android-sign.sh and .gitea/workflows/ci.yml.)

3) BACK UP "${KEYSTORE_OUT}" and BOTH passwords in a safe place (password
   manager / offline). If lost, you can never update an already-installed APK.

4) Do NOT commit the keystore. (.gitignore already excludes *.keystore/*.jks.)
=============================================================================
EOF
