# -*- coding: utf-8 -*-
"""
PB 组装器：根据顺序清单和分组 YAML，按 vehicle_config.proto 填充 Message 后序列化为 .pb.txt。
"""

import yaml
from pathlib import Path
from typing import Dict, List, Any, Optional

from ._proto_io import dict_to_message, message_to_pb_text


def _default_proto_templates_dir() -> Path:
    return Path(__file__).resolve().parent / "proto_templates"


class PBBuilder:
    """从 order_manifest + YAML 目录组装为 .pb.txt 文件。"""

    def __init__(self, proto_templates_dir: Optional[str] = None):
        self.proto_templates_dir = Path(proto_templates_dir or _default_proto_templates_dir())

    def load_from_yaml_dir(self, input_dir: str) -> Dict[str, Any]:
        """从目录加载 order_manifest.yaml 及所有引用 YAML，按顺序组装。"""
        inp = Path(input_dir)
        with open(inp / "order_manifest.yaml", "r", encoding="utf-8") as f:
            manifest = yaml.safe_load(f)

        data = {
            "vehicle_info": {},
            "vehicle_param": {},
            "extrinsics": [],
            "intrinsics": [],
        }
        vi_file = manifest.get("vehicle_info_file", "vehicle_info.yaml")
        vp_file = manifest.get("vehicle_param_file", "vehicle_param.yaml")
        if (inp / vi_file).exists():
            with open(inp / vi_file, "r", encoding="utf-8") as f:
                data["vehicle_info"] = yaml.safe_load(f) or {}
        if (inp / vp_file).exists():
            with open(inp / vp_file, "r", encoding="utf-8") as f:
                data["vehicle_param"] = yaml.safe_load(f) or {}

        for ext_item in manifest.get("extrinsics", []):
            path = inp / ext_item["file"]
            if path.exists():
                with open(path, "r", encoding="utf-8") as f:
                    data["extrinsics"].append(yaml.safe_load(f) or {})

        for int_item in manifest.get("intrinsics", []):
            path = inp / int_item["file"]
            if path.exists():
                with open(path, "r", encoding="utf-8") as f:
                    data["intrinsics"].append(yaml.safe_load(f) or {})

        return data

    def build_pb_text(self, data: Dict[str, Any]) -> str:
        """将组装后的数据按 vehicle_config.proto 填充 Message 并序列化为 PB 文本。"""
        msg = dict_to_message(data)
        return message_to_pb_text(msg)

    def build_file(self, input_dir: str, output_pb_path: str) -> None:
        """从 input_dir 读取 order_manifest 与所有 YAML，组装并写入 output_pb_path（.pb.txt）。"""
        data = self.load_from_yaml_dir(input_dir)
        content = self.build_pb_text(data)
        Path(output_pb_path).parent.mkdir(parents=True, exist_ok=True)
        with open(output_pb_path, "w", encoding="utf-8") as f:
            f.write(content)
