#!/usr/bin/env bash
# ═════════════════════════════════════════════════════════
#  تست انتها-به-انتهای «بازوی قیمت‌ها»
# ═════════════════════════════════════════════════════════
#  اجرا:  bash tests/run-tests.sh
#  نیاز:  php (>= 7.4) + curl
#
# سه سرور محلی بالا می‌آیند:
#  • 8098: موک وب‌سرویس قیمت
#  • 8099: موک API بله (سخت‌گیر روی فرمت URL! تمام فراخوانی‌ها در tests/bale-calls.log)
#  • 8080: خود پروژه (وبهوک)

set -u

PHP="${PHP:-php}"
command -v "$PHP" >/dev/null || { echo "❌ php پیدا نشد"; exit 1; }
command -v curl >/dev/null || { echo "❌ curl پیدا نشد"; exit 1; }

DIR="$(cd "$(dirname "$0")/.." && pwd)"
TMP=/tmp/bale-test
PORT_PRICE=8098
PORT_BALE=8099
PORT_APP=8080
KEY="testkey123456789"

cd "$DIR" || exit 1

# ── پاک‌سازی ──
rm -rf "$TMP"; mkdir -p "$TMP"
rm -f tests/bale-calls.log

# ── سرورها ──
"$PHP" -S 127.0.0.1:$PORT_PRICE tests/price-mock.php >/dev/null 2>&1 &
P1=$!
"$PHP" -S 127.0.0.1:$PORT_BALE tests/mock-bale.php >/dev/null 2>&1 &
P2=$!
BALE_API_BASE="http://127.0.0.1:$PORT_BALE/bot" \
BALE_PRICE_API="http://127.0.0.1:$PORT_PRICE/prices" \
BALE_TOKEN="TESTTOKEN123456789ABCDEF" \
BALE_WEBHOOK_KEY="$KEY" \
BALE_DATA_DIR="$TMP" \
BALE_DB="$TMP/bot.sqlite" \
BALE_CACHE="$TMP/prices.cache.json" \
BALE_ADMINS="777" \
"$PHP" -S 127.0.0.1:$PORT_APP >"$TMP/app.log" 2>&1 &
P3=$!

cleanup() { kill $P1 $P2 $P3 2>/dev/null; }
trap cleanup EXIT

sleep 1

# ── سلامت سرورها ──
curl -sf "http://127.0.0.1:$PORT_PRICE/prices" >/dev/null || { echo "❌ موک قیمت بالا نیامد"; exit 1; }
curl -sf -X POST "http://127.0.0.1:$PORT_BALE/botTESTTOKEN123456789ABCDEF/getMe" >/dev/null || { echo "❌ موک بله بالا نیامد"; exit 1; }
code=$(curl -s -o /dev/null -w "%{http_code}" -X POST "http://127.0.0.1:$PORT_APP/webhook.php?key=WRONG")
[ "$code" = "403" ] && echo "  ✅ کلید اشتباه → 403 (سرور اپ سالم)" || { echo "  ❌ سرور اپ: کلید اشتباه → $code (باید 403 باشد)"; cat "$TMP/app.log"; FAIL=1; }

# ── تست موک سخت‌گیر: مسیر غلط باید 404 بدهد (مثل بلهٔ واقعی) ──
code=$(curl -s -o /dev/null -w "%{http_code}" -X POST "http://127.0.0.1:$PORT_BALE/bot/TESTTOKEN123456789ABCDEF/getMe")
[ "$code" = "404" ] && echo "  ✅ موک سخت‌گیر: مسیر bot/TOKEN → 404 (مثل بلهٔ واقعی)" || echo "  ❌ موک باید 404 بدهد، گرفت: $code"

# ── اجرای ۲۱ فیکسچر (به ترتیب update_id تا dedup مزاحم نشود) ──
echo "── اجرای آپدیت‌ها ──────────────────────────"
PASS=0; FAIL=0
ORDERED=$(for f in tests/update_*.json; do
    uid=$("$PHP" -r '$j=json_decode(file_get_contents($argv[1]),true); echo $j["update_id"] ?? 0;' "$f" 2>/dev/null)
    echo "$uid $f"
done | sort -n | awk '{print $2}')
for f in $ORDERED; do
    code=$(curl -s -o /dev/null -w "%{http_code}" -X POST --data-binary @"$f" \
        "http://127.0.0.1:$PORT_APP/webhook.php?key=$KEY")
    if [ "$code" = "200" ]; then
        PASS=$((PASS+1))
        echo "  ✅ $f"
    else
        FAIL=$((FAIL+1))
        echo "  ❌ $f → HTTP $code"
    fi
done
echo "  ($PASS پاس، $FAIL خطا)"

# ── کلید اشتباه باید ۴۰۳ بدهد ──
code=$(curl -s -o /dev/null -w "%{http_code}" -X POST --data-binary '{"update_id":1}' \
    "http://127.0.0.1:$PORT_APP/webhook.php?key=WRONG")
