#!/usr/bin/env bash
#
# onx-panel-cert-read — Panel hostname için /etc/onoxsoft/ssl/<hostname>.crt
# dosyasını root yetkisi ile oku ve metadata'sını JSON döndür.
#
# Bu wrapper PHP-FPM apache user'ı /etc/onoxsoft/ssl dizinine erişemediği
# (chmod 700) durumlar için fallback yoldur. SslManagerController::readPanelCert()
# direct is_readable() check'i başarısız olursa bu sysapi'yi çağırır.
#
# Stdin (JSON):
#   {"hostname":"panel.onoxsoft.com.tr"}
#
# Stdout (JSON):
#   {
#     "exists": true,
#     "issuer": "Let's Encrypt",
#     "issuer_cn": "R3",
#     "subject_cn": "panel.onoxsoft.com.tr",
#     "is_self_signed": false,
#     "expires_at": "2026-08-17T06:35:17Z",
#     "expires_epoch": 1755...,
#     "days_until_expiry": 87,
#     "fingerprint_sha256": "AB:CD:...",
#     "cert_path": "/etc/onoxsoft/ssl/panel.onoxsoft.com.tr.crt",
#     "key_exists": true,
#     "fullchain_exists": true
#   }
#
# Exit:
#   0 = success (her zaman, cert yoksa exists:false döner)
#   1 = invalid input (hostname yok / bozuk)
#   2 = preflight fail (openssl yok)

set -uo pipefail

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

# ── Input ──────────────────────────────────────────────────────────────────
onx_json_input
HOSTNAME=$(onx_json_field "hostname")

[[ -z "${HOSTNAME}" ]] && onx_die 1 "hostname gerekli"

# Basit hostname güvenlik kontrolü — path traversal koruması
if [[ "${HOSTNAME}" =~ [^a-zA-Z0-9.\-] ]]; then
    onx_die 1 "geçersiz hostname formatı: ${HOSTNAME}"
fi
if [[ "${HOSTNAME}" == *".."* || "${HOSTNAME}" == *"/"* ]]; then
    onx_die 1 "geçersiz hostname formatı: ${HOSTNAME}"
fi

command -v openssl >/dev/null 2>&1 || onx_die 2 "openssl bulunamadı"

SSL_DIR="/etc/onoxsoft/ssl"
CERT_PATH="${SSL_DIR}/${HOSTNAME}.crt"
KEY_PATH="${SSL_DIR}/${HOSTNAME}.key"
FULLCHAIN_PATH="${SSL_DIR}/${HOSTNAME}.fullchain"

# ── Cert var mı? ───────────────────────────────────────────────────────────
if [[ ! -f "${CERT_PATH}" ]]; then
    jq -nc \
        --arg path "${CERT_PATH}" \
        --arg host "${HOSTNAME}" \
        '{exists:false,hostname:$host,cert_path:$path,issuer:"unknown",expires_at:null,days_until_expiry:null,is_self_signed:false,fingerprint_sha256:null,key_exists:false,fullchain_exists:false}'
    exit 0
fi

if [[ ! -r "${CERT_PATH}" ]]; then
    onx_die 2 "cert dosyası okunamıyor (root da okuyamıyor?): ${CERT_PATH}"
fi

# ── Parse cert ─────────────────────────────────────────────────────────────
CERT_TEXT=$(openssl x509 -in "${CERT_PATH}" -noout -subject -issuer -dates -fingerprint -sha256 2>/dev/null || true)

if [[ -z "${CERT_TEXT}" ]]; then
    onx_die 3 "openssl x509 parse başarısız: ${CERT_PATH}"
fi

# Trim helper — xargs kullanmıyoruz çünkü Let's Encrypt issuer'da ("Let's Encrypt")
# tek tırnak var, xargs unmatched-quote error veriyor. Pure sed ile trim ediyoruz.
_trim() { sed -E 's/^[[:space:]]+//;s/[[:space:]]+$//'; }

