"""本地问题加载器

从本地 problems/ 目录加载问题配置，无需云端注册。
"""

from __future__ import annotations

import importlib.util
import sys
from pathlib import Path
from typing import Any

from ..models import PhaseConfig


class LocalProblemLoader:
    """本地问题加载器

    从本地 problems/<problem_name>/ 目录加载：
    1. config.py - PhaseConfig 子类定义
    2. sandbox/ - 评测代码（judge runtime）
    """

    def load(self, problem_path: str | Path) -> PhaseConfig:
        """加载问题配置

        Args:
            problem_path: 问题目录路径，如 "problems/interrupt_judge"

        Returns:
            PhaseConfig 实例

        Raises:
            FileNotFoundError: 如果找不到 config.py
            ValueError: 如果 config.py 中没有有效的 PhaseConfig 子类
        """
        problem_path = Path(problem_path).resolve()

        if not problem_path.exists():
            raise FileNotFoundError(f"Problem path not found: {problem_path}")

        config_path = problem_path / "config.py"
        if not config_path.exists():
            raise FileNotFoundError(f"config.py not found in {problem_path}")

        # 动态导入 config.py
        config_module = self._load_module_from_path("problem_config", config_path)

        # 查找 PhaseConfig 子类
        phase_config = self._find_phase_config(config_module)

        if phase_config is None:
            raise ValueError(
                f"No PhaseConfig subclass found in {config_path}. "
                "Please define a class that inherits from PhaseConfig."
            )

        return phase_config

    def _load_module_from_path(self, module_name: str, path: Path) -> Any:
        """从文件路径加载 Python 模块"""
        spec = importlib.util.spec_from_file_location(module_name, path)
        if spec is None or spec.loader is None:
            raise ImportError(f"Cannot load module from {path}")

        module = importlib.util.module_from_spec(spec)
        sys.modules[module_name] = module
        spec.loader.exec_module(module)
        return module

    def _find_phase_config(self, module: Any) -> PhaseConfig | None:
        """在模块中查找 PhaseConfig 子类

        查找顺序：
        1. 名为 *Config 的类（如 InterruptJudgeConfig）
        2. 任何继承自 PhaseConfig 的类
        """
        from ..models import PhaseConfig

        candidates = []

        for attr_name in dir(module):
            attr = getattr(module, attr_name)
            if (
                isinstance(attr, type)
                and issubclass(attr, PhaseConfig)
                and attr is not PhaseConfig
            ):
                candidates.append(attr)

        if not candidates:
            return None

        # 优先选择以 Config 结尾的类名
        for candidate in candidates:
            if candidate.__name__.endswith("Config"):
                return candidate()

        # 否则返回第一个找到的
        return candidates[0]()