[ "$code" = "403" ] && echo "  ✅ کلید اشتباه → 403" || echo "  ❌ کلید اشتباه → $code"

# ── خطای PHP در سرور اپ؟ ──
if [ -s "$TMP/app.log" ] && grep -qiE 'error|warning|fatal|deprecated' "$TMP/app.log" 2>/dev/null; then
    echo "  ⚠️ خطا/هشدار PHP در سرور اپ:"
    grep -iE 'error|warning|fatal|deprecated' "$TMP/app.log" | sort -u | head -8
    FAIL=$((FAIL+1))
fi
if [ -s "$TMP/bot.log" ]; then
    # «webhook hit» و «webhook forbidden» (نتیجهٔ تستِ خودِ کلید اشتباه) طبیعی‌اند
    BOTERR=$(grep -cvE 'webhook hit|webhook forbidden' "$TMP/bot.log" || true)
    if [ "${BOTERR:-0}" -gt 0 ]; then
        echo "  ⚠️ لاگ بات ($BOTERR خط غیرعادی):"
        grep -vE 'webhook hit|webhook forbidden' "$TMP/bot.log" | head -5
        FAIL=$((FAIL+1))
    fi
fi

# ── بررسی لاگ فراخوانی‌های بله ──
echo "── بررسی رفتار بات ─────────────────────────"
LOG=tests/bale-calls.log
check() {  # $1=الگو $2=توضیح
    if grep -qF "$1" "$LOG" 2>/dev/null; then
        echo "  ✅ $2"
    else
        echo "  ❌ $2"
        FAIL=$((FAIL+1))
    fi
}

check '"method":"sendMessage"'      'sendMessage فراخوانی شد'
check '"method":"answerCallbackQuery"' 'answerCallbackQuery فراخوانی شد'
check '"method":"editMessageText"'  'editMessageText (بروزرسانی آمار) فراخوانی شد'
check 'قیمت چی میخوای'              'متن منوی اصلی از bot.php'
check '🟡 قیمت طلا 🟡'               'هدر /Special — طلا'
check '🟠 قیمت سکه 🟠'               'هدر /Special — سکه (املا درست: سکه)'
check 'طلای ۱۸ عیار'                'دکمهٔ طلای ۱۸'
check 'امامی'                        'زیرمجموعهٔ سکه در /Special'
check 'یورو'                         'زیرمجموعهٔ ارز در /Special'
check 'بروزرسانی داده'              'پانویس تاریخ'
check 'reply_to_message_id'         'پاسخ (reply) در گروه'
check '"show_alert":true'           'اعلان هشداری برای دکمه‌های /Special'
check '/Special — منوی قیمت'        'راهنمای گروه زیر قیمت'
check '"keyboard":'                 'کیبورد پاسخ (ReplyKeyboard) ارسال شد'
check 'دستورهای من در این گروه'      'پیام دستورهای گروه (بدون منوی خصوصی)'

# ── بررسی رفتاری دقیق (تحلیل JSON لاگ موک) ──
if "$PHP" tests/check-behavior.php "$LOG"; then
    :
else
    FAIL=$((FAIL+1))
fi

# ── تست مسیر خطا: قطع وب‌سرویس قیمت → پیام خطا از bot.php ──
echo "── تست مسیر خطا (قطع سرویس قیمت) ──────────"
kill $P1 2>/dev/null
rm -f "$TMP/prices.cache.json"
printf '%s' '{"update_id":99999,"message":{"message_id":99,"from":{"id":555,"is_bot":false,"first_name":"تست"},"chat":{"id":555,"type":"private"},"text":"طلا"}}' > "$TMP/err-update.json"
code=$(curl -s -o /dev/null -w "%{http_code}" -X POST --data-binary @"$TMP/err-update.json" \
    "http://127.0.0.1:$PORT_APP/webhook.php?key=$KEY")
[ "$code" = "200" ] && echo "  ✅ وبهوک در قطعی هم ۲۰۰ می‌دهد" || { echo "  ❌ قطعی → HTTP $code"; FAIL=$((FAIL+1)); }
check '⚠️ سرویس قیمت'               'متن خطا از bot.php'

# شمارش‌ها
SM=$(grep -c '"method":"sendMessage"' "$LOG" 2>/dev/null) || SM=0
AC=$(grep -c '"method":"answerCallbackQuery"' "$LOG" 2>/dev/null) || AC=0
EM=$(grep -c '"method":"editMessageText"' "$LOG" 2>/dev/null) || EM=0
echo "  📊 sendMessage=$SM  answerCallbackQuery=$AC  editMessageText=$EM"
[ "${SM:-0}" -ge 10 ] || { echo "  ❌ تعداد sendMessage خیلی کم است"; FAIL=$((FAIL+1)); }

echo "──────────────────────────────────────────"
echo "RESULT: $([ $FAIL -eq 0 ] && echo 'ALL PASS ✅' || echo "$FAIL FAILED ❌")"
exit $([ $FAIL -eq 0 ] && echo 0 || echo 1)
