#!/usr/bin/env python3
"""
Webhook 功能测试脚本
用于验证 Gitea Webhook Ambassador 的各项功能
"""

import asyncio
import json
import httpx
import time
from datetime import datetime

# 测试配置
BASE_URL = "http://localhost:8000"
WEBHOOK_SECRET = "your-secret-key-here-make-it-long-and-random"

# 测试数据
TEST_WEBHOOK_DATA = {
    "ref": "refs/heads/dev",
    "before": "abc1234567890abcdef1234567890abcdef123456",
    "after": "def1234567890abcdef1234567890abcdef123456",
    "compare_url": "https://gitea.freeleaps.com/freeleaps/test-project/compare/abc123...def123",
    "commits": [
        {
            "id": "def1234567890abcdef1234567890abcdef123456",
            "message": "feat: add new feature",
            "url": "https://gitea.freeleaps.com/freeleaps/test-project/commit/def1234567890abcdef1234567890abcdef123456",
            "author": {
                "id": 1,
                "login": "developer",
                "full_name": "Test Developer",
                "email": "dev@freeleaps.com"
            }
        }
    ],
    "repository": {
        "id": 1,
        "name": "test-project",
        "owner": {
            "id": 1,
            "login": "freeleaps",
            "full_name": "Freeleaps Team",
            "email": "team@freeleaps.com"
        },
        "full_name": "freeleaps/test-project",
        "private": False,
        "clone_url": "https://gitea.freeleaps.com/freeleaps/test-project.git",
        "ssh_url": "git@gitea.freeleaps.com:freeleaps/test-project.git",
        "html_url": "https://gitea.freeleaps.com/freeleaps/test-project",
        "default_branch": "main"
    },
    "pusher": {
        "id": 1,
        "login": "developer",
        "full_name": "Test Developer",
        "email": "dev@freeleaps.com"
    }
}


async def test_health_check():
    """测试健康检查"""
    print("🔍 测试健康检查...")
    
    async with httpx.AsyncClient() as client:
        try:
            response = await client.get(f"{BASE_URL}/health")
            if response.status_code == 200:
                data = response.json()
                print(f"✅ 健康检查通过: {data['status']}")
                return True
            else:
                print(f"❌ 健康检查失败: {response.status_code}")
                return False
        except Exception as e:
            print(f"❌ 健康检查异常: {e}")
            return False


async def test_queue_status():
    """测试队列状态"""
    print("🔍 测试队列状态...")
    
    async with httpx.AsyncClient() as client:
        try:
            response = await client.get(f"{BASE_URL}/health/queue")
            if response.status_code == 200:
                data = response.json()
                print(f"✅ 队列状态: {data['queue_stats']}")
                return True
            else:
                print(f"❌ 队列状态检查失败: {response.status_code}")
                return False
        except Exception as e:
            print(f"❌ 队列状态检查异常: {e}")
            return False


async def test_webhook_endpoint():
    """测试 Webhook 端点"""
    print("🔍 测试 Webhook 端点...")
    
    headers = {
        "Content-Type": "application/json",
        "X-Gitea-Signature": WEBHOOK_SECRET
    }
    
    async with httpx.AsyncClient() as client:
        try:
            response = await client.post(
                f"{BASE_URL}/webhook/gitea",
                headers=headers,
                json=TEST_WEBHOOK_DATA
            )
            
            print(f"📊 响应状态: {response.status_code}")
            print(f"📊 响应内容: {response.text}")
            
            if response.status_code in [200, 202]:
                print("✅ Webhook 端点测试通过")
                return True
            else:
                print(f"❌ Webhook 端点测试失败: {response.status_code}")
                return False
                
        except Exception as e:
            print(f"❌ Webhook 端点测试异常: {e}")
            return False


async def test_metrics_endpoint():
    """测试监控指标端点"""
    print("🔍 测试监控指标端点...")
    
    async with httpx.AsyncClient() as client:
        try:
            response = await client.get(f"{BASE_URL}/metrics")
            if response.status_code == 200:
                print("✅ 监控指标端点测试通过")
                # 打印一些关键指标
                content = response.text
                for line in content.split('\n'):
                    if 'webhook_requests_total' in line or 'queue_size' in line:
                        print(f"📊 {line}")
                return True
            else:
                print(f"❌ 监控指标端点测试失败: {response.status_code}")
                return False
        except Exception as e:
            print(f"❌ 监控指标端点测试异常: {e}")
            return False


