"""Тест вебхуков — парсинг и верификация подписи.

Этот тест работает локально без API, проверяет что webhook утилиты работают.

Запуск:
    python examples/test_webhook.py
"""
import hashlib
import hmac
import json

from runblob import (
    WebhookEvent,
    parse_webhook_payload,
    verify_webhook_signature,
)


class Colors:
    GREEN = "\033[92m"
    RED = "\033[91m"
    BOLD = "\033[1m"
    END = "\033[0m"


def ok(msg: str):
    print(f"  {Colors.GREEN}✓{Colors.END} {msg}")


def fail(msg: str):
    print(f"  {Colors.RED}✗{Colors.END} {msg}")


def main():
    print(f"\n{Colors.BOLD}══ Тест вебхуков ══{Colors.END}\n")

    passed = 0
    failed = 0

    # ── 1. Парсинг из dict ───────────────────────────────────────────
    print(f"  {Colors.BOLD}▸ Парсинг webhook payload (dict){Colors.END}")
    try:
        event = parse_webhook_payload({
            "task_uuid": "abc-123",
            "status": "completed",
            "prompt": "A sunset",
            "result_image_url": "https://storage.runblob.io/img.png",
            "message": None,
        })
        assert event.task_uuid == "abc-123"
        assert event.status == "completed"
        ok("Парсинг из dict работает")
        passed += 1
    except Exception as e:
        fail(f"{e}")
        failed += 1

    # ── 2. Парсинг из JSON string ─────────────────────────────────────
    print(f"\n  {Colors.BOLD}▸ Парсинг webhook payload (JSON string){Colors.END}")
    try:
        payload = json.dumps({
            "task_uuid": "def-456",
            "status": "failed",
            "prompt": "test",
            "result_image_url": None,
            "message": "MODERATION_FAILED",
        })
        event = parse_webhook_payload(payload)
        assert event.task_uuid == "def-456"
        assert event.status == "failed"
        ok("Парсинг из JSON string работает")
        passed += 1
    except Exception as e:
        fail(f"{e}")
        failed += 1

    # ── 3. Парсинг из bytes ───────────────────────────────────────────
    print(f"\n  {Colors.BOLD}▸ Парсинг webhook payload (bytes){Colors.END}")
    try:
        payload = json.dumps({"task_uuid": "ghi-789", "status": "completed", "prompt": "x", "result_image_url": "https://x.com/img.png", "message": None}).encode()
        event = parse_webhook_payload(payload)
        assert event.task_uuid == "ghi-789"
        ok("Парсинг из bytes работает")
        passed += 1
    except Exception as e:
        fail(f"{e}")
        failed += 1

    # ── 4. Верификация подписи ────────────────────────────────────────
    print(f"\n  {Colors.BOLD}▸ Верификация HMAC подписи (валидная){Colors.END}")
    try:
        secret = "whsec_test_secret_123"
        body = b'{"task_uuid":"abc","status":"completed"}'
        signature = hmac.new(secret.encode(), body, hashlib.sha256).hexdigest()

        assert verify_webhook_signature(body, signature, secret) is True
        ok("Валидная подпись проходит")
        passed += 1
    except Exception as e:
        fail(f"{e}")
        failed += 1

    # ── 5. Невалидная подпись ─────────────────────────────────────────
    print(f"\n  {Colors.BOLD}▸ Верификация HMAC подписи (невалидная){Colors.END}")
    try:
        assert verify_webhook_signature(body, "invalid_signature", secret) is False
        ok("Невалидная подпись отклоняется")
        passed += 1
    except Exception as e:
        fail(f"{e}")
        failed += 1

    # ── 6. Подменённое тело ───────────────────────────────────────────
    print(f"\n  {Colors.BOLD}▸ Верификация HMAC подписи (подмена тела){Colors.END}")
    try:
        tampered = b'{"task_uuid":"abc","status":"failed"}'
        assert verify_webhook_signature(tampered, signature, secret) is False
        ok("Подменённое тело отклоняется")
        passed += 1
    except Exception as e:
        fail(f"{e}")
        failed += 1

    # ── Итоги ─────────────────────────────────────────────────────────
    total = passed + failed
    print(f"\n  Всего: {total} | {Colors.GREEN}Прошло: {passed}{Colors.END}", end="")
    if failed:
        print(f" | {Colors.RED}Упало: {failed}{Colors.END}")
    else:
        print()
    print()


if __name__ == "__main__":
    main()