# Subject CN
SUBJECT_LINE=$(printf '%s\n' "${CERT_TEXT}" | grep -E '^subject=' | head -1)
SUBJECT_CN=$(printf '%s' "${SUBJECT_LINE}" | sed -nE 's/.*CN[[:space:]]*=[[:space:]]*([^,/]+).*/\1/p' | _trim)

# Issuer CN + O
ISSUER_LINE=$(printf '%s\n' "${CERT_TEXT}" | grep -E '^issuer=' | head -1)
ISSUER_CN=$(printf '%s' "${ISSUER_LINE}" | sed -nE 's/.*CN[[:space:]]*=[[:space:]]*([^,/]+).*/\1/p' | _trim)
ISSUER_O=$(printf '%s' "${ISSUER_LINE}" | sed -nE 's/.*O[[:space:]]*=[[:space:]]*([^,/]+).*/\1/p' | _trim)

# Tercihli issuer label: O varsa O, yoksa CN
if [[ -n "${ISSUER_O}" ]]; then
    ISSUER_LABEL="${ISSUER_O}"
elif [[ -n "${ISSUER_CN}" ]]; then
    ISSUER_LABEL="${ISSUER_CN}"
else
    ISSUER_LABEL="unknown"
fi

# Expiry
NOT_AFTER=$(printf '%s\n' "${CERT_TEXT}" | grep -E '^notAfter=' | sed 's/^notAfter=//' || true)
EXPIRES_AT=""
EXPIRES_EPOCH=0
DAYS_LEFT="null"

if [[ -n "${NOT_AFTER}" ]]; then
    EXPIRES_EPOCH=$(date -d "${NOT_AFTER}" +%s 2>/dev/null || echo 0)
    if [[ "${EXPIRES_EPOCH}" -gt 0 ]]; then
        EXPIRES_AT=$(date -d "@${EXPIRES_EPOCH}" -u +"%Y-%m-%dT%H:%M:%SZ" 2>/dev/null || echo "")
        NOW_EPOCH=$(date +%s)
        DAYS_LEFT=$(( (EXPIRES_EPOCH - NOW_EPOCH) / 86400 ))
    fi
fi

# Fingerprint
FINGERPRINT=$(printf '%s\n' "${CERT_TEXT}" | grep -iE '^sha256 fingerprint=' | head -1 | sed -E 's/^[^=]*=//' || true)

# Self-signed check
IS_SELF_SIGNED="false"
if [[ -n "${SUBJECT_CN}" && "${SUBJECT_CN}" == "${ISSUER_CN}" ]]; then
    IS_SELF_SIGNED="true"
fi

# Key + fullchain var mı?
KEY_EXISTS="false"
FULLCHAIN_EXISTS="false"
[[ -f "${KEY_PATH}" ]] && KEY_EXISTS="true"
[[ -f "${FULLCHAIN_PATH}" ]] && FULLCHAIN_EXISTS="true"

# ── Output ─────────────────────────────────────────────────────────────────
jq -nc \
    --arg host "${HOSTNAME}" \
    --arg path "${CERT_PATH}" \
    --arg subj "${SUBJECT_CN}" \
    --arg iss "${ISSUER_LABEL}" \
    --arg iss_cn "${ISSUER_CN}" \
    --arg exp_at "${EXPIRES_AT}" \
    --argjson exp_epoch "${EXPIRES_EPOCH:-0}" \
    --argjson days "${DAYS_LEFT}" \
    --arg fp "${FINGERPRINT}" \
    --argjson self "${IS_SELF_SIGNED}" \
    --argjson key_ok "${KEY_EXISTS}" \
    --argjson chain_ok "${FULLCHAIN_EXISTS}" \
    '{
        exists: true,
        hostname: $host,
        cert_path: $path,
        subject_cn: $subj,
        issuer: $iss,
        issuer_cn: $iss_cn,
        is_self_signed: $self,
        expires_at: ($exp_at | if . == "" then null else . end),
        expires_epoch: $exp_epoch,
        days_until_expiry: $days,
        fingerprint_sha256: ($fp | if . == "" then null else . end),
        key_exists: $key_ok,
        fullchain_exists: $chain_ok
    }'

exit 0
