"""抓取配置加载器。

从 YAML 文件读取 sources.yaml,并校验为 CrawlerConfig。
"""

from __future__ import annotations

from pathlib import Path
from typing import Any

import yaml
from loguru import logger

from .models import CrawlerConfig

DEFAULT_CONFIG_PATH = Path("configs/sources.yaml")


def load_crawler_config(path: str | Path | None = None) -> CrawlerConfig:
    """加载并校验抓取配置。

    参数:
        path: YAML 配置路径,默认 configs/sources.yaml。

    返回:
        CrawlerConfig 实例。

    异常:
        FileNotFoundError: 配置文件不存在。
        ValueError: YAML 顶层不是 mapping 或 sources 缺失。
        pydantic.ValidationError: schema 校验失败。
    """
    config_path = Path(path) if path else DEFAULT_CONFIG_PATH
    if not config_path.is_file():
        raise FileNotFoundError(f"抓取配置文件不存在: {config_path}")

    with config_path.open("r", encoding="utf-8") as f:
        raw: Any = yaml.safe_load(f)

    if not isinstance(raw, dict):
        raise ValueError(f"配置文件顶层必须是 mapping,实际类型: {type(raw).__name__}")
    if "sources" not in raw:
        raise ValueError("配置文件缺少 sources 字段")

    config = CrawlerConfig.model_validate(raw)
    logger.info(
        "已加载抓取配置: 总 {} 个源, 启用 {} 个, 并发上限 {}",
        len(config.sources),
        len(config.enabled_sources()),
        config.settings.concurrency,
    )
    return config
