#!/usr/bin/env bash
# onx-cert-renew — Force-renew an existing Let's Encrypt certificate.
#
# Input (stdin JSON):
#   domain  string  Domain whose cert to renew
#   force   bool    Force renewal even if not near expiry (default: false)
#
# Output (stdout JSON):
#   {"renewed":true, "cert_path":..., "expires_at":..., "issuer":"Let's Encrypt"}
#
# Exit codes: 0=ok 1=invalid-input 2=preflight-fail 3=exec-fail
#
# Deployed to: /usr/local/onoxsoft/bin/onx-cert-renew

set -euo pipefail

SCRIPT_DIR="$(dirname "$(readlink -f "$0")")"
# shellcheck source=_lib/common.sh
source "${SCRIPT_DIR}/_lib/common.sh"

# ── Constants ────────────────────────────────────────────────────────────────
export LE_WORKING_DIR="/etc/onoxsoft/acme.sh"
ACME_BIN="${LE_WORKING_DIR}/acme.sh"
ACME_CERT_BASE="/etc/letsencrypt/live"

# ── Read & parse stdin ───────────────────────────────────────────────────────
INPUT=$(cat)

onx_require_json "${INPUT}"

DOMAIN=$(onx_json_get "${INPUT}" "domain")
FORCE=$(onx_json_get_bool "${INPUT}" "force" "false")

# ── Input validation ─────────────────────────────────────────────────────────
onx_validate_domain "${DOMAIN}"

# ── Preflight ────────────────────────────────────────────────────────────────
[[ -f "${ACME_BIN}" && -x "${ACME_BIN}" ]] || \
  onx_die 2 "acme.sh not found: ${ACME_BIN}"

CERT_INSTALL_DIR="${ACME_CERT_BASE}/${DOMAIN}"
CERT_FILE="${CERT_INSTALL_DIR}/fullchain.pem"
KEY_FILE="${CERT_INSTALL_DIR}/privkey.pem"
CHAIN_FILE="${CERT_INSTALL_DIR}/chain.pem"

# ── Renew ────────────────────────────────────────────────────────────────────
mkdir -p "/var/log/onoxsoft"

RENEW_CMD=("${ACME_BIN}" --renew -d "${DOMAIN}")
[[ "${FORCE}" == "true" ]] && RENEW_CMD+=(--force)

onx_log "Renewing certificate for: ${DOMAIN}"

if ! "${RENEW_CMD[@]}" 2>&1 | tee -a "/var/log/onoxsoft/acme-${DOMAIN}.log"; then
  RENEW_EC=$?
  [[ "${RENEW_EC}" -ne 2 ]] && onx_die 3 "acme.sh --renew failed for ${DOMAIN} (exit ${RENEW_EC})"
fi

# ── Re-install cert to canonical paths ───────────────────────────────────────
mkdir -p "${CERT_INSTALL_DIR}"

INSTALL_CMD=(
  "${ACME_BIN}" --install-cert -d "${DOMAIN}"
  --cert-file      "${CERT_INSTALL_DIR}/cert.pem"
  --key-file       "${KEY_FILE}"
  --fullchain-file "${CERT_FILE}"
  --ca-file        "${CHAIN_FILE}"
  --reloadcmd      "systemctl reload httpd 2>/dev/null || true"
)

"${INSTALL_CMD[@]}" 2>&1 | tee -a "/var/log/onoxsoft/acme-${DOMAIN}.log" || \
  onx_die 3 "acme.sh --install-cert failed after renew"

# ── Read expiry ───────────────────────────────────────────────────────────────
EXPIRES_AT=""
if command -v openssl >/dev/null 2>&1 && [[ -f "${CERT_FILE}" ]]; then
  EXPIRES_AT=$(openssl x509 -enddate -noout -in "${CERT_FILE}" 2>/dev/null \
    | sed 's/notAfter=//' || echo "")
fi

# ── Success ──────────────────────────────────────────────────────────────────
onx_json_out \
  "renewed"    "true" \
  "cert_path"  "${CERT_FILE}" \
  "expires_at" "${EXPIRES_AT}" \
  "issuer"     "Let's Encrypt"
