"""测试用例收集器"""

from typing import List, Dict, Any, Optional
from pathlib import Path

from .read.excel_reader import ExcelReader, TestCase, TestStep
from ..reference import INFO


class CaseCollector:
    """测试用例收集器

    从配置和 Excel 文件收集测试用例。
    """

    def __init__(self, config: Dict[str, Any] = None):
        """初始化用例收集器

        Args:
            config: 配置字典
        """
        self._config = config or {}
        self._cases: List[TestCase] = []
        self._case_files: List[Dict[str, Any]] = []

    def add_case_file(
        self,
        file_path: str,
        sheets: List[str] = None,
        interface_switch: bool = False
    ) -> None:
        """添加测试用例文件

        Args:
            file_path: Excel 文件路径
            sheets: 要执行的 Sheet 列表，None 表示全部
            interface_switch: 是否接口测试
        """
        self._case_files.append({
            'path': file_path,
            'sheets': sheets,
            'interface': interface_switch
        })

    def collect(self) -> List[TestCase]:
        """收集所有测试用例

        Returns:
            List[TestCase]: 测试用例列表
        """
        self._cases.clear()

        # 从配置收集
        if 'testCaseFile' in self._config:
            for file_config in self._config['testCaseFile']:
                self.add_case_file(
                    file_path=file_config.get('caseFilePath', ''),
                    sheets=file_config.get('caseItem'),
                    interface_switch=file_config.get('interfaceSwitch', False)
                )

        # 收集用例
        for file_info in self._case_files:
            self._collect_from_file(file_info)

        INFO(f"共收集 {len(self._cases)} 个测试用例")
        return self._cases

    def _collect_from_file(self, file_info: Dict[str, Any]) -> None:
        """从文件收集用例

        Args:
            file_info: 文件信息
        """
        file_path = file_info['path']
        sheets = file_info['sheets']

        if not Path(file_path).exists():
            INFO(f"用例文件不存在: {file_path}", "WARNING")
            return

        try:
            with ExcelReader(file_path) as reader:
                if sheets:
                    # 只读取指定 Sheet
                    all_cases = reader.read_all_sheets(sheets)
                else:
                    # 读取所有 Sheet
                    all_cases = reader.read_all_sheets()

                for sheet_name, cases in all_cases.items():
                    for case_data in cases:
                        case_data['file'] = file_path
                        case_data['interface'] = file_info['interface']
                        self._cases.append(TestCase(case_data))

        except Exception as e:
            INFO(f"读取用例文件失败: {file_path} - {e}", "ERROR")

    @property
    def cases(self) -> List[TestCase]:
        """获取所有测试用例"""
        return self._cases.copy()

    @property
    def case_count(self) -> int:
        """获取用例数量"""
        return len(self._cases)

    def get_cases_by_sheet(self, sheet_name: str) -> List[TestCase]:
        """按 Sheet 获取用例

        Args:
            sheet_name: Sheet 名称

        Returns:
            List[TestCase]: 匹配的用例列表
        """
        return [c for c in self._cases if c.sheet == sheet_name]

    def get_cases_by_name(self, name_pattern: str) -> List[TestCase]:
        """按名称模式获取用例

        Args:
            name_pattern: 名称模式（支持通配符 *）

        Returns:
            List[TestCase]: 匹配的用例列表
        """
        import fnmatch
        return [c for c in self._cases if fnmatch.fnmatch(c.name, name_pattern)]

    def get_cases_by_id(self, case_ids: List[str]) -> List[TestCase]:
        """按 ID 获取用例

        Args:
            case_ids: 用例 ID 列表

        Returns:
            List[TestCase]: 匹配的用例列表
        """
        return [c for c in self._cases if c.id in case_ids]

    def filter_cases(
        self,
        include_sheets: List[str] = None,
        exclude_sheets: List[str] = None,
        include_ids: List[str] = None,
        exclude_ids: List[str] = None,
        name_pattern: str = None
    ) -> List[TestCase]:
        """过滤用例

        Args:
            include_sheets: 包含的 Sheet
            exclude_sheets: 排除的 Sheet
            include_ids: 包含的 ID
            exclude_ids: 排除的 ID
            name_pattern: 名称模式

        Returns:
            List[TestCase]: 过滤后的用例列表
        """
        result = self._cases.copy()

        if include_sheets:
            result = [c for c in result if c.sheet in include_sheets]

        if exclude_sheets:
            result = [c for c in result if c.sheet not in exclude_sheets]

        if include_ids:
            result = [c for c in result if c.id in include_ids]

        if exclude_ids:
            result = [c for c in result if c.id not in exclude_ids]

        if name_pattern:
            import fnmatch
            result = [c for c in result if fnmatch.fnmatch(c.name, name_pattern)]

        return result
