#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
模块名称：data_extractor.py
模块描述：功能测试报告 - 信息提取模块，从测试数据和BUG中提取关键信息

移植自独立工具 FunctionalTestReportGeneration/src/data_extractor.py，
import 改为相对导入。

作者：czj
创建日期：2026-08-12
最后修改：2026-08-12
"""

import re
from typing import Dict, List, Set, Optional

from .config import (
    KEYWORD_SERVER_INFO,
    KEYWORD_DEPLOYMENT_ENV,
    KEYWORD_VERSION_INFO,
    VERSION_STOP_MARKERS,
    DEFAULT_TEST_LEAD,
    DEFAULT_TESTER,
    DEFAULT_TEST_ENV,
    DEFAULT_SYSTEM_VERSION,
    DEFAULT_SERVER_ADDRESS,
    DEFAULT_DEPLOYMENT_ENV,
)
from .excel_reader import TestCase, Bug

# IP地址正则
IP_ADDRESS_PATTERN = r'\b(?:\d{1,3}\.){3}\d{1,3}\b'


def extract_ip_address(text: str) -> str:
    """
    从文本中提取IP地址

    Args:
        text: 文本内容

    Returns:
        IP地址字符串，未找到返回空字符串
    """
    if not text:
        return ""
    ips = re.findall(IP_ADDRESS_PATTERN, text)
    return ips[0] if ips else ""


def extract_keyword_value(text: str, keyword: str) -> str:
    """
    从文本中提取关键字后面的值

    Args:
        text: 文本内容
        keyword: 关键字

    Returns:
        关键字后面的值
    """
    if not text or not keyword:
        return ""

    # 尝试匹配 【关键字】值 或 关键字：值
    patterns = [
        rf'{re.escape(keyword)}\s*[：:]\s*([^\n]+)',  # 【关键字】: 值
        rf'{re.escape(keyword)}\s*([^\n]+)',  # 【关键字】 值
    ]

    for pattern in patterns:
        match = re.search(pattern, text)
        if match:
            return match.group(1).strip()

    return ""


def extract_version_info(text: str) -> str:
    """
    从文本中提取版本信息

    Args:
        text: 文本内容

    Returns:
        版本信息字符串
    """
    if not text:
        return ""

    # 查找版本信息开始位置
    version_start = text.find(KEYWORD_VERSION_INFO)
    if version_start == -1:
        return ""

    # 从版本信息标签后开始提取
    start_pos = version_start + len(KEYWORD_VERSION_INFO)
    remaining = text[start_pos:].strip()

    lines = []
    for line in remaining.split('\n'):
        line = line.strip()
        if not line:
            continue

        # 检查是否遇到结束标记
        should_stop = False
        for marker in VERSION_STOP_MARKERS:
            if line.startswith(marker):
                should_stop = True
                break
        if should_stop:
            break

        # 处理行特征：包含 ":" 或特定开头
        if ":" in line or line.startswith(("对内服务", "对外服务", "MQTT", "Web", "数据")):
            lines.append(line)

    return "\n".join(lines) if lines else ""


def extract_testers(bugs: List[Bug]) -> str:
    """
    提取测试人员名单（从BUG提单人员中去重）

    Args:
        bugs: BUG列表

    Returns:
        测试人员名单，用"、"连接
    """
    reporters: Set[str] = set()
    for bug in bugs:
        if bug.reporter and bug.reporter.strip():
            reporters.add(bug.reporter.strip())
    return "、".join(sorted(reporters)) if reporters else DEFAULT_TESTER


def extract_info_from_cases(cases: List[TestCase], keyword: str) -> str:
    """
    从测试用例中提取指定关键字的信息

    Args:
        cases: 测试用例列表
        keyword: 关键字

    Returns:
        提取到的信息
    """
    for case in cases:
        if case.pre_condition and keyword in case.pre_condition:
            value = extract_keyword_value(case.pre_condition, keyword)
            if value:
                return value
    return ""


def extract_server_info(cases: List[TestCase]) -> str:
    """
    从测试用例中提取服务器信息

    Args:
        cases: 测试用例列表

    Returns:
        服务器信息
    """
    info = extract_info_from_cases(cases, KEYWORD_SERVER_INFO)
    if info:
        return info

    # 如果没有找到关键字，尝试从预置条件中提取IP地址
    for case in cases:
        if case.pre_condition:
            ip = extract_ip_address(case.pre_condition)
            if ip:
                return ip

    return DEFAULT_SERVER_ADDRESS


def extract_deployment_env(cases: List[TestCase]) -> str:
    """
    从测试用例中提取部署环境信息

    Args:
        cases: 测试用例列表

    Returns:
        部署环境信息
    """
    info = extract_info_from_cases(cases, KEYWORD_DEPLOYMENT_ENV)
    return info if info else DEFAULT_DEPLOYMENT_ENV


def extract_version_info_from_bug_list(bugs: List[Bug]) -> str:
    """
    从BUG列表中提取版本信息

    Args:
        bugs: BUG列表

    Returns:
        版本信息
    """
    versions = []
    for bug in bugs:
        if bug.reproduction_steps:
            version = extract_version_info(bug.reproduction_steps)
            if version:
                versions.append(version)

    if versions:
        return "\n---\n".join(list(set(versions)))

    return DEFAULT_SYSTEM_VERSION


def extract_test_lead(bugs: List[Bug]) -> str:
    """
    提取测试负责人（使用第一个BUG的提单人员）

    Args:
        bugs: BUG列表

    Returns:
        测试负责人姓名
    """
    if bugs and bugs[0].reporter:
        return bugs[0].reporter.strip()
    return DEFAULT_TEST_LEAD