async def test_deduplication():
    """测试防抖功能"""
    print("🔍 测试防抖功能...")
    
    headers = {
        "Content-Type": "application/json",
        "X-Gitea-Signature": WEBHOOK_SECRET
    }
    
    async with httpx.AsyncClient() as client:
        try:
            # 第一次请求
            print("📤 发送第一次请求...")
            response1 = await client.post(
                f"{BASE_URL}/webhook/gitea",
                headers=headers,
                json=TEST_WEBHOOK_DATA
            )
            print(f"📊 第一次响应: {response1.status_code}")
            
            # 等待一秒
            await asyncio.sleep(1)
            
            # 第二次请求（相同数据，应该被防抖）
            print("📤 发送第二次请求（相同数据）...")
            response2 = await client.post(
                f"{BASE_URL}/webhook/gitea",
                headers=headers,
                json=TEST_WEBHOOK_DATA
            )
            print(f"📊 第二次响应: {response2.status_code}")
            
            # 修改提交哈希，发送第三次请求
            modified_data = TEST_WEBHOOK_DATA.copy()
            modified_data["after"] = "ghi1234567890abcdef1234567890abcdef123456"
            
            print("📤 发送第三次请求（不同提交哈希）...")
            response3 = await client.post(
                f"{BASE_URL}/webhook/gitea",
                headers=headers,
                json=modified_data
            )
            print(f"📊 第三次响应: {response3.status_code}")
            
            print("✅ 防抖功能测试完成")
            return True
            
        except Exception as e:
            print(f"❌ 防抖功能测试异常: {e}")
            return False


async def test_invalid_webhook():
    """测试无效的 Webhook 请求"""
    print("🔍 测试无效的 Webhook 请求...")
    
    async with httpx.AsyncClient() as client:
        try:
            # 测试缺少签名
            print("📤 测试缺少签名...")
            response1 = await client.post(
                f"{BASE_URL}/webhook/gitea",
                headers={"Content-Type": "application/json"},
                json=TEST_WEBHOOK_DATA
            )
            print(f"📊 缺少签名响应: {response1.status_code}")
            
            # 测试错误的签名
            print("📤 测试错误的签名...")
            response2 = await client.post(
                f"{BASE_URL}/webhook/gitea",
                headers={
                    "Content-Type": "application/json",
                    "X-Gitea-Signature": "wrong-secret"
                },
                json=TEST_WEBHOOK_DATA
            )
            print(f"📊 错误签名响应: {response2.status_code}")
            
            # 测试无效的 JSON
            print("📤 测试无效的 JSON...")
            response3 = await client.post(
                f"{BASE_URL}/webhook/gitea",
                headers={
                    "Content-Type": "application/json",
                    "X-Gitea-Signature": WEBHOOK_SECRET
                },
                content="invalid json"
            )
            print(f"📊 无效 JSON 响应: {response3.status_code}")
            
            print("✅ 无效请求测试完成")
            return True
            
        except Exception as e:
            print(f"❌ 无效请求测试异常: {e}")
            return False


async def main():
    """主测试函数"""
    print("🚀 开始 Gitea Webhook Ambassador 功能测试")
    print("=" * 50)
    
    tests = [
        ("健康检查", test_health_check),
        ("队列状态", test_queue_status),
        ("Webhook 端点", test_webhook_endpoint),
        ("监控指标", test_metrics_endpoint),
        ("防抖功能", test_deduplication),
        ("无效请求", test_invalid_webhook),
    ]
    
    results = []
    
    for test_name, test_func in tests:
        print(f"\n🧪 {test_name}")
        print("-" * 30)
        
        try:
            result = await test_func()
            results.append((test_name, result))
        except Exception as e:
            print(f"❌ {test_name} 测试异常: {e}")
            results.append((test_name, False))
        
        # 等待一下再进行下一个测试
        await asyncio.sleep(1)
    
    # 输出测试结果
    print("\n" + "=" * 50)
    print("📊 测试结果汇总")
    print("=" * 50)
    
    passed = 0
    total = len(results)
    
    for test_name, result in results:
        status = "✅ 通过" if result else "❌ 失败"
        print(f"{test_name}: {status}")
        if result:
            passed += 1
    
    print(f"\n📈 总体结果: {passed}/{total} 测试通过")
    
    if passed == total:
        print("🎉 所有测试通过！服务运行正常。")
    else:
        print("⚠️ 部分测试失败，请检查服务配置和日志。")


if __name__ == "__main__":
    # 运行测试
    asyncio.run(main()) 