#  @line_count 200
"""测试规范选择器，实现规则+AI混合选择策略"""
from typing import List, Dict, Any, Optional, TYPE_CHECKING
from .test_standard_loader import TestStandardLoader
import json
import re

if TYPE_CHECKING:
    from .api_client import APIClient


class StandardSelector:
    """测试规范选择器，实现规则+AI混合选择策略"""
    
    def __init__(self, loader: TestStandardLoader, api_client: Optional['APIClient'] = None):
        """
        初始化规范选择器
        
        Args:
            loader: 测试规范加载器
            api_client: API客户端，用于AI辅助选择
        """
        self.loader = loader
        self.api_client = api_client
        self.mapping_rules = loader.get_requirement_mapping()
        self.keyword_mapping = loader.get_keyword_mapping()
    
    def select_standards(self, requirement: Dict[str, Any], use_ai: bool = True) -> List[str]:
        """
        为需求选择适用的测试规范
        
        Args:
            requirement: 需求字典，包含requirement_type、description等
            use_ai: 是否使用AI辅助选择（当规则匹配不足时）
            
        Returns:
            测试规范ID列表
        """
        # 第一步：规则匹配
        rule_based = self._rule_based_selection(requirement)
        
        # 第二步：如果规则匹配不足，使用AI补充
        if use_ai and len(rule_based) < 2 and self.api_client:
            ai_based = self._ai_based_selection(requirement)
            # 合并去重
            all_standards = list(set(rule_based + ai_based))
            return all_standards
        
        return rule_based
    
    def _rule_based_selection(self, requirement: Dict[str, Any]) -> List[str]:
        """
        基于规则的规范选择
        
        Args:
            requirement: 需求字典
            
        Returns:
            测试规范ID列表
        """
        standards = []
        req_type = requirement.get('requirement_type', '')
        req_desc = requirement.get('description', '')
        
        # 1. 需求类型映射
        if req_type in self.mapping_rules:
            mapping = self.mapping_rules[req_type]
            # 主要测试类型
            standards.extend(mapping.get('primary', []))
            # 次要测试类型
            standards.extend(mapping.get('secondary', []))
            # 条件性测试类型
            conditionals = mapping.get('conditional', {})
            if '有界面' in conditionals and ('界面' in req_desc or '显示' in req_desc):
                standards.extend(conditionals['有界面'])
            if '有性能要求' in conditionals and ('性能' in req_desc or '速度' in req_desc or '时间' in req_desc):
                standards.extend(conditionals['有性能要求'])
            if '安全关键' in conditionals and ('安全' in req_desc or '危险' in req_desc or '报警' in req_desc):
                standards.extend(conditionals['安全关键'])
            if '多软件交互' in conditionals and ('交互' in req_desc or '协同' in req_desc):
                standards.extend(conditionals['多软件交互'])
            if '性能相关' in conditionals and ('性能' in req_desc):
                standards.extend(conditionals['性能相关'])
            if '安全相关' in conditionals and ('安全' in req_desc):
                standards.extend(conditionals['安全相关'])
        
        # 2. 关键词匹配
        for keyword, test_types in self.keyword_mapping.items():
            if keyword in req_desc:
                standards.extend(test_types)
        
        # 3. 接口信息检测
        if requirement.get('interface_info'):
            standards.append('外部接口测试')
        
        # 去重并返回
        return list(set(standards))
    
    def _ai_based_selection(self, requirement: Dict[str, Any]) -> List[str]:
        """
        基于AI的规范选择（当规则匹配不足时使用）
        
        Args:
            requirement: 需求字典
            
        Returns:
            测试规范ID列表
        """
        if not self.api_client:
            return []
        
        # 获取所有测试规范名称
        all_standards = self.loader.get_all_standards()
        standard_names = [f"{i+1}. {std.get('name', '')}" for i, std in enumerate(all_standards)]
        
        prompt = f"""根据以下需求，从14个测试类型中选择最适用的3-5个：

{chr(10).join(standard_names)}

需求类型：{requirement.get('requirement_type', '未知')}
需求描述：{requirement.get('description', '')}

请只返回测试类型的名称列表，格式为JSON数组，例如：["功能测试", "性能测试", "边界测试"]
不要包含其他说明文字。"""
        
        try:
            response = self.api_client.call_api(prompt)
            # 尝试解析JSON
            test_types = self._parse_ai_response(response)
            return test_types
        except Exception as e:
            # 如果AI选择失败，返回空列表
            print(f"AI选择失败: {str(e)}")
            return []
    
    def _parse_ai_response(self, response: str) -> List[str]:
        """
        解析AI响应，提取测试类型列表
        
        Args:
            response: AI响应文本
            
        Returns:
            测试类型名称列表
        """
        # 尝试直接解析JSON
        try:
            # 尝试提取JSON数组
            json_match = re.search(r'\[.*?\]', response, re.DOTALL)
            if json_match:
                json_str = json_match.group(0)
                test_types = json.loads(json_str)
                if isinstance(test_types, list):
                    return test_types
        except:
            pass
        
        # 如果JSON解析失败，尝试文本匹配
        all_standards = self.loader.get_all_standards()
        standard_names = [std.get('name', '') for std in all_standards]
        
        found_types = []
        for name in standard_names:
            if name in response:
                found_types.append(name)
        
        return found_types
