# -*- coding: utf-8 -*-
"""流式响应测试脚本"""

import requests
import json
import time
from datetime import datetime
import argparse
import logging.config
from test_config import API_BASE_URL, AUTH_TOKEN, TEST_CASES, LOG_CONFIG, HEADERS

# 配置日志
logging.config.dictConfig(LOG_CONFIG)
logger = logging.getLogger('stream_test')

class StreamResponseTester:
    def __init__(self, base_url, headers):
        self.base_url = base_url
        self.headers = headers
        
    def run_test(self, test_case):
        """运行单个测试用例"""
        logger.info(f"\n开始测试: {test_case['name']}")
        
        # 构建请求数据
        test_data = {
            "question": test_case["question"],
            "conversation_id": test_case["conversation_id"],
            "dataset_id_list": [test_case["dataset_id"]],
            "stream": True
        }
        
        start_time = time.time()
        response_count = 0
        content_length = 0
        full_content = ""
        
        try:
            # 发送请求
            url = f"{self.base_url}/api/chat-history/"
            logger.info(f"请求URL: {url}")
            logger.info(f"请求数据: {json.dumps(test_data, ensure_ascii=False)}")
            
            response = requests.post(
                url=url,
                json=test_data,
                headers=self.headers,
                stream=True
            )
            
            # 检查响应状态
            if response.status_code != 200:
                if test_case.get('expected_error', False):
                    logger.info("测试通过：预期的错误响应")
                    return True
                logger.error(f"请求失败: {response.status_code}, {response.text}")
                return False
            
            # 处理流式响应
            buffer = ""
            last_time = start_time
            
            for chunk in response.iter_content(chunk_size=1):
                if chunk:
                    current_time = time.time()
                    chunk_time = current_time - last_time
                    
                    try:
                        chunk_str = chunk.decode('utf-8')
                        buffer += chunk_str
                        
                        if '\n\n' in buffer:
                            lines = buffer.split('\n\n')
                            for line in lines[:-1]:
                                if line.startswith('data: '):
                                    response_count += 1
                                    
                                    try:
                                        data = json.loads(line[6:])
                                        if 'data' in data and 'content' in data['data']:
                                            content = data['data']['content']
                                            prev_length = content_length
                                            content_length += len(content)
                                            full_content += content
                                            
                                            # 记录响应信息
                                            logger.debug(
                                                f"响应 #{response_count}: "
                                                f"+{content_length - prev_length} 字符, "
                                                f"间隔: {chunk_time:.3f}s"
                                            )
                                            
                                            # 检查是否结束
                                            if data['data'].get('is_end', False):
                                                total_time = time.time() - start_time
                                                logger.info(f"\n测试结果:")
                                                logger.info(f"总响应时间: {total_time:.3f}秒")
                                                logger.info(f"数据包数量: {response_count}")
                                                logger.info(f"内容长度: {content_length} 字符")
                                                logger.info(f"完整内容: {full_content}")
                                                
                                                # 检查响应时间是否符合预期
                                                if 'expected_response_time' in test_case:
                                                    if total_time <= test_case['expected_response_time']:
                                                        logger.info("响应时间符合预期")
                                                    else:
                                                        logger.warning(
                                                            f"响应时间超出预期: "
                                                            f"{total_time:.3f}s > {test_case['expected_response_time']}s"
                                                        )
                                                
                                                return True
                                            
                                    except json.JSONDecodeError as e:
                                        logger.error(f"JSON解析错误: {e}")
                                        if not test_case.get('expected_error', False):
                                            return False
                            
                            buffer = lines[-1]
                            last_time = current_time
                            
                    except UnicodeDecodeError:
                        logger.debug("解码错误，跳过")
                        continue
            
            return True
            
        except Exception as e:
            logger.error(f"测试执行错误: {str(e)}")
            return False

def main():
    parser = argparse.ArgumentParser(description='流式响应测试工具')
    parser.add_argument('--test-case', type=int, help='指定要运行的测试用例索引')
    args = parser.parse_args()
    
    # 创建测试器实例
    tester = StreamResponseTester(API_BASE_URL, HEADERS)
    
    if args.test_case is not None:
        # 运行指定的测试用例
        if 0 <= args.test_case < len(TEST_CASES):
            test_case = TEST_CASES[args.test_case]
            success = tester.run_test(test_case)
            logger.info(f"\n测试用例 {args.test_case} {'通过' if success else '失败'}")
        else:
            logger.error(f"无效的测试用例索引: {args.test_case}")
    else:
        # 运行所有测试用例
        total_cases = len(TEST_CASES)
        passed_cases = 0
        
        for i, test_case in enumerate(TEST_CASES):
            logger.info(f"\n运行测试用例 {i+1}/{total_cases}")
            if tester.run_test(test_case):
                passed_cases += 1
                
        logger.info(f"\n测试完成: {passed_cases}/{total_cases} 个测试用例通过")

if __name__ == '__main__':
    main()
