#!/usr/bin/env bash
#
# onx-dnssec-enable — Zone için DNSSEC aktive et (PowerDNS pdnsutil)
#
# Stdin:  {"zone":"example.com","algorithm":"ECDSAP256SHA256"}
# Stdout: {"ok":true,"zone":"...","ksk":{...},"ds_records":[...]}
#
# Defaults:
#   algorithm: ECDSAP256SHA256 (RFC 8624 recommended, smaller signatures vs RSA)
#
# Exit codes: 0=ok 1=invalid_input 2=preflight_fail 3=execution_fail

set -uo pipefail

die() {
    local msg="$1" code="${2:-3}"
    msg="${msg//\\/\\\\}"; msg="${msg//\"/\\\"}"
    printf '{"error":"%s","code":%d}\n' "$msg" "$code" >&2
    exit "$code"
}

INPUT=$(cat 2>/dev/null || echo '{}')
ZONE=$(echo "$INPUT" | jq -r '.zone // ""')
ALGORITHM=$(echo "$INPUT" | jq -r '.algorithm // "ecdsa256"')

[[ -z "$ZONE" ]] && die "zone gerekli" 1
[[ "$ZONE" =~ ^[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$ ]] || die "Geçersiz zone: $ZONE" 1

# Preflight
command -v pdnsutil >/dev/null 2>&1 || \
    die "pdnsutil bulunamadı. PowerDNS authoritative paketi kurulu olmalı: dnf install pdns" 2

# Zone var mı?
pdnsutil show-zone "$ZONE" >/dev/null 2>&1 || \
    die "Zone PowerDNS'de yok: $ZONE" 2

# Zaten DNSSEC aktif mi?
if pdnsutil show-zone "$ZONE" 2>/dev/null | grep -q "Zone is .* presigned\|Zone has \(NSEC\|NSEC3\)"; then
    # Zaten varsa idempotent — DS records'u dön
    DS_LINES=$(pdnsutil show-zone "$ZONE" 2>/dev/null | grep "^DS = " | sed 's/^DS = //')
    DS_JSON=$(printf '%s\n' "$DS_LINES" | jq -R -s -c 'split("\n") | map(select(length>0))')
    jq -nc --arg zone "$ZONE" --argjson ds "$DS_JSON" \
        '{ok:true,zone:$zone,already_enabled:true,ds_records:$ds}'
    exit 0
fi

# Algoritma mapping
case "$ALGORITHM" in
    ecdsa256|ecdsap256sha256|ECDSAP256SHA256) ALGO="ecdsa256" ;;
    ecdsa384|ECDSAP384SHA384) ALGO="ecdsa384" ;;
    rsasha256|RSASHA256) ALGO="rsasha256" ;;
    ed25519|ED25519) ALGO="ed25519" ;;
    *) ALGO="ecdsa256" ;;
esac

# DNSSEC enable — KSK+ZSK otomatik
pdnsutil secure-zone "$ZONE" 2>&1 >/dev/null || \
    die "secure-zone başarısız: $ZONE" 3

# NSEC3 (modern, daha güvenli — zone walking koruması)
pdnsutil set-nsec3 "$ZONE" "1 0 0 -" 2>/dev/null || true

# Rectify (NSEC/NSEC3 + RRSIG hesaplamaları)
pdnsutil rectify-zone "$ZONE" 2>&1 >/dev/null || \
    die "rectify-zone başarısız: $ZONE" 3

# DS records (registrar'a verilecek)
DS_LINES=$(pdnsutil show-zone "$ZONE" 2>/dev/null | grep "^DS = " | sed 's/^DS = //')
DS_JSON=$(printf '%s\n' "$DS_LINES" | jq -R -s -c 'split("\n") | map(select(length>0))')

# Anahtarlar (KSK/ZSK ID + bilgi)
KEYS_RAW=$(pdnsutil list-keys "$ZONE" 2>/dev/null || echo "")

# Output
jq -nc \
    --arg zone "$ZONE" \
    --arg algo "$ALGO" \
    --argjson ds "$DS_JSON" \
    --arg keys "$KEYS_RAW" \
    '{ok:true,zone:$zone,algorithm:$algo,ds_records:$ds,keys_info:$keys,note:"DS kayıtlarını registrar paneline ekleyin (TPMK/Natro/İsimTescil → DNSSEC → DS Record)."}'

exit 0
