from typing import Any, Dict
import os
import yaml


def _env_substitute(value: Any) -> Any:
    if isinstance(value, str) and value.startswith("${ENV:") and value.endswith("}"):
        key = value[6:-1]
        return os.getenv(key, "")
    return value


def _walk_env(obj: Any) -> Any:
    if isinstance(obj, dict):
        return {k: _walk_env(v) for k, v in obj.items()}
    if isinstance(obj, list):
        return [_walk_env(v) for v in obj]
    return _env_substitute(obj)


def load_config(path: str) -> Dict[str, Any]:
    with open(path, "r", encoding="utf-8") as f:
        data = yaml.safe_load(f) or {}
    if "source" not in data or "sink" not in data:
        raise ValueError("config must include source and sink")
    if "type" not in data["source"] or "type" not in data["sink"]:
        raise ValueError("source/sink must include type")
    data = _walk_env(data)
    return data
