#!/usr/bin/env bash
# onx-cert-install-manual — Install a user-supplied (3rd-party) SSL cert.
#
# Input (stdin JSON):
#   domain        string   Domain whose vhost will use the cert
#   cert          string   PEM-encoded leaf certificate
#   private_key   string   PEM-encoded private key (RSA or EC)
#   chain         string   Optional PEM-encoded intermediate CA bundle
#
# Output (stdout JSON):
#   {"domain":...,
#    "cert_path":"/etc/onoxsoft/ssl/manual/<domain>/cert.pem",
#    "key_path": "/etc/onoxsoft/ssl/manual/<domain>/privkey.pem",
#    "chain_path":...,
#    "fullchain_path":...,
#    "expires_at":..., "issuer":..., "subject":...}
#
# PHP tarafı openssl_x509_check_private_key + CN/SAN sanity zaten yaptı; bu
# script yalnızca dosyaya yazıp permission'ları sıkar. Apache reload sonra
# httpd-reload sysapi'siyle ayrı bir hop ile yapılır (caller'a bırakılır).
#
# Exit codes: 0=ok 1=invalid-input 2=preflight-fail 3=exec-fail
#
# Deployed to: /usr/local/onoxsoft/bin/onx-cert-install-manual

set -euo pipefail

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

readonly SSL_BASE="/etc/onoxsoft/ssl/manual"

# ── Read & parse stdin ───────────────────────────────────────────────────────
INPUT=$(cat)
onx_require_json "${INPUT}"

DOMAIN=$(onx_json_get "${INPUT}" "domain")
CERT_PEM=$(onx_json_get "${INPUT}" "cert")
KEY_PEM=$(onx_json_get "${INPUT}" "private_key")
CHAIN_PEM=$(onx_json_get "${INPUT}" "chain" "")

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

[[ "${CERT_PEM}" == *"BEGIN CERTIFICATE"* ]] \
    || onx_die 1 "cert is not a valid PEM (missing BEGIN CERTIFICATE header)"

[[ "${KEY_PEM}" == *"PRIVATE KEY"* ]] \
    || onx_die 1 "private_key is not a valid PEM (missing PRIVATE KEY header)"

# ── Preflight ────────────────────────────────────────────────────────────────
command -v openssl >/dev/null 2>&1 || onx_die 2 "openssl not installed"

INSTALL_DIR="${SSL_BASE}/${DOMAIN}"
CERT_FILE="${INSTALL_DIR}/cert.pem"
KEY_FILE="${INSTALL_DIR}/privkey.pem"
CHAIN_FILE="${INSTALL_DIR}/chain.pem"
FULLCHAIN_FILE="${INSTALL_DIR}/fullchain.pem"
BACKUP_DIR="${SSL_BASE}/.backups/${DOMAIN}/$(date -u +%Y%m%dT%H%M%SZ)"

# ── Backup existing cert (if any) ────────────────────────────────────────────
if [[ -d "${INSTALL_DIR}" ]]; then
    mkdir -p "${BACKUP_DIR}"
    cp -a "${INSTALL_DIR}/." "${BACKUP_DIR}/" 2>/dev/null || true
    onx_log "Manual cert backup: ${BACKUP_DIR}"
fi

mkdir -p "${INSTALL_DIR}"
chmod 750 "${INSTALL_DIR}"

# ── Write PEM payloads ───────────────────────────────────────────────────────
# `printf` ile yaz — echo bazı shell'lerde \n'leri yutar.
printf '%s\n' "${CERT_PEM}" > "${CERT_FILE}"
printf '%s\n' "${KEY_PEM}"  > "${KEY_FILE}"

if [[ -n "${CHAIN_PEM}" && "${CHAIN_PEM}" == *"BEGIN CERTIFICATE"* ]]; then
    printf '%s\n' "${CHAIN_PEM}" > "${CHAIN_FILE}"
    cat "${CERT_FILE}" "${CHAIN_FILE}" > "${FULLCHAIN_FILE}"
else
    : > "${CHAIN_FILE}"
    cp "${CERT_FILE}" "${FULLCHAIN_FILE}"
fi

chmod 644 "${CERT_FILE}" "${CHAIN_FILE}" "${FULLCHAIN_FILE}"
chmod 600 "${KEY_FILE}"

# Apache okuyabilsin (group readable on key only via apache group)
if getent group apache >/dev/null 2>&1; then
    chown root:apache "${KEY_FILE}" 2>/dev/null || true
    chmod 640 "${KEY_FILE}"
fi

# ── Sanity-check via openssl ─────────────────────────────────────────────────
if ! openssl x509 -in "${CERT_FILE}" -noout -text >/dev/null 2>&1; then
    onx_die 3 "openssl x509 verify failed for ${CERT_FILE}"
fi

EXPIRES_AT=$(openssl x509 -in "${CERT_FILE}" -noout -enddate 2>/dev/null \
    | sed 's/notAfter=//')
ISSUED_AT=$(openssl x509 -in "${CERT_FILE}" -noout -startdate 2>/dev/null \
    | sed 's/notBefore=//')
ISSUER=$(openssl x509 -in "${CERT_FILE}" -noout -issuer 2>/dev/null \
    | sed 's/^issuer=//')
SUBJECT=$(openssl x509 -in "${CERT_FILE}" -noout -subject 2>/dev/null \
    | sed 's/^subject=//')
SERIAL=$(openssl x509 -in "${CERT_FILE}" -noout -serial 2>/dev/null \
    | sed 's/^serial=//')
FP=$(openssl x509 -in "${CERT_FILE}" -noout -fingerprint -sha256 2>/dev/null \
    | sed 's/^SHA256 Fingerprint=//')

onx_log "Manual cert installed for ${DOMAIN} (issuer=${ISSUER})"

# ── Emit JSON ────────────────────────────────────────────────────────────────
jq -n \
    --arg domain "${DOMAIN}" \
    --arg cert "${CERT_FILE}" \
    --arg key "${KEY_FILE}" \
    --arg chain "${CHAIN_FILE}" \
    --arg fullchain "${FULLCHAIN_FILE}" \
    --arg expires "${EXPIRES_AT}" \
    --arg issued "${ISSUED_AT}" \
    --arg issuer "${ISSUER}" \
    --arg subject "${SUBJECT}" \
    --arg serial "${SERIAL}" \
    --arg fp "${FP}" \
    '{
       domain: $domain,
       cert_path: $cert, key_path: $key, chain_path: $chain, fullchain_path: $fullchain,
       expires_at: $expires, issued_at: $issued,
       issuer: $issuer, subject: $subject,
       serial_number: $serial, fingerprint_sha256: $fp
     }'
