"""配置加载、验证、保存。"""

from __future__ import annotations

from pathlib import Path

import yaml


class PromptGradConfig:
    """解析后的 PromptGrad 配置。"""

    def __init__(self, raw: dict, config_path: str):
        self.raw = raw
        self.config_path = config_path

    @property
    def project_name(self) -> str:
        return self.raw["project"]["name"]

    @property
    def prompt_config(self) -> dict:
        return self.raw["prompt"]

    @property
    def prompt_version(self) -> int:
        return self.raw["prompt"]["version"]

    @property
    def model_name(self) -> str:
        return self.raw["model"]["name"]

    @property
    def model_config(self) -> dict:
        return self.raw["model"]

    @property
    def dimensions(self) -> list[dict]:
        return self.raw["eval_rubric"]["dimensions"]

    @property
    def pass_threshold(self) -> float:
        return self.raw["eval_rubric"]["pass_threshold"]

    @property
    def max_iterations(self) -> int:
        return self.raw["optimization"]["max_iterations"]

    @property
    def target_score(self) -> float:
        return self.raw["optimization"]["target_score"]

    @property
    def patience(self) -> int:
        return self.raw["optimization"]["patience"]

    @property
    def strategy(self) -> str:
        return self.raw["optimization"]["strategy"]

    @property
    def concurrency(self) -> int:
        return self.raw["optimization"]["concurrency"]

    @property
    def enable_regression_check(self) -> bool:
        return self.raw["optimization"]["enable_regression_check"]

    @property
    def base_dir(self) -> str:
        """config.yaml 所在的 .promptgrad 目录。"""
        return str(Path(self.config_path).parent)

    @property
    def test_cases_dir(self) -> str:
        """测试用例目录的绝对路径。"""
        rel = self.raw["test_suite"]["path"]
        return str(Path(self.base_dir) / rel)

    @property
    def prompts_dir(self) -> str:
        """prompt 快照目录。"""
        return str(Path(self.base_dir) / "prompts")

    @property
    def tmp_dir(self) -> str:
        """临时数据交换目录。"""
        return str(Path(self.base_dir) / "tmp")


def load_config(config_path: str) -> PromptGradConfig:
    """从 YAML 文件加载配置。"""
    path = Path(config_path)
    if not path.exists():
        raise FileNotFoundError(f"配置文件不存在: {config_path}")
    with open(path, "r", encoding="utf-8") as f:
        raw = yaml.safe_load(f)
    return PromptGradConfig(raw=raw, config_path=str(path.resolve()))


def save_config(config_dict: dict, config_path: str) -> None:
    """将配置字典写入 YAML 文件。"""
    path = Path(config_path)
    path.parent.mkdir(parents=True, exist_ok=True)
    with open(path, "w", encoding="utf-8") as f:
        yaml.dump(config_dict, f, default_flow_style=False, allow_unicode=True, sort_keys=False)
