from dataclasses import dataclass, field
from pathlib import Path

import yaml


@dataclass(slots=True)
class OverlayRef:
    path: str
    alias: str | None = None


@dataclass(slots=True)
class InstanceSpec:
    port: int
    overlays: list[OverlayRef] = field(default_factory=list)
    arguments: list[str] = field(default_factory=list)
    config: list[str] = field(default_factory=list)


def _parse_overlay(item) -> OverlayRef:
    if isinstance(item, str):
        return OverlayRef(path=item)
    if isinstance(item, dict):
        path = item.get("path")
        if not isinstance(path, str) or not path:
            raise ValueError(f"overlay entry missing 'path': {item!r}")
        raw_alias = item.get("alias")
        alias = str(raw_alias) if raw_alias not in (None, "") else None
        return OverlayRef(path=path, alias=alias)
    raise ValueError(f"unsupported overlay entry type: {type(item).__name__}")


def load_spec(path: Path) -> InstanceSpec:
    raw = yaml.safe_load(path.read_text()) or {}
    return InstanceSpec(
        port=int(raw["port"]),
        overlays=[_parse_overlay(item) for item in raw.get("overlays", [])],
        arguments=[str(item) for item in raw.get("arguments", [])],
        config=[str(item) for item in raw.get("config", [])],
    )
