#!/usr/bin/env bash
# parse-diagnostic-bundle.sh — summarise a Lumotia diagnostic bundle zip.
# Usage: ./scripts/parse-diagnostic-bundle.sh path/to/tester-bundle.zip
# Requires: unzip (required), jq (preferred; graceful grep fallback).
# Privacy: never prints transcript text, audio content, or .db content.
set -euo pipefail

BOLD='\033[1m'; GREEN='\033[0;32m'; RED='\033[0;31m'; YELLOW='\033[0;33m'; RESET='\033[0m'
pass()  { printf "${GREEN}  ✓${RESET} %s\n" "$*"; }
fail()  { printf "${RED}  ×${RESET} %s\n" "$*"; OVERALL_FAIL=1; }
warn()  { printf "${YELLOW}  !${RESET} %s\n" "$*"; }
info()  { printf "  %s\n" "$*"; }
header(){ printf "\n${BOLD}%s${RESET}\n" "$*"; }
OVERALL_FAIL=0

# Argument + file validation
[[ $# -lt 1 ]] && { echo "Usage: $0 path/to/tester-bundle.zip" >&2; exit 1; }
BUNDLE="$1"; BUNDLE_NAME="$(basename "$BUNDLE")"
[[ ! -f "$BUNDLE" ]] && { echo "ERROR: file not found: $BUNDLE" >&2; exit 2; }
if ! file "$BUNDLE" 2>/dev/null | grep -qi 'zip'; then
  (dd if="$BUNDLE" bs=2 count=2 2>/dev/null | grep -q 'PK') \
    || { echo "ERROR: $BUNDLE does not appear to be a zip archive." >&2; exit 2; }
fi

# jq check
HAS_JQ=0
command -v jq &>/dev/null && HAS_JQ=1 \
  || echo "WARNING: jq not found — falling back to grep-based extraction. Install jq for best results." >&2

# Extract
TMPDIR_WORK="$(mktemp -d)"; trap 'rm -rf "$TMPDIR_WORK"' EXIT
unzip -q "$BUNDLE" -d "$TMPDIR_WORK" 2>/dev/null \
  || { echo "ERROR: failed to extract $BUNDLE" >&2; exit 3; }

# Header
TITLE="LUMOTIA DIAGNOSTIC BUNDLE SUMMARY: $BUNDLE_NAME"
printf "\n${BOLD}%s${RESET}\n" "$TITLE"
printf '%0.s=' $(seq 1 ${#TITLE}); printf '\n'

# metadata.json → version + timestamps
META="$TMPDIR_WORK/metadata.json"; GEN_AT=""; VERSION=""
if [[ -f "$META" ]]; then
  if [[ $HAS_JQ -eq 1 ]]; then
    GEN_AT="$(jq -r '.generated_at // empty' "$META" 2>/dev/null)"
    VERSION="$(jq -r '.lumotia_version // empty' "$META" 2>/dev/null)"
  else
    GEN_AT="$(grep -o '"generated_at":[^,}]*' "$META" | grep -o '[0-9]*' | head -1)"
    VERSION="$(grep -o '"lumotia_version":"[^"]*"' "$META" | cut -d'"' -f4)"
  fi
fi
GEN_HUMAN=""
if [[ -n "$GEN_AT" && "$GEN_AT" =~ ^[0-9]+$ ]]; then
  GEN_HUMAN="$(date -u -d "@$GEN_AT" '+%Y-%m-%dT%H:%M:%SZ' 2>/dev/null \
               || date -u -r "$GEN_AT" '+%Y-%m-%dT%H:%M:%SZ' 2>/dev/null \
               || echo "$GEN_AT (epoch)")"
fi
info "Generated:        ${GEN_HUMAN:-unknown}"
info "Lumotia version:  ${VERSION:-unknown}"

# system_info.txt → platform
SYSINFO="$TMPDIR_WORK/system_info.txt"
if [[ -f "$SYSINFO" ]]; then
  OS_LINE="$(grep -i '^OS:' "$SYSINFO" | head -1 | sed 's/^OS: *//')"
  ARCH_LINE="$(grep -i '^Arch:' "$SYSINFO" | head -1 | sed 's/^Arch: *//')"
  info "Platform:         ${OS_LINE:-unknown} / ${ARCH_LINE:-unknown}"
fi

# Content inventory
header "CONTENT INVENTORY:"
check_path() {
  [[ -e "$TMPDIR_WORK/$2" ]] && pass "$1" || warn "$1  (not present)"
}
check_path "system_info.txt"           "system_info.txt"
check_path "preferences-redacted.json" "preferences-redacted.json"
check_path "metadata.json"             "metadata.json"

LOG_DIR="$TMPDIR_WORK/logs"; LOG_COUNT=0
if [[ -d "$LOG_DIR" ]]; then
  LOG_COUNT="$(find "$LOG_DIR" -type f | wc -l)"
  pass "logs/  ($LOG_COUNT files, $(du -sh "$LOG_DIR" 2>/dev/null | cut -f1))"
else warn "logs/  (directory not present)"; fi

CRASH_DIR="$TMPDIR_WORK/crashes"
if [[ -d "$CRASH_DIR" ]]; then
  CRASH_COUNT="$(find "$CRASH_DIR" -type f | wc -l)"
  [[ "$CRASH_COUNT" -eq 0 ]] \
    && pass "crashes/  (0 files)  — no crash dumps, good" \
    || warn "crashes/  ($CRASH_COUNT files)  — crash dumps present, review carefully"
else pass "crashes/  (directory absent)  — no crash dumps, good"; fi

# Redaction check — bundle MUST NEVER contain these
header "REDACTION CHECK (bundle MUST NEVER include these):"
DENY_CLEAN=1
check_absent() {
  local hits; hits="$(find "$TMPDIR_WORK" -type f | { grep -iE "$2" 2>/dev/null || true; })"
  [[ -z "$hits" ]] && pass "$1" \
    || { fail "$1  — FOUND: $(printf '%s' "$hits" | head -3 | tr '\n' ' ')"; DENY_CLEAN=0; }
}
check_absent "no .wav files"                  '\.wav$'
check_absent "no .mp3/.opus/.ogg/.flac files" '\.(mp3|opus|ogg|flac)$'
check_absent "no transcripts/ paths"          '/transcripts/'
check_absent "no captures/ paths"             '/captures/'
check_absent "no .db files"                   '\.(db|db-wal|db-shm)$'
check_absent "no .env files"                  '(^|/)\.env(\.|$)'
if [[ $DENY_CLEAN -eq 1 ]]; then
  printf "\n${GREEN}  PASS: bundle passed redaction check.${RESET}\n"
else
  printf "\n${RED}  FAIL: bundle contains DENIED content — do not share this bundle.${RESET}\n"
  OVERALL_FAIL=1
fi

# Log analysis
header "LOG ANALYSIS (last 7 days):"
if [[ -d "$LOG_DIR" && "$LOG_COUNT" -gt 0 ]]; then
  ALL_LOGS="$(find "$LOG_DIR" -type f -exec cat {} \;)"
  ERR_COUNT="$(printf '%s' "$ALL_LOGS" | { grep -iE '(ERROR|ERRO|\bERR\b)' 2>/dev/null || true; } | wc -l)"
  WARN_COUNT="$(printf '%s' "$ALL_LOGS" | { grep -iE '(WARN|WARNING)' 2>/dev/null || true; } | wc -l)"
  info "Errors:     $ERR_COUNT"
  info "Warnings:   $WARN_COUNT"
  if [[ "$ERR_COUNT" -gt 0 ]]; then
    info ""; info "TOP 3 ERROR PATTERNS:"
    printf '%s' "$ALL_LOGS" \
      | { grep -iE '(ERROR|ERRO|\bERR\b)' || true; } \
      | sed 's/^[0-9TZ:. -]*//' | sort | uniq -c | sort -rn | head -3 \
      | while IFS= read -r line; do info "  × $line"; done
  fi
else warn "No log files found."; fi

# Preferences (non-secret values)
PREFS="$TMPDIR_WORK/preferences-redacted.json"
header "PREFERENCES (redacted secrets):"
if [[ ! -f "$PREFS" ]]; then
  warn "preferences-redacted.json not found"
elif [[ $HAS_JQ -eq 1 ]]; then
  jq -r 'paths(scalars) as $p | getpath($p)
    | select(. != "[redacted]" and . != null and . != "")
    | "\($p | join(".")): \(.)"' "$PREFS" 2>/dev/null | head -30 \
    | while IFS= read -r line; do info "  $line"; done
  REDACTED_COUNT="$(jq '[.. | strings | select(. == "[redacted]")] | length' "$PREFS" 2>/dev/null || echo '?')"
  info "  ($REDACTED_COUNT field(s) redacted by bundler)"
else
  { grep -oE '"[^"]+": *("[^"]*"|[0-9.]+|true|false)' "$PREFS" || true; } \
    | grep -v '\[redacted\]' | head -30 | while IFS= read -r line; do info "  $line"; done
fi

# Verdict
header "VERDICT:"
if [[ $OVERALL_FAIL -eq 0 ]]; then
  printf "${GREEN}  PASS: bundle looks healthy. Safe to inspect for bug triage.${RESET}\n\n"
else
  printf "${RED}  FAIL: one or more checks failed — review items marked × above.${RESET}\n\n"
  exit 1
fi
