#!/usr/bin/env bash
# onx-archive-extract — Arşivi belirtilen klasöre çıkar
# Input:  {"archive":"/home/onx_xxx/backup.zip","destination":"/home/onx_xxx/restore"}
# Output: {"files_extracted":42,"destination":"/home/onx_xxx/restore"}

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
source "${SCRIPT_DIR}/_lib/common.sh"

require_root
onx_json_input

# ─── Parse input ─────────────────────────────────────────────────────────────
ARCHIVE="$(onx_json_field archive)"
DESTINATION="$(onx_json_field destination)"

[[ -z "$ARCHIVE" ]]     && onx_die 1 "archive zorunlu"
[[ -z "$DESTINATION" ]] && onx_die 1 "destination zorunlu"

# ─── Validate paths ───────────────────────────────────────────────────────────
ARCHIVE_REAL="$(realpath -e "$ARCHIVE" 2>/dev/null)" \
    || onx_die 1 "Arşiv dosyası bulunamadı: $ARCHIVE"
[[ "$ARCHIVE_REAL" == /home/* ]] || onx_die 1 "Arşiv /home/ dışında: $ARCHIVE_REAL"
[[ -f "$ARCHIVE_REAL" ]]         || onx_die 1 "Arşiv bir dosya değil: $ARCHIVE_REAL"

# Destination may not exist yet — validate its future real path under /home/
DEST_PARENT="$(dirname "$DESTINATION")"
DEST_PARENT_REAL="$(realpath -m "$DEST_PARENT" 2>/dev/null || echo "$DEST_PARENT")"
[[ "$DEST_PARENT_REAL" == /home/* || "$DEST_PARENT_REAL" == /home" " ]] \
    || [[ "$DESTINATION" == /home/* ]] \
    || onx_die 1 "destination /home/ dışında: $DESTINATION"

mkdir -p "$DESTINATION" || onx_die 3 "destination oluşturulamadı: $DESTINATION"

# ─── Determine format and extract ─────────────────────────────────────────────
FILENAME="$(basename "$ARCHIVE_REAL")"
FILES_EXTRACTED=0

# ─── MED-14: symlink/hardlink/device girdilerini reddet ────────────────────────
# tar/unzip bu girdileri restore edip /home dışına link kurabilir; sonradan o link
# üzerinden okuma/yazma ev dizini dışına taşar (cross-account). Backup restore'ları
# normalde link içermez — içeriyorsa güvenlik için reddet. ($(...) || true: set -e + pipe.)
if [[ "$FILENAME" == *.zip ]]; then
    require_cmd unzip
    _UNSAFE="$(unzip -Z "$ARCHIVE_REAL" 2>/dev/null | awk 'substr($1,1,1)=="l"{print "1"; exit}' || true)"
else
    require_cmd tar
    _UNSAFE="$(tar -tvf "$ARCHIVE_REAL" 2>/dev/null | awk '{t=substr($1,1,1)} (t=="l"||t=="b"||t=="c"||t=="p"||t=="s"|| $0 ~ / -> / || $0 ~ / link to /){print "1"; exit}' || true)"
fi
if [[ "${_UNSAFE:-}" == "1" ]]; then
    onx_die 1 "Arşivde symlink/hardlink/device girdisi var — güvenlik için reddedildi (MED-14)"
fi

if [[ "$FILENAME" == *.zip ]]; then
    require_cmd unzip
    # Count files before extraction
    FILES_EXTRACTED="$(unzip -l "$ARCHIVE_REAL" | tail -1 | awk '{print $2}' 2>/dev/null || echo 0)"
    unzip -o "$ARCHIVE_REAL" -d "$DESTINATION" \
        || onx_die 3 "unzip başarısız: $ARCHIVE_REAL"
elif [[ "$FILENAME" == *.tar.gz || "$FILENAME" == *.tgz ]]; then
    require_cmd tar
    FILES_EXTRACTED="$(tar -tzf "$ARCHIVE_REAL" 2>/dev/null | wc -l || echo 0)"
    tar -xzf "$ARCHIVE_REAL" -C "$DESTINATION" \
        || onx_die 3 "tar extract başarısız: $ARCHIVE_REAL"
elif [[ "$FILENAME" == *.tar.bz2 ]]; then
    require_cmd tar
    FILES_EXTRACTED="$(tar -tjf "$ARCHIVE_REAL" 2>/dev/null | wc -l || echo 0)"
    tar -xjf "$ARCHIVE_REAL" -C "$DESTINATION" \
        || onx_die 3 "tar extract başarısız: $ARCHIVE_REAL"
elif [[ "$FILENAME" == *.tar ]]; then
    require_cmd tar
    FILES_EXTRACTED="$(tar -tf "$ARCHIVE_REAL" 2>/dev/null | wc -l || echo 0)"
    tar -xf "$ARCHIVE_REAL" -C "$DESTINATION" \
        || onx_die 3 "tar extract başarısız: $ARCHIVE_REAL"
else
    onx_die 1 "Tanınmayan arşiv formatı: $FILENAME (desteklenen: .zip .tar.gz .tgz .tar.bz2 .tar)"
fi

onx_log "archive-extract: archive=${ARCHIVE_REAL} destination=${DESTINATION} files=${FILES_EXTRACTED}"
onx_json_out files_extracted "$FILES_EXTRACTED" destination "$DESTINATION"
