# circular_import_checker_subprocess.py
import os
import sys
import argparse
import subprocess
from typing import List

def find_python_modules(package_path: str) -> List[str]:
    """
    (此函数与上一版本完全相同)
    扫描指定包路径，将其下所有 .py 文件转换为模块导入字符串。
    """
    package_path = os.path.abspath(package_path)
    if not os.path.isdir(package_path):
        print(f"错误: 路径 '{package_path}' 不是一个有效的目录。")
        return []

    parent_dir = os.path.dirname(package_path)
    
    modules = []
    for root, _, files in os.walk(package_path):
        for file in files:
            if file.endswith(".py") and not file.startswith("__"):
                full_path = os.path.join(root, file)
                relative_path_from_parent = os.path.relpath(full_path, parent_dir)
                module_name = relative_path_from_parent.replace(os.sep, '.')[:-3]
                modules.append(module_name)
                
    return modules

def check_for_circular_imports_subprocess(package_path: str):
    """
    使用独立的子进程来检测指定包内的循环导入问题。
    """
    package_path = os.path.abspath(package_path)
    parent_dir = os.path.dirname(package_path)
    
    # 确保我们使用与当前脚本相同的 Python 解释器
    python_executable = sys.executable

    modules_to_check = find_python_modules(package_path)
    if not modules_to_check:
        print("在指定路径下没有找到可供检查的 Python 模块。")
        return

    print(f"--- 开始独立进程检测: {os.path.basename(package_path)} ---")
    print(f"--- 共找到 {len(modules_to_check)} 个模块待检测 (此过程可能较慢) ---\n")

    found_issues = False
    
    for module in sorted(modules_to_check):
        print(f"[*] 正在通过子进程独立检测: {module}")

        # 1. 构建要在子进程中执行的 Python 命令字符串
        # 使用 r'' 来安全地处理 Windows 路径中的反斜杠
        command_code = f"import {module}"
        
        # 2. 执行命令
        # subprocess.run 会等待命令执行完成
        result = subprocess.run(
            [python_executable, "-c", command_code],
            capture_output=True,  # 捕获 stdout 和 stderr
            text=True,            # 以文本模式处理输出
            encoding='utf-8'      # 指定编码
        )

        # 3. 分析结果
        # 如果 returncode 不为 0，说明子进程执行出错
        if result.returncode == 0:
            print(f"  [+] 成功: {module} 导入正常。")
        else:
            # 获取标准错误输出，并转为小写以便搜索
            stderr_output = result.stderr.lower()
            if "circular import" in stderr_output:
                print(f"  [!] 严重: 检测到循环导入！")
                # 打印原始的、未经修改的错误信息，以保留细节
                print(f"      错误详情:\n{result.stderr.strip()}")
                found_issues = True
            else:
                # 可能是其他导入错误，如 SyntaxError, ModuleNotFoundError 等
                print(f"  [?] 警告: 发生未知导入错误。")
                print(f"      错误详情:\n{result.stderr.strip()}")
                found_issues = True

    print("\n--- 检测完成 ---")
    if found_issues:
        print("检测到循环导入或其他导入问题。请检查上面的日志。")
    else:
        print("恭喜！在独立进程检测中未发现导入问题。")


if __name__ == "__main__":
    parser = argparse.ArgumentParser(
        description="一个使用独立子进程来检测 Python 包中循环导入问题的工具 (更精确，但更慢)。",
        formatter_class=argparse.RawTextHelpFormatter
    )
    parser.add_argument(
        "package_path",
        type=str,
        help="要检查的 Python 包的根目录路径。\n例如: ./my_project/my_package"
    )
    args = parser.parse_args()
    check_for_circular_imports_subprocess(args.package_path)
