#!/usr/bin/env bash
# test_pre_compact_diary.sh — PreCompact diary 훅 테스트
# 실행: bash /home/jay/workspace/hooks/tests/test_pre_compact_diary.sh

set +e

HOOK_SCRIPT="/home/jay/workspace/hooks/pre-compact-diary.sh"
TEST_DIARY_DIR="/tmp/test-diary-$$"
PATCHED_SCRIPT="/tmp/test-hook-$$-pre-compact-diary.sh"
PASS_COUNT=0
FAIL_COUNT=0
TOTAL=5
TODAY=$(date +"%Y-%m-%d")

# --------------------------------------------------------------------------
# 헬퍼 함수
# --------------------------------------------------------------------------

pass() {
  local name="$1"
  echo "[PASS] ${name}"
  PASS_COUNT=$((PASS_COUNT + 1))
}

fail() {
  local name="$1"
  local reason="${2:-}"
  echo "[FAIL] ${name}${reason:+ — ${reason}}"
  FAIL_COUNT=$((FAIL_COUNT + 1))
}

# --------------------------------------------------------------------------
# setup / teardown
# --------------------------------------------------------------------------

setup() {
  # 임시 diary 디렉토리 생성
  mkdir -p "$TEST_DIARY_DIR"

  # 스크립트 복사본 생성 후 DIARY_DIR 경로를 임시 경로로 교체
  sed "s|DIARY_DIR=\"/home/jay/.claude/memory/diary\"|DIARY_DIR=\"${TEST_DIARY_DIR}\"|g" \
    "$HOOK_SCRIPT" > "$PATCHED_SCRIPT"
  chmod +x "$PATCHED_SCRIPT"
}

teardown() {
  rm -rf "$TEST_DIARY_DIR"
  rm -f "$PATCHED_SCRIPT"
}

# --------------------------------------------------------------------------
# TC1: Compact 입력 시 diary 파일 생성
# --------------------------------------------------------------------------

tc1_compact_creates_diary_file() {
  local name="TC1: Compact 입력 시 diary 파일 생성"

  # 임시 디렉토리 초기화 (다른 TC 영향 격리)
  rm -f "${TEST_DIARY_DIR}"/${TODAY}-session-*.md

  echo '{"tool_name": "Compact"}' | bash "$PATCHED_SCRIPT"

  # 오늘 날짜 파일이 1개 이상 존재하는지 확인
  local file
  file=$(ls -1 "${TEST_DIARY_DIR}"/${TODAY}-session-*.md 2>/dev/null | head -1)

  if [[ -n "$file" && -s "$file" ]]; then
    pass "$name"
  else
    fail "$name" "diary 파일이 생성되지 않았거나 크기가 0"
  fi
}

# --------------------------------------------------------------------------
# TC2: 비-Compact 도구는 무시
# --------------------------------------------------------------------------

tc2_non_compact_no_file() {
  local name="TC2: 비-Compact 도구는 무시"

  rm -f "${TEST_DIARY_DIR}"/${TODAY}-session-*.md

  echo '{"tool_name": "Read"}' | bash "$PATCHED_SCRIPT"

  local count
  count=$(ls -1 "${TEST_DIARY_DIR}"/${TODAY}-session-*.md 2>/dev/null | wc -l)

  if [[ "$count" -eq 0 ]]; then
    pass "$name"
  else
    fail "$name" "diary 파일이 생성됨 (${count}개)"
  fi
}

# --------------------------------------------------------------------------
# TC3: 세션 번호 자동 증가
# --------------------------------------------------------------------------

tc3_session_number_increments() {
  local name="TC3: 세션 번호 자동 증가"

  rm -f "${TEST_DIARY_DIR}"/${TODAY}-session-*.md

  # 첫 번째 실행
  echo '{"tool_name": "Compact"}' | bash "$PATCHED_SCRIPT"
  # 두 번째 실행
  echo '{"tool_name": "Compact"}' | bash "$PATCHED_SCRIPT"

  local file1="${TEST_DIARY_DIR}/${TODAY}-session-01.md"
  local file2="${TEST_DIARY_DIR}/${TODAY}-session-02.md"

  if [[ -f "$file1" && -f "$file2" ]]; then
    pass "$name"
  else
    local missing=""
    [[ ! -f "$file1" ]] && missing="${missing} session-01.md"
    [[ ! -f "$file2" ]] && missing="${missing} session-02.md"
    fail "$name" "누락된 파일:${missing}"
  fi
}

# --------------------------------------------------------------------------
# TC4: frontmatter 구조 검증
# --------------------------------------------------------------------------

tc4_frontmatter_fields() {
  local name="TC4: frontmatter 구조 검증"

  rm -f "${TEST_DIARY_DIR}"/${TODAY}-session-*.md

  echo '{"tool_name": "Compact"}' | bash "$PATCHED_SCRIPT"

  local file
  file=$(ls -1 "${TEST_DIARY_DIR}"/${TODAY}-session-*.md 2>/dev/null | head -1)

  if [[ -z "$file" ]]; then
    fail "$name" "diary 파일이 생성되지 않아 frontmatter 검증 불가"
    return
  fi

  local missing_fields=()
  local required_fields=("date:" "session:" "team_id:" "task_id:" "tags:" "auto_generated:")

  for field in "${required_fields[@]}"; do
    if ! grep -q "^${field}" "$file"; then
      missing_fields+=("$field")
    fi
  done

  if [[ ${#missing_fields[@]} -eq 0 ]]; then
    pass "$name"
  else
    fail "$name" "누락된 필드: ${missing_fields[*]}"
  fi
}

# --------------------------------------------------------------------------
# TC5: 에러 시 exit 0 보장
# --------------------------------------------------------------------------

tc5_error_exits_zero() {
  local name="TC5: 에러 시 exit 0 보장"

  local exit_code

  # TC5-A: 빈 stdin
  echo "" | bash "$PATCHED_SCRIPT"
  exit_code=$?
  if [[ $exit_code -ne 0 ]]; then
    fail "$name" "빈 stdin 시 exit code ${exit_code} (0이어야 함)"
    return
  fi

  # TC5-B: 잘못된 JSON
  echo "not-valid-json-{{{" | bash "$PATCHED_SCRIPT"
  exit_code=$?
  if [[ $exit_code -ne 0 ]]; then
    fail "$name" "잘못된 JSON 시 exit code ${exit_code} (0이어야 함)"
    return
  fi

  pass "$name"
}

# --------------------------------------------------------------------------
# 메인 실행
# --------------------------------------------------------------------------

main() {
  # 훅 스크립트 존재 여부 확인
  if [[ ! -f "$HOOK_SCRIPT" ]]; then
    echo "[ERROR] 훅 스크립트 없음: ${HOOK_SCRIPT}"
    exit 1
  fi

  setup

  echo "============================="
  echo "pre-compact-diary.sh 테스트"
  echo "============================="

  tc1_compact_creates_diary_file
  tc2_non_compact_no_file
  tc3_session_number_increments
  tc4_frontmatter_fields
  tc5_error_exits_zero

  teardown

  echo "============================="
  echo "결과: ${PASS_COUNT}/${TOTAL} PASS, ${FAIL_COUNT}/${TOTAL} FAIL"
  echo "============================="

  # 하나라도 실패하면 비정상 종료
  [[ $FAIL_COUNT -eq 0 ]]
}

main